0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

同じWAFが、SQLiは弾くのにIDORは素通しする ── 境界防御とアプリ認可の線引き

0
Posted at

はじめに ── 同じWAFが、SQLiは弾くのにIDORは素通しする

数年前の私は、「AWS WAF とセキュリティグループを入れたんだから、もう安全だろう」と本気で思っていました。インフラで境界を固めた、だからアプリ側の対策は後回しでいい、と考えていたのです。第1回で扱った IDOR(他人の ID を指定して他人のデータを見てしまう脆弱性)も、WAF が止めてくれるものだと思い込んでいました。

その思い込みは、ある実験で崩れました。同じ1台の WAF に、宛先も認証済みセッションも固定したまま、2種類のリクエストを投げます。

  • (A) SQL インジェクションのペイロードを送ると、WAF は 403 Forbidden弾きました
  • (B) 認証済みのまま ID だけ他人のものに書き換えた、ごく普通の GET を送ると、200 OK で他人のデータが返ってきました

同じ WAF です。攻撃の「形」をしている (A) は止めたのに、正当な「形」の (B) は素通しにしました。ここでようやく気づきました。その WAF、「誰がそのデータを見てよいか」まで判断してくれてはいなかったのです。

この記事は、そんなちょっと前の私に向けて書きます。

想定読者:

  • AWS WAF やセキュリティグループを導入して「インフラで境界を固めたから大丈夫」と考え、アプリ側の認可(特にオブジェクト単位)を後回しにしていた Web アプリ開発者
  • WAF が何を止めて何を通すのか、L3/4(セキュリティグループ)と L7(WAF)の違いをあまり意識していなかった人

この記事のゴールは、境界防御(WAF / セキュリティグループ)とアプリの認可の「線引き」を持ち帰ることです。何が境界で防げて、何が境界では防げずアプリでしか防げないのか。その線を引けるようになるのが到達点です。

本記事は社内セキュリティ勉強会シリーズ(全6回)の第5回です。ロードマップは次のとおりで、今回は境界に重心を置きます。

  • 第1回: 認証・認可(IDOR)
  • 第2回: インジェクション・SSRF
  • 第3回: XSS・CSRF・セッション
  • 第4回: 暗号・シークレット
  • 第5回: ネットワーク・WAF(本記事 = 現在地)
  • 第6回: ログ・追跡

第2回では「入口は WAF・ネットワーク境界で塞ぐ、詳しくは第5回で」、第4回では「暗号の入口である SSRF などは境界・WAF で、第5回で」と送りました。その伏線を、この記事で回収します。当日の発表スライドも公開しているので、あわせてご覧ください。

先に結論(この記事で伝えたい3点)

細かい説明に入る前に、いちばん伝えたいことを3つ先に出します。

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

この3点を、以降の本文でほどいていきます。冒頭の「SQLi は弾くのに IDOR は素通し」という現象は、この3点がわかれば当然の帰結として腑に落ちます。

この記事で扱うこと・扱わないこと

対象技術とバージョンは次のとおりです。

  • AWS WAF(v2): Web ACL を CloudFront / ALB / API Gateway などに関連付ける L7 の Web アプリケーションファイアウォール
  • Amazon VPC: セキュリティグループ(ステートフル・ENI 単位・L3/4)/ ネットワーク ACL(ステートレス・サブネット単位)
  • Amazon EC2 IMDS: インスタンスメタデータサービス(169.254.169.254)
  • Laravel 13.x(新規)+ FuelPHP 1.x(レガシー)、言語は PHP
  • OWASP Top 10: A01:2021 Broken Access Control
  • CCT 日本語 eBook: Module 07(Network Security Controls – Technical Controls)
  • WAF の検査サイズ上限などの数値は 2026年7月時点の現行値です(AWS が将来変更しうるため、実際の設計時は公式ドキュメントで再確認してください)

範囲を絞るため、次の項目は本記事では深追いしません。いずれも重要ですが、1記事に詰め込むと焦点がぼやけます。

  • TLS / HTTPS が前提であること自体は当然として、暗号の中身には踏み込みません(第4回で扱います)。
  • IDOR / 認可の具体的な実装コード(オブジェクト単位の認可)は第1回で扱ったので、本記事では再解説せず結線だけします。
  • SQLi のプレースホルダ・SSRF の URL 検証・IMDSv2 の実装は第2回、XSS の出力エスケープの実装は第3回で扱っています。
  • 境界を素通りした攻撃の検知・追跡(WAF ログ / VPC フローログ / GuardDuty)は第6回で扱います。

