Upgrade to Pro — share decks privately, control downloads, hide ads and more …

同じWAFが、攻撃の“形”は弾く── 正当な“形”の不正は通す

Avatar for kuroneko kuroneko
August 13, 2026

同じWAFが、攻撃の“形”は弾く── 正当な“形”の不正は通す

同じ WAF に、同じ宛先へ、同じログイン済みセッションで、2つのリクエストを投げます。SQLインジェクションのペイロードは 403 Forbidden で弾かれ、GET /api/v1/cust/124 は 200 OK で他人の氏名とメールアドレスを返します。違うのはリクエストの「形」だけ。境界は攻撃の形は知っていても、「誰が見ていいか」は知りません。

社内エンジニア向けセキュリティ勉強会(全6回)の第5回です。AWS WAF・セキュリティグループ・ネットワークACL という境界防御を「通信の形を判断する道具」として位置づけ直し、境界で受けられる脅威と、アプリの認可でしか塞げない脅威の線引きに落とします。Laravel 13.x(新規)と FuelPHP 1.x(レガシー)が混在する現場を前提に、どの脅威をどの層で受けるかを設計として示します。

疑似デモは2つ。中身だけを変えて同じ経路に投げます。(A) SQLi ペイロードはマネージドルールのパターンに一致して 403 で止まる。(B) /api/v1/cust/124 は攻撃パターンに一致しないので 200 OK、他人のデータがそのまま返る。片方が止まって片方が通る理由を、WAF は「既知のパターン」を見ていて、SG は「ポート」しか見ていない、という構造まで分解します。

扱うトピック
- 境界の正体:セキュリティグループ=L3/L4 のパケットフィルタ(ENI 単位・ステートフル・許可ルールのみ)、WAF=L7 のアプリケーションレベルゲートウェイ(Web ACL・マネージドルール・Allow / Block(403) / Count)
- なぜ素通しするのか:攻撃パターンに一致しなければ許可されてアプリへ渡る。443 が開いていれば文法的に正当な GET は SG の対象外。加えてマネージドルールにも検査上限がある(ALB・AppSync は 8KB 固定、CloudFront 等は既定 16KB・最大 64KB、ヘッダ/クッキーは 8KB)── Allow ならリクエストは丸ごと転送される
- 脅威×層のマトリクス:SQLi・XSS は WAF で緩和(仮想パッチ=時間稼ぎ)+コードで根治、SSRF は egress 制限+URL 検証+IMDSv2、IDOR/BOLA は境界では止まらずアプリのオブジェクト単位の認可が唯一の砦
- SG と NACL の使い分けと限界:ステートフル/ステートレス、ENI/サブネット。そして AWS が明記するとおり SG も NACL も IMDS(169.254.169.254)宛の通信はフィルタできない ── だから第一の防御は IMDSv2 とホップ制限

持ち帰る3つの結論
1. 境界(WAF/SG)は通信の形=IP・ポート・既知パターンを判断する
2. 中身の正当性(認可)は境界では判断できず、アプリでしか塞げない
3. 脅威ごとに受ける層を決め、多層で守る

レガシー保守(FuelPHP 1.x)でも「明日からできる」棚卸しまで示します(Web ACL とルール・開放ポートの棚卸し、WAF 任せにしている画面/API にアプリ側の認可があるかの確認、WAF ログと VPC フローログの出力を有効化)。Appendix には AWS WAF の構成と検査上限、SG と NACL の詳細比較、ファイアウォールの分類と限界、DMZ・セグメンテーション・IDS/IPS、出典リンク集を付けています。

想定読者:「WAF と SG を入れたから安全」と思い、アプリ側の認可を後回しにしていた"ちょっと前の自分"。
分類:IDOR/BOLA・認可不備 = OWASP A01:2021 Broken Access Control(CWE-639 / CWE-862 / CWE-200)、SQLi・XSS = A03:2021 Injection、SSRF = A10:2021 Server-Side Request Forgery

Avatar for kuroneko

kuroneko

August 13, 2026

More Decks by kuroneko

Other Decks in Technology

