「complex_value two-pass capture-clobbering」バグ(regex map + regex capture → ヒープオーバーフロー / 情報漏洩)に対して脆弱な nginx 設定を検出する静的設定スキャナ。
complex_value の2パスキャプチャクラバリングバグクラス(F5/nginx SIRT アドバイザリ、2026年7月)に対して脆弱な nginx 設定を検出する読み取り専用の静的スキャナーです。設定を解析し、脆弱なパターンをその理由と場所とともに報告します。エクスプロイトは行わず、稼働中のサーバーにも触れません。
単一ファイル、標準ライブラリのみ、Python 3.6+。
脆弱性の詳細な解説: https://cyberstan.co.uk/nginx-rce/
nginx は多くのディレクティブ値を2パスで構築します。LEN パスが長さを測定してバッファを確保し、その後 VALUE パスがそこへ書き込みます。正規表現キャプチャ($1 から $9、または名前付き (?P<name>...))はリクエストごとの共有状態から読み取られます。マッチキーが正規表現である map は、その変数が評価された瞬間に新たな PCRE マッチを実行し、そのマッチが共有キャプチャ状態を上書きします。キャプチャが LEN パスで測定され、その後 VALUE パスがそのキャプチャを書き換える前に正規表現 map が実行されると、2つのパスが食い違います:
map の入力が攻撃者の影響を受ける場合($request_body、$http_*、$arg_*、$uri、$ssl_preread_server_name など)、どちらの方向もリモートからトリガー可能です。
スキャナーは、以下すべてが1つの2パスバッファ内に、悪用可能な順序で揃った場合に、その location または server を検出します:
location ~、server_name ~、rewrite、if (... ~ ...)、または正規表現 map。~ または ~* の正規表現マッチキーを持つ map(http または stream)で、その出力変数によって参照されているもの。return、set、add_header、proxy_method、proxy_pass、rewrite、index など): 両方の参照が同じ値内にある。proxy_set_header、proxy_set_body、fastcgi_param、scgi_param、uwsgi_param、grpc_set_header): これらはファミリー全体でリクエストごとに1つのバッファを構築するため、2つの参照が同じ location 内の別々のディレクティブにあってもよい。# scan a single config (follows include directives by default)
python3 nginx_capture_clobber_scan.py /etc/nginx/nginx.conf
# scan a directory (uses nginx.conf if present, else all *.conf)
python3 nginx_capture_clobber_scan.py /etc/nginx/
# scan several roots
python3 nginx_capture_clobber_scan.py site-a.conf site-b.conf
# machine-readable output
python3 nginx_capture_clobber_scan.py /etc/nginx/nginx.conf --json
# do not expand include directives
python3 nginx_capture_clobber_scan.py /etc/nginx/nginx.conf --no-includes
| オプション | 効果 |
|---|---|
--json | テキストの代わりに JSON レポートを出力します。 |
--no-includes | include ディレクティブを追跡しません。 |
| コード | 意味 |
|---|---|
0 | 脆弱な設定は見つかりませんでした。 |
1 | 少なくとも 1 つの脆弱な設定が見つかりました。 |
2 | 使用エラー (パスが指定されていない、または見つからない)。 |
脆弱な設定では非ゼロで終了するため、CI で使用できます:
python3 nginx_capture_clobber_scan.py /etc/nginx/nginx.conf || echo "review needed"
テキストモードでは、各検出結果について、ファイルと行、それを囲むスコープ、シンクディレクティブ、関与するキャプチャ変数とマップ変数、トリガーとなったマップ、および1行の理由を出力します。クリアされたセクションには、安全な順序で共存するケースが一覧表示されます。--json は次を生成します:
{
"vulnerable": true,
"findings": [
{
"file": "/etc/nginx/conf.d/api.conf",
"line": 12,
"scope": "location ~ ^/api/(.+)$",
"directive": "proxy (family buffer)",
"captures": ["$1"],
"map_vars": ["$is_bot"],
"triggers": ["$is_bot <- regex-map on $http_user_agent [nginx.conf:30]"],
"reason": "..."
}
],
"cleared_safe_order": [],
"regex_maps": [],
"missing_includes": []
}
map変数を$1から$9または名前付きキャプチャ参照と一緒に参照しないでください。(?P<name>...)グループを複数の正規表現mapで再利用しないでください。proxy_set_headerまたはfastcgi_paramファミリーに混在させないでください。setされた変数によって生成される値は解決できません。includeターゲット(例えば、ローカルに存在しない絶対パス)は、黙ってスキップされるのではなくmissing_includesの下に報告されます。完全なカバレッジを得るには、設定が解決されるホスト上で実行してください。脆弱性の解説とエクスプロイトチェーン: https://cyberstan.co.uk/nginx-rce/