ここでは「境界とアプリ認可の線引き」の一点に絞ります。

境界防御は「通信の形」を判断する

まず、WAF とセキュリティグループが何を判断する道具なのかを正しく揃えます。ここが揃うと、冒頭の「SQLi は弾くのに IDOR は素通し」がなぜ起きるのかが構造で見えてきます。

境界防御とは、信頼できない外部と内部を分け、入口で通信を制限する仕組みです。ただし境界は最初の関門であって、唯一の関門ではありません。図のように、境界の内側にはネットワーク分離、アプリの認可、データの暗号と、層が続きます。

CCT の教材でも、ファイアウォールの機能は「流れる全トラフィックをルールセットの基準で検査し、明示的に許可されたトラフィックのみ通し、他はデフォルトで拒否する。各パケットを検査して宛先へ送るか判定し、侵入を記録する」と説明されています(出典: CCT eBook 書籍825/PDF836)。ファイアウォールにはいくつか種類があり、機能する層が異なります(出典: CCT eBook 書籍791・806-811/PDF802・817-822)。

ファイアウォールの種類(CCT) 機能する層
パケットフィルタリング IP層 / トランスポート層(L3/4)
ステートフルマルチレイヤインスペクション 複数層
サーキットレベルゲートウェイ セッション層
アプリケーションレベルゲートウェイ アプリケーション層(L7)

この表の両端、パケットフィルタ(L3/4)とアプリケーションレベルゲートウェイ(L7)が、それぞれ AWS のセキュリティグループと AWS WAF に対応します。順に見ていきます。

セキュリティグループ = L3/4 のパケットフィルタ

CCT のパケットフィルタリングファイアウォールは、TCP/IP の IP 層(ネットワーク層)とトランスポート層、いわゆる L3/4 で機能し、送信元/宛先の IP アドレス・ポート・プロトコルなどでパケットを許可またはドロップします(出典: CCT eBook 書籍806-807/PDF817-818)。判断材料は通信の「形」だけです。