Transcript

  1. 今日のゴール: 境界とアプリの“線引き”を持ち帰る 境界(WAF/SG)は通信の形を守るが、認可(中身の正当性)はアプリでしか塞げない 第1回 認証・認可 第2回 第3回 インジェクション /SSRF XSS/CSRF

    /セッション 第4回 暗号/シークレット 想定読者は「ちょっと前の自分」。TLS/HTTPS 前提は当然として深掘りしません。 話者: kuroneko 第5回 ネットワーク /WAF 第6回 ログ/追跡
  2. 今日の道順と、持ち帰る結論3つ 道順: S1境界の役割 → S2デモ → S3なぜ素通し → S4線引き 結論①

    結論② 結論③ 境界(WAF/SG)は通信の形=IP ・ポート・既知パターンを判 断する 中身の正当性(認可)は境界で は判断できず、アプリでしか 塞げない 脅威ごとに受ける層を決め、 多層で守る
  3. 多層防御の最前線が“境界” ── 入口で通信を絞り込む 境界 → ネットワーク分離 → アプリ(認可) → データ

    ── 層で守る 第1層 第2層 第3層 第4層 境界 (WAF/SG) ネットワーク 分離 アプリ (認可) データ 誰が何を見てよいか 暗号で保護 通信の形・既知パター ン =最前線 セグメント/NACL 境界は“最初の関門”であって、唯一の関門ではない
  4. セキュリティグループ = L3/L4 のパケットフィルタ IP・ポート・プロトコルで通す/止める ── 中身は見ない CCT: パケットフィルタ AWS:

    Security Group IP層/TP層で機能 IP・ポート・プロトコルで許可/ドロップ リソース(EC2/ENI)に付く仮想FW ステートフル・許可ルールのみ どちらも見るのは IP・ポート・プロトコル(L3/4)の“形”だけ ── 中身は見ない
  5. WAF = L7 の門番 ── HTTP の“中身のパターン”を見て弾く 既知の攻撃パターンを検知・ブロック ── 見るのは“パターン”

    CCT: アプリレベルGW AWS WAF OSI アプリ層で機能 http post/get を検査 Web ACL を各種リソースに関連付け 一致で Allow/Block(403)/Count 既知の攻撃をマネージドルールで検知・ブロック ── ただし見るのは“パターン”
  6. 境界は“通信の形”を見る ── まだ“中身の正当性”は見ていない SG=形(L3/4)・WAF=パターン(L7) ── どちらも“誰が見てよいか”は未判断 境界 = 形とパターン 認可

    = ? SG=IP・ポート(L3/4) WAF=既知パターン(L7) この人がこのデータを 見てよいか?は未判断 境界=形とパターン / 認可=?
  7. デモで見るもの: 同じ1台のWAFに、2種類のリクエストを投げる 宛先も認証済みセッションも同じ ── 変えるのは“中身”だけ STEP 1 STEP 2 STEP

    3 同じWAF・同じ認証 (A) SQLi を送る (B) IDOR を送る 宛先もセッションも固定 ' or '1'='1 /api/v1/cust/124 注目 ── (A)は止まり、(B)は通るか?
  8. 反例: ' or '1'='1' を送ると、WAFが 403 でブロックした SQLi ペイロードを WAF

    が“攻撃の形”と認識(値は説明用フィクスチャ) ❖ SQLi ペイロードを URL/ボディに混ぜて送信 ❖ WAF のマネージドルール(SQLi 検知)が“攻撃の形 ”を認識 ❖ 応答は 403 Forbidden(WAF がブロック) # 認証済みセッションで SQLi ペイロードを送る $ curl -i "https://app.example.com/api/v1/ cust/%27%20or%20%271%27%3D%271" HTTP/1.1 403 Forbidden ← WAF(SQLi検知)がブロック Server: awselb/2.0 # → 境界(WAF)は「攻撃の"形"」を認識して止めた
  9. ★ GET /api/v1/cust/124 は、WAFもSGも素通しで 200 認証済みのまま ID だけ 124 に

    ── 他人のデータが返る(値は説明用フィクスチャ) ❖ 第1回の IDOR を、認証済みのまま ID だけ 124 に 書き換え ❖ WAF に一致する攻撃パターンなし・SG は 443 を許可済み ❖ 200 OK で他人のデータが返る # 同じWAF・同じ認証で、ID を 124 に書き換えた GET $ curl -i "https://app.example.com/api/v1/cust/124" HTTP/1.1 200 OK ← 攻撃パターン無し・SG は 443 許可済み Content-Type: application/json {"id":124,"name":"佐藤花子", "email":"[email protected]"} ← 他人のデータ # → 正当な HTTP GET を止める理由が境界には無い
  10. 今起きたこと: 境界は“攻撃の形”は弾くが、“認可”は判断していない (A)既知の攻撃パターン=弾く / (B)文法的に正当な GET=通す (A) SQLi → 403

    (B) IDOR → 200 既知の攻撃パターンに一致 =弾いた 文法的に正当な HTTP GET =通した 境界は“形”で判断 ── 中身が“誰のものか”は見ていない
  11. WAFは“攻撃パターン”を探す ── /cust/124 に一致するパターンが無い 文法的に正当な HTTP リクエスト=止める理由が WAF に無い STEP

    1 STEP 2 STEP 3 リクエスト /cust/124 WAFルール照合 不一致 → 許可 文法的に正当な GET 既知の攻撃パターンと照合 どのパターンにも一致せず アプリへ素通り SQLi は一致して 403 / IDOR は不一致で素通り ── “正しく見える通信”は止められない
  12. SGは“通信の形”しか見ない ── 443を許可したら 443上のGETは通る L3/4=IP・ポート・プロトコルだけ ── 中身は関知外 ❖ SG は

    L3/4=IP・ポート・プロトコルだけを見る ❖ Web を公開する以上、443 は許可する ❖ 443 の上を流れる“正当な形”の GET は、中身が何であれ関知外
  13. マネージドルールも万能でない ── 検査に上限、認可は対象外 “既知パターン”照合+検査上限 ── 上限外は素通り、認可は対象外 ❖ WAF は“既知パターン”照合(マネージドルールは OWASP

    Top10 等が対象) ❖ ボディ検査上限: ALB/AppSync=8KB・CloudFront等=既定16KB(最大64KB)、ヘッダ/ク ッキー各8KB・200個 ❖ 許可時はリクエスト全体が転送=上限外は素通り ❖ そして認可はルールの対象外(何を書いても判断できない)
  14. だから“認可”は誰も見ていない ── 中身の正当性は境界の対象外 SG=形を見た・WAF=パターンを見た・でも“誰のデータか”は誰も見ていない STEP 1 STEP 2 STEP 3

    STEP 4 リクエスト SG: 形OK WAF: パターンOK アプリの認可 /cust/124 IP・ポートは通過 攻撃パターン無し=通過 ここで初めて “誰のデータか”を判断 境界を全部通り抜けた先で、初めてアプリが認可を判断できる
  15. 脅威ごとに“受ける層”を決める ── IDOR/BOLA はアプリのみ SQLi/XSS は境界+アプリ / IDOR/BOLA はアプリだけが砦 脅威

    WAF (L7) SG/NACL (L3/4) アプリ (コード) SQLi △ 緩和 (既知パターン) × ◎ 根治 (プレースホルダ/第2回) XSS △ 緩和 (既知パターン) × ◎ 根治 (出力エスケープ/第3回) SSRF △ 一部 (メタデータ検知) × IMDS不可 (egressで宛先限定) ◎ URL検証+IMDSv2 (第2回) IDOR/BOLA 認可不備 × 止まらない (文法的に正当) × ◎ 唯一の砦 Object単位の認可(第1回)
  16. SQLi/XSSは“境界+アプリ”の二重で受ける ── WAFは時間稼ぎ WAF=緩和(攻撃を減らす) / コード=根治 WAF = 緩和層 アプリ

    = 根治層 既知パターンを弾く =攻撃を減らす・稼ぐ プレースホルダ(第2回) 出力エスケープ(第3回) WAF は“緩和/仮想パッチ” ── 根治はコード(検査上限があり完全ではない)
  17. IDOR/BOLA/認可不備は“アプリのみ” ── 第1回の認可が唯一の砦 境界を全部通り抜けても、アプリの明示的認可があれば 124 は 403 STEP 1 STEP

    2 STEP 3 STEP 4 リクエスト 124 SG 通過 WAF 通過 アプリの認可 他人のIDに書き換え 形はOK パターン無し=OK Object単位の認可 → 403 境界を全通過した後、最後のアプリ認可で初めて 403 ──「WAFがあるから認可を省略」は最悪の設計
  18. SSRFは“egress+アプリ+IMDSv2”で受ける ── SG/NACLではIMDSを止められない 出口(egress)で宛先を絞る / IMDS は境界の外=IMDSv2で守る egress + アプリ

    出口で外部宛先を限定 アプリのURL検証(第2回) IMDS は境界の外 169.254.169.254 は SG/NACLで止められない → IMDSv2+hop制限(第2回) AWS公式明言: SG も NACL も IMDS 宛/発トラフィックはフィルタしない ── 第一防御は IMDSv2
  19. L3/4をどう設計しても、認可は SG も NACL も見ていない SG=基本境界(ENIに付ける) / NACL=粗いサブネット遮断 外側 サブネット

    インスタンス 外部 NACL SG インターネット 粗いサブネット遮断 ステートレス 基本境界(ENI) ステートフル どちらも IMDS は止められず、認可(中身)も見ていない(詳細比較は A2)
  20. WAFを運用で磨いても、認可はルールの対象外 磨くべきは磨き、認可はアプリで ── 別の仕事 ルール レート ログ マネージドルールを 本番前にテスト・調整 1分/5分の超過を

    ブロック・カウント CloudWatch Logs S3 / Data Firehose この3点をどれだけ磨いても“認可”の枠は空のまま ── 認可はアプリの仕事
  21. 多層防御(defense in depth): 1枚の壁に頼らない 境界・ネットワーク・アプリ・監視 ── どれか1層が抜かれても次で止める 第1層 第2層 第3層

    第4層 境界 (WAF/SG) ネットワーク 分離 アプリ (認可) 監視 (ログ) IDOR/BOLA を根治 素通りを検知(第6回) SQLi/XSS を緩和 NACL/セグメント 「WAFがあるから安全」ではなく「WAFも、SGも、認可も、ログも」
  22. 脅威→対策マッピング: 境界は“形”を、アプリは“認可”を 全編の背骨を1枚に ── 22枚目の2軸に対策を重ねる 境界 = 形 → 対策

    アプリ = 認可 → 対策 SQLi/XSS=WAF緩和 SSRF=egressで宛先限定 IDOR/BOLA=Object単位の認可 SSRF=URL検証+IMDSv2 どの層で受けるかを決め、多層で守る(境界=形 / アプリ=認可)
  23. Next action: 明日からできる3つ 抽象で終わらせず、明日からの具体に落とす 1. 棚卸し 2. 認可確認 3. ログ有効化

    WAF/SG の ACL・ルール・ポ ートを棚卸し 「何を止め何を通すか」を書 き出す WAF任せの画面/APIに アプリ側の認可(第1回)があ るか確認 WAFログ・VPCフローログの 出力を有効化 (第6回の準備)
  24. A1: AWS WAF の構成 関連付け先・マネージドルール・検査上限・ログ(G1〜G4) ❖ 関連付け先: CloudFront/API Gateway/ALB/AppSync/Cognito/App Runner/Verified

    Access 等 ❖ マネージドルール: CRS/SQL database/Known bad inputs/PHP application 等(CRS は OWASP Top10 等が対象) ❖ ボディ検査上限: ALB/AppSync=8KB・CloudFront等=既定16KB(最大64KB)、ヘッダ/ク ッキー各8KB・200個、許可時は全体転送 ❖ レートベースルール / ログ出力先: CloudWatch Logs・S3・Data Firehose
  25. A2: Security Group vs NACL 詳細比較 どちらも IMDS は止められない(G5/G6/G8) 観点

    Security Group NACL 状態 ステートフル (戻り自動許可) ステートレス (戻りも明示) 適用単位 リソース(ENI) サブネット ルール 許可のみ 許可+拒否 評価 全ルール評価 番号順・最初の一致 IMDS 止められない 止められない
  26. A3: ファイアウォールの種類(CCT) 種類と機能する層(F5/F6/F7) 種類 機能する層 パケットフィルタリング IP層/TP層(L3/4) ステートフルマルチレイヤ インスペクション 複数層

    サーキットレベルGW セッション層 アプリケーションレベルGW アプリ層(L7) アプリケーションプロキシ/NAT/VPN ─
  27. A6: 用語・出典リンク集 F/G の出典(CCTページ / 公式URL) 項目 出典 CCT ネットワークセキュリティ

    CCT eBook Module 07(書籍709〜) AWS WAF docs.aws.amazon.com/waf/…/what-is-aws-waf.html AWS Managed Rules docs.aws.amazon.com/waf/…/aws-managed-rule-groups-list.html WAF 検査上限 docs.aws.amazon.com/waf/…/waf-oversize-request-components.html SG / NACL docs.aws.amazon.com/vpc/…/vpc-security-groups.html ・vpc-network-acls.html OWASP A01:2021 owasp.org/Top10/2021/A01_2021-Broken_Access_Control/