生涯未熟

生涯未熟

プログラミングをちょこちょこと。

Cloud ArmorのOWASPルールセットによるGraphQLリクエストでの誤検出

たまたま遭遇したけど誤検出のあるあるっぽいなと思ったので調べてメモしとく。

前提としてCloud Armorの事前構成 WAF ルールであるOWASP TOP 10のルールを有効化して運用しておりました。

cloud.google.com

運用自体は特に問題なかったのですが、ある日GraphQLの機能実装をしていたメンバーから特定のリクエストが403で弾かれますと報告を受け調べることに。

Cloud Armorのログを確認する

Cloud Loggingで jsonPayload.enforcedSecurityPolicy.outcome="DENY" なログを調べたところ、特定のルールが原因で弾かれていました。

それが、 lfi-v33-stableowasp-crs-v030301-id930120-lfi で弾かれていて、どうやら .profile がヒットしている様子。
たしかに、特定のリクエストにはfragmentとして profile といった文字列を含んでいて、それがルールに抵触して弾かれているようなのですが正直何で?といったお気持ちになったので少し調べてみることに。

ルールを確認してみよう

Cloud ArmorのOWASP TOP 10のルールはこのリポジトリで管理されているコアルールセットを元に構成されています。

github.com

で、今回引っかかっていたのはこの OS File Access に関するルールでした。

github.com

#
# -=[ OS File Access ]=-
#
# Ref: https://github.com/lightos/Panoptic/blob/master/cases.xml
#
SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@pmFromFile lfi-os-files.data" \
    "id:930120,\
    phase:2,\
    block,\
    capture,\
    t:none,t:utf8toUnicode,t:urlDecodeUni,t:normalizePathWin,t:lowercase,\
    msg:'OS File Access Attempt',\
    logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
    tag:'application-multi',\
    tag:'language-multi',\
    tag:'platform-multi',\
    tag:'attack-lfi',\
    tag:'paranoia-level/1',\
    tag:'OWASP_CRS',\
    tag:'capec/1000/255/153/126',\
    tag:'PCI/6.5.4',\
    ver:'OWASP_CRS/3.3.1',\
    severity:'CRITICAL',\
    setvar:'tx.lfi_score=+%{tx.critical_anomaly_score}',\
    setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'"

たしかに、 owasp-crs-v030301-id930120-lfi で検索をかけるとOSファイルアクセス試行とあったので間違ってなさそうですね。
ここで参照している lfi-os-files.data を見てみると・・・ .profile がありました!間違いなくここですね。

github.com

こりゃめちゃくちゃ引っ掛かりそうだなーと思いながら調べていると、別のリポジトリでこの .profile を含めていることに憤っている方もいました。

github.com

対応として合致パターンを ^.profile とかにすればいいと思うとのこと。しかし、Cloud Armorで用意されているルールに手を加えることも出来んし困るなー・・・

困ってる人多そうとか思ったが、調べた限りあまりいなかったのでモヤモヤしつつも OS File Access のルールをオプトアウトルールにする対応を取りましたというお話でした。