これに対応する AWS の実体がセキュリティグループです。EC2 インスタンスや ENI といったリソースに付く仮想ファイアウォールで、次の性質を持ちます(出典: https://docs.aws.amazon.com/vpc/latest/userguide/vpc-security-groups.html)。

  • ステートフル: 許可した通信の戻りは、インバウンドルールに関係なく自動で許可される
  • 許可ルールのみを持つ(拒否ルールは書けない)
  • リソース(ENI)単位で適用する

どちらも見ているのは IP・ポート・プロトコル、つまり L3/4 の「形」だけで、HTTP の中身は見ていません。

AWS WAF = L7 の門番

CCT のアプリケーションレベルゲートウェイは、OSI モデルのアプリケーション層(L7)で機能し、http:postget などのアプリケーション層コマンドを検査します(出典: CCT eBook 書籍811/PDF822)。

これに対応するのが AWS WAF です。Web ACL を CloudFront ディストリビューション・Application Load Balancer・API Gateway・AppSync などに関連付けて HTTP / HTTPS リクエストを検査し、一致すれば Allow / Block(HTTP 403)/ Count / CAPTCHA・challenge のいずれかを返します(出典: https://docs.aws.amazon.com/waf/latest/developerguide/what-is-aws-waf.html)。

SQLi や XSS のような既知の攻撃パターンは、AWS Managed Rules で検知・ブロックできます。マネージドルールには Core rule set(CRS)/ Admin protection / Known bad inputs / SQL database / PHP application などがあり、CRS は「Web アプリに一般的に適用でき、OWASP Top 10 など OWASP 刊行物に記載の高リスク・多発脆弱性を含む広範な脆弱性の悪用から保護する」と明記されています(出典: https://docs.aws.amazon.com/waf/latest/developerguide/aws-managed-rule-groups-list.html)。

セキュリティグループより一段深く「中身」を見ますが、見ているのはあくまで既知の「パターン」です。

境界は「形」と「パターン」まで ── 認可はまだ誰も見ていない

ここまでを1行にまとめます。

  • セキュリティグループは L3/4 の「形」(IP・ポート)を見る。
  • WAF は L7 の既知「パターン」を見る。

どちらも「このリクエストは正当な形か」までしか見ていません。「この人がこのデータを見てよいか」という認可の判断は、まだどこでもされていないのです。

この差が、冒頭の現象の正体です。では実際に、境界に2種類のリクエストを投げてみましょう。

【実演】同じWAFが、SQLiは弾いてIDORは素通しする

ここが本記事の山場です。以下は example.com を使った説明用のフィクスチャで、値そのものは架空です。ただし構図は本物で、第1回で見た billpay.com/api/v1/cust/459(CCT 教材由来)と同じものを、境界の視点から見直します。

デモの前提 ── 宛先も認証も同じ、変えるのは中身だけ

条件をそろえます。宛先の WAF も、認証済みのセッションも固定です。変えるのは、投げるリクエストの中身だけです。

  • (A) SQLi のペイロード ' or '1'='1(URL エンコードして混ぜる)
  • (B) IDOR、つまり認証済みのまま ID を 124 に書き換えた GET /api/v1/cust/124

まず正常時の動きを押さえておきます。自分のデータは GET /api/v1/cust/123 で返ります。

$ curl -i "https://app.example.com/api/v1/cust/123"
HTTP/1.1 200 OK
Content-Type: application/json

{"id":123,"name":"山田太郎","email":"taro@example.com"}   ← 自分のデータ

このあと、(A) は止まるのに (B) は通ってしまう、という対比に注目してください。

反例: SQLiペイロードはWAFが403でブロックする

まず (A)、SQLi のペイロードを送ります。

# 認証済みセッションで、顧客API(/cust/)の ID 位置に SQLi ペイロードを混ぜて送る(' or '1'='1 を URL エンコード)
$ curl -i "https://app.example.com/api/v1/cust/%27%20or%20%271%27%3D%271"
HTTP/1.1 403 Forbidden          ← AWS WAF のマネージドルール(SQLi 検知)がブロック
Server: awselb/2.0
# ボディ: WAF によりリクエストが拒否された旨(AWS WAF の block アクション)
# → 境界(WAF)は「攻撃の"形"」を認識して止めた

返ってきたのは 403 Forbidden。WAF のマネージドルールが「攻撃の形」を認識してブロックしました。境界は確かに効いています。

ただし一点だけ注意します。これは SQLi 検知ルールを有効にした前提の一例で、設定やペイロード次第で弾かれないこともあります。「WAF は常に SQLi を弾く」と一般化はしないでください(その理由は後半の「なぜ素通しするのか」で扱います)。ここで見てほしいのは、攻撃の「形」をしたリクエストは境界で止まるという事実です。

山場: GET /api/v1/cust/124 は WAF も SG も素通しで 200

では (B)。同じ WAF、同じ認証済みセッションのまま、ID を 124 に書き換えただけの、ごく普通の GET です。

# 同じWAF・同じ認証済みセッションで、ID を 124 に書き換えただけの"正当な形"の GET
$ curl -i "https://app.example.com/api/v1/cust/124"
HTTP/1.1 200 OK                 ← WAF に一致する攻撃パターンなし・SG は 443 許可済み → 何も止めない
Content-Type: application/json

{"id":124,"name":"佐藤花子","email":"hanako@example.com"}   ← 他人のデータが返る(=IDOR)
# → 境界は「文法的に正当な HTTP GET」を止める理由がない。認可はアプリ側の仕事

200 OK。返ってきたのは他人(佐藤花子さん)の氏名とメールアドレスです。WAF に一致する攻撃パターンはなく、セキュリティグループは 443(HTTPS)を許可済みなので、境界は何も止めませんでした。

同じ WAF です。SQLi は止めたのに、IDOR は通しました。これが本記事でいちばん見てほしい場面です。

いま起きたこと ── 境界は「攻撃の形」は弾くが認可は見ていない

いま起きたことを言葉にします。

  • (A) SQLi → 403: 既知の攻撃パターンに一致したから弾いた
  • (B) IDOR → 200: 文法的に正当な HTTP GET だから通した

境界は「形」で判断していて、中身が「誰のものか」は見ていません。CCT もファイアウォールの限界として「一般的なポートやアプリケーションから発生する攻撃を防御するものではない」と明記しています(出典: CCT eBook 書籍826-827/PDF837-838)。IDOR はまさに、一般的なポート(443)と正当なアプリケーション操作(GET)を悪用する攻撃です。

なお、こうやって ID を総当たりで試す挙動をログで検知して追跡する話は、第6回で扱います(近日公開予定)。次は、なぜ (B) が素通しするのかを構造で見ます。

なぜ素通しするのか ── 境界に「見えないもの」

さきほど体感した「なんとなく怖い」を、ここから「境界の構造的な限界」という言葉にきちんと翻訳していきます。

WAFは「攻撃パターン」を探す ── 正当なGETには一致しない

WAF は、シグネチャやルールで既知の攻撃(SQLi や XSS)を照合する道具です。図のように、/api/v1/cust/124 は文法的にまったく正当な HTTP リクエストで、どの攻撃パターンにも一致しません

SQLi のほうは一致して 403 になりましたが、IDOR は不一致だから許可され、アプリへ素通りします。「正しく見える通信」を止める理由が、WAF には無いのです。マネージドルールは「既知」にしか反応しません。

セキュリティグループは「通信の形」しか見ない

ではセキュリティグループはどうか。すでに見たとおり、セキュリティグループは L3/4、IP・ポート・プロトコルだけを見ます。

Web サービスを公開する以上、443 番ポートは許可しないといけません。すると、その 443 の上を流れる「正当な形」の GET は、中身が何であってもセキュリティグループの関知外です。CCT もファイアウォールの限界として「パスワードの不正使用を防ぐものではない」「上位プロトコル層(アプリ層)からの攻撃をブロックしない」と明記しています(出典: CCT eBook 書籍826-827/PDF837-838)。セキュリティグループは通信の形しか見ていないので、中身の悪用は止められません。

CCTも明言 ── 限界を知らずに使うと「誤った安心感」を生む

ここが本記事の思想的な核です。CCT の教材には、こう書かれています。

ファイアウォールは、限界を理解せずに導入すると、誤った安心感を与えてしまうことがある。

そして限界の一つとして「プロトコルスタックの上位レベル(=アプリケーション層)からの攻撃をブロックしない」と明言しています(出典: CCT eBook 書籍826-827/PDF837-838)。

今回の IDOR や認可不備は、まさにこのアプリケーション層で起きる「正当な操作の悪用」です。攻撃の形をしておらず、正当な操作に見える。だから境界では止まりません。「境界を入れたから安全」という誤解を解く中心が、この一節です。境界は必須ですが、万能ではありません。

マネージドルールも万能でない ── 検査に上限、認可は対象外

「マネージドルールを全部有効にすれば防げるのでは?」と思うかもしれません。ここも過信は禁物で、理由は2つあります。

1つ目、WAF の検査には上限があります。AWS WAF のボディ検査サイズ上限は、2026年7月時点で次のとおりです(出典: https://docs.aws.amazon.com/waf/latest/developerguide/waf-oversize-request-components.html)。

  • ボディ / JSON ボディ: Application Load Balancer と AppSync は先頭 8KB(固定・引き上げ不可)、CloudFront・API Gateway・Cognito・App Runner・Verified Access は既定 16KB(Web ACL 設定で最大 64KB まで引き上げ可)
  • ヘッダ: 先頭 8KB かつ先頭 200個 まで
  • クッキー: 先頭 8KB かつ先頭 200個 まで

そして重要なのは、AWS 公式が「AWS WAF がリクエストを許可して保護対象へ通すとき、検査できたサイズ・数の上限を超える内容も含め、リクエスト全体が送られる」と明記している点です。つまり上限を超えた部分は検査されずに素通りします。

2つ目、そもそも認可はルールの対象外です。何を書いても、WAF に「この人がこのデータを見てよいか」は判断できません。

だから WAF は「緩和(あるいは仮想パッチ)」であって、コードの根治の代替にはなりません。

だから「認可」は誰も見ていない

まとめます。セキュリティグループは形を見た、WAF はパターンを見た。でも「この人がこのデータを見てよいか」は、誰も見ていません。

リクエストはセキュリティグループを通り、WAF を通り、境界を全部通り抜けた先で、初めてアプリが認可を判断できます。OWASP の A01:2021 も、次のように述べています。

Access control is only effective in trusted server-side code or server-less API, where the attacker cannot modify the access control check or metadata.
(アクセス制御は、攻撃者が改変できない信頼されたサーバサイドのコード、あるいはサーバレス API でのみ有効である)

(出典: https://owasp.org/Top10/2021/A01_2021-Broken_Access_Control/)

だから認可はアプリで強制するしかありません。この線引きを、次章で設計の言葉に落とします。

どの脅威を、どの層で受けるか ── 線引きと多層防御

ここは羅列ではなく、1本の「線引き論」です。すべてが「認可はアプリ」に収束します。自社は Laravel の新規開発と FuelPHP のレガシー、両方を使っている前提で進めます。

線引きの原則 ── 境界は「形」を、アプリは「認可」を守る

核心の設計版はこれです。

  • **境界(WAF / セキュリティグループ)**は、通信の形と既知パターンを守る。これは必須の第一層です。
  • アプリは、誰が何を見てよいか、つまり認可を守る。これは境界の外側では代替できません。

大事なのは、両方が要るということです。境界だけでも守れませんし、アプリだけでも守れません。この2軸(境界 = 形、アプリ = 認可)が本記事の背骨です。

脅威 × 層マトリクス

第1回から第3回で扱った脅威を、どの層で受けるかに割り付け直したのが次の表です。これが設計判断の共有になります。

脅威 WAF(L7) セキュリティグループ / NACL(L3/4) アプリ(コード)
SQLi △ 緩和(既知パターンを弾く / 検査上限あり) × ◎ 根治(プレースホルダ = 第2回)
XSS △ 緩和(既知パターンを弾く) × ◎ 根治(出力エスケープ = 第3回)
SSRF △ 一部(メタデータ検知ルール等 / 上限あり) × IMDS は止められない(egress は外部宛先の限定) ◎ URL検証(第2回)+ IMDSv2(第2回)
IDOR / BOLA / 認可不備 × 止まらない(文法的に正当) × ◎ 唯一の砦 = Object単位の明示的認可(第1回)

「WAF で止まる / 止まらない」を列で明示しました。以下、行ごとに受け方を見ます。

SQLi / XSS ── WAFは緩和、根治はコード

SQLi と XSS は、WAF で既知パターンを弾いて攻撃を減らし、時間を稼げます。これは有用です。ただし、さきほど見たように検査には上限があり、許可時はリクエスト全体が転送されるので、完全ではありません

だから根治はコード側です。SQLi はプレースホルダ(第2回)、XSS は出力エスケープ(第3回)。WAF は「緩和 / 仮想パッチ」、コードが「根治」。この二重で受けるのが原則です。

IDOR / BOLA / 認可不備 ── アプリの認可だけが唯一の砦

ここが本記事の主役です。IDOR・BOLA・認可不備は、アプリのみで受けます。

他人の ID に書き換えた 124 は、セキュリティグループを通過し、WAF も通過し、境界を全部通り抜けます。それでも、アプリにオブジェクト単位の明示的な認可があれば、最後の最後で 403 になります。

この「オブジェクト単位の明示的な認可」の具体的な実装(FuelPHP の所有チェック、Laravel の Gate / Policy による集約認可)は、第1回で詳しく扱いました。本記事ではその実装を再掲せず、「境界を素通りした 124 を止める最後の関門はここ」という結線だけしておきます(第1回)。

強調したいのは、「WAF があるから認可を省略」は最悪の設計だということです。境界は認可を代わりに守ってくれません。

SSRF ── egress とアプリ、IMDSはIMDSv2で

SSRF の受け方は、役割分離が要点です。

まず入口だけでなく出口(egress)を絞ります。セキュリティグループのアウトバウンドや VPC エンドポイントで、アプリが余計な外部宛先へ出ないよう限定します。加えてアプリの URL 検証(第2回)を組み合わせます。

ただし、ここで最も間違えやすい点があります。SSRF の狙い先であるインスタンスメタデータ(IMDS、169.254.169.254)について、AWS 公式は次のように明記しています。

つまり、IMDS はセキュリティグループや NACL の egress では止められません。SSRF → IMDS の第一防御は IMDSv2 + hop 制限(第2回で扱った内容)です。egress は「外部宛先の限定」には使えますが、「IMDS の遮断」には使えません。ここを混同しないでください。

セキュリティグループとNACLの使い分け(と共通の限界)

設計の勘所は1点です。セキュリティグループを基本の境界として ENI に付け、NACL はサブネット単位の粗い遮断に使う。機構の詳細な比較は次の表のとおりです(出典: セキュリティグループ・NACL の各公式ドキュメント)。

観点 セキュリティグループ ネットワーク ACL
状態 ステートフル(戻り自動許可) ステートレス(戻りも明示)
適用単位 リソース(ENI) サブネット
ルール 許可のみ 許可 + 拒否
評価 全ルール評価 番号順・最初の一致
IMDS 止められない 止められない

そして忘れてはいけないのが、どちらも IMDS は止められず、認可(中身)も見ていないことです。L3/4 をどう設計しても、「誰がこのデータを見てよいか」はセキュリティグループも NACL も見ていません。

WAFは運用で磨けるが、認可はルールの対象外

WAF は運用で磨く価値があります。ポイントは3点です(出典: AWS WAF 公式ドキュメント)。

  • ルール: マネージドルールを本番前にテスト・チューニングする(AWS 自身が本番前のテストを推奨しています)
  • レート: レートベースルールで、1分または5分あたりのリクエスト数が指定を超えたものをブロック / カウントする
  • ログ: Web ACL のトラフィックログを CloudWatch Logs・S3・Amazon Data Firehose に出力する

これらは有用です。でも、どれだけ磨いても認可はルールの対象外です。「誰がこのデータを見てよいか」はルールに書けません。WAF の磨き込みは境界の仕事、アプリの認可は中身の仕事。別の仕事です(ログの活用・GuardDuty・VPC フローログは第6回で扱います)。

多層防御(defense in depth)── 1枚の壁に頼らない

ここで最初の層図に戻り、各層に対応する脅威を重ねます。

第1層の境界で SQLi や XSS を緩和し、第3層のアプリの認可で IDOR や BOLA を根治し、第4層の監視で素通りを検知する。これが**多層防御(defense in depth)**です。どれか1層が抜かれても、次の層で止めます。「WAF があるから安全」ではなく、「WAF も、セキュリティグループも、認可も、ログも」。全部が要る、というのが核心です。

レガシー / FuelPHPでも今日から

最後に、明日からの話です。「うちはレガシーの FuelPHP だから無理」で終わらせないでほしいのです。

  • 「WAF / セキュリティグループがあるから認可は省略していい」という発想をやめる(最内層は必ずコードです)。
  • FuelPHP やレガシーでも、所有チェック(第1回でやった認可の集約)は書けます。
  • 境界の運用は運用チームの仕事、認可は開発の仕事。この両輪です。

冒頭で私が「境界を固めたからアプリは後回し」と思っていた、あの失敗への答えがこれです。

脅威 → 対策マッピング

さきほどの「脅威 × 層マトリクス」が WAF / SG・NACL / アプリの3層で受け止め方を細かく見た表なら、こちらは層の内訳を畳んで「境界(形)か、アプリ(認可・中身)か」の2軸に絞った、持ち帰り用の1枚です。

脅威 境界(形)での対策 アプリ(認可・中身)での対策
SQLi WAF で緩和(既知パターン) プレースホルダで根治(第2回)
XSS WAF で緩和(既知パターン) 出力エスケープで根治(第3回)
SSRF egress で外部宛先を限定 URL検証 + IMDSv2(第2回)
IDOR / BOLA 止められない(文法的に正当) Object単位の明示的認可(第1回)

どの層で受けるかを決め、多層で守る。これが第1回から続く「脅威の地図」の、境界視点での姿です。

まとめ ── 「WAFがあるから安全」ではない

最後に、この記事の要点を振り返ります。冒頭に出した結論3点と、同じ言葉で締めます。

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

同じ WAF が SQLi は弾くのに IDOR は素通しした理由は、いまなら当然の帰結として見えるはずです。境界は「形」を見て「攻撃の形」を止めますが、GET /cust/124 のように文法的に正当な操作の悪用は、形をしていないので止まりません。「誰がこのデータを見てよいか」は、境界を全部通り抜けた先のアプリでしか判断できないのです。

ちょっと前の私がいちばん助かったであろう一言は、「境界は必須だが、認可の代わりにはならない」でした。ここが腑に落ちると、WAF の設定も、セキュリティグループのポートも、アプリの認可の1行も、すべて「どの脅威をどの層で受けるか」という一本の線でつながります。

Next action: 明日からできる3つ

理想論で終わらせないために、明日からできる具体を3つ挙げます。

  1. 棚卸し: WAF とセキュリティグループの Web ACL・ルール・ポートを棚卸しして、「何を止めて、何を通しているか」を書き出す。
  2. 認可確認: WAF 任せにしている画面や API に、アプリ側の認可(第1回)がちゃんとあるかを確認する。
  3. ログ有効化: WAF ログと VPC フローログの出力を有効化する(第6回、ログと追跡の準備になります)。

このうち1つでも赤信号があれば、そこが「境界任せ」の穴です。まずは棚卸しから始めてみてください。

あわせて読みたい

本シリーズは順次公開予定です。公開され次第、以下の「近日公開予定」を実 URL に差し替えます(未公開のうちはハードリンクしません)。

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?