1-4. OWASP Top 10 - Webアプリ脆弱性の地図

所要時間: 35-50分 ゴール: OWASP Top 10(2021年版)の10項目それぞれの本質、典型的な攻撃、最低限の対策を概観できる。自分のサービスがどこに弱いか感覚を持つ コミット内容: 自サービス(架空でOK)の Top 10 自己点検チェックリストを ~/learn/security/day04_owasp/checklist.md に残す


前章とのつながり

このレッスンの位置づけ

1-1〜1-3 で 「認証 / 認可 / 通信路」 という基礎の3本柱を立てた。本章は 業界全体が共有する『脆弱性地図』 を概観する回。

  • 1-1 で学んだ AuthN/AuthZ は A01 (Broken Access Control) と A07 (Auth Failures) に直結
  • 1-2 のパスワード保存は A02 (Cryptographic Failures) と A07
  • 1-3 の HTTPS/TLS は A02
  • 次章 1-5 SQLi / 1-6 XSS は A03 (Injection) の深掘り

本章は「目次」、次章以降が「各章本文」。ここで全体地図を頭に入れておくと、後続の個別深掘りが「全体のどこの話か」分かって理解が速くなる(スキャフォールディング)。

実害シーン: Top 10 の実被害

  • A01 Broken Access Control: First American Financial の 8.85億件流出 (2019)
  • A02 Cryptographic Failures: Equifax の 1.4億件流出 (2017、暗号通信の不適切実装)
  • A03 Injection: TalkTalk の 400万件流出 (2015、SQLi)
  • A06 Vulnerable Components: Equifax (Struts2 の既知脆弱性放置、上記と同事件)
  • A07 Auth Failures: Disney+ ローンチ時のクレデンシャル・スタッフィング攻撃

Top 10 を語れる」は、防御側として最低限のリテラシー。攻撃手法を知らないと防御もできない。


大前提: OWASP Top 10 は「最低限知ってないと恥」のリスト

OWASP(Open Web Application Security Project) は、Web アプリのセキュリティを推進する非営利団体。彼らが数年に一度発表する Top 10 は、世界中の脆弱性データを集計した「現代Webアプリで最も多い・致命的な脆弱性 トップ10」。

採用面接、コードレビュー、社内研修、すべてで前提知識として扱われる。バックエンドエンジニアで「OWASP Top 10 を聞いたことがない」は転職市場で不利になるレベル

このレッスンでは2021年版(次回更新は2024-2025年予定)の10項目を概観する。深掘りは別レッスン(SQL Injection、XSS など)で個別に行う。

各項目について 「これは何か」「実例」「最低限の対策」 をセットで覚える。完璧主義より「全項目を1分で説明できる」を目指す。


セッション①: A01〜A05(25-30分)

0. 録画&メモ準備

mkdir -p ~/log ~/learn/security/day04_owasp
cd ~/learn/security/day04_owasp
script ~/log/security_day04.log

A01: Broken Access Control(アクセス制御の不備)

2021年版で1位に躍進。前回4位から急上昇した、現代Webで最大の脆弱性カテゴリ。

A01 の本質

認可(AuthZ)が壊れている / 欠けている問題。

「ログインしたユーザーが、本来見られないはずのリソースを見られる」が典型。

代表的なパターン:

  • IDOR(Insecure Direct Object Reference): URLに /users/1234/profile のようにIDを直書きしていて、他人のID 5678 に書き換えれば他人のデータが見える
  • 権限昇格: 一般ユーザーが /admin/... を叩いたら通ってしまう
  • 強制ブラウジング: ログイン前提のURLにログインせず直接アクセスできる
  • CORS設定ミス: Access-Control-Allow-Origin: * で全ドメインに API を開放してしまう

実例: First American Financial Corp (2019)

9億件の不動産取引文書がURL改変で見えてしまった。document/1document/2 document/3 … と辿るだけで、認証なしで他社の契約書がダウンロードできた。

典型的な IDOR で、保険会社の評価額1.4億ドル相当の事故になった。

A01 の最低限対策

  • すべてのエンドポイントで「リソース所有者か」をチェック
  • ID は連番ではなく UUID やランダム文字列に(推測不能化)
  • 管理画面のURLにアクセスした時点でロール検証
  • 「default deny」: 明示的に許可した操作以外は全部拒否

A02: Cryptographic Failures(暗号化の不備)

旧称「Sensitive Data Exposure」(機密データの露出)。

A02 の本質

暗号化を「やってない」「やってるけど弱い」「鍵管理がずさん」のいずれか。

パターン:

  • HTTPS を使っていない(前回で扱った)
  • 平文でパスワード保存1-2回目で扱った)
  • 古い暗号アルゴリズム(MD5、SHA-1、DES、RC4)の使用
  • ハードコードされた秘密鍵がリポジトリに混入
  • 通信路の暗号化はあるが、DB内は平文 = DBダンプで全漏洩

実例: Adobe (2013)

1.5億件流出。パスワードを 可逆暗号化(共通鍵 + 弱いモード)で保存していたため、漏洩時に大半が解読された。「パスワードヒント」も同時漏洩していたので解読が促進された。

「ハッシュ化」と「暗号化」を混同した典型例として今も語り継がれる。

A02 の最低限対策

  • HTTPS 必須(HSTS で強制)
  • パスワードは bcrypt / argon2id
  • 機密データ(クレカ番号、マイナンバー)はDB保存時にも暗号化
  • 秘密鍵・APIキーは環境変数 or KMS、ソースコードに書かない
  • 古いアルゴリズム(MD5、SHA-1、DES)を排除

A03: Injection(インジェクション)

ずっと長年首位だった代表選手。2021年版で3位に下がったが依然重大。

A03 の本質

ユーザー入力を コードや構文の一部として解釈させる 攻撃の総称。

種類:

  • SQL Injection (SQLi): SQL文に悪意ある文字列が混入し、想定外のクエリが実行される
  • コマンドインジェクション: シェルコマンドに混入(os.system("ping " + user_input) のような実装)
  • LDAP インジェクション: LDAP クエリへの混入
  • NoSQL インジェクション: MongoDB などへの混入(クエリ言語がJSONでも発生する)
  • テンプレートインジェクション: テンプレートエンジンに評価される構文を流し込む(SSTI)

実例: Sony Pictures (2011) / TalkTalk (2015)

どちらも SQL Injection が侵入の起点。Sonyは7700万件、TalkTalkは15.7万件流出。

数十年前から知られている古典的攻撃なのに、未だに大企業で起きるレベル。ORMがあっても生SQLを書く場面で油断すると死ぬ

A03 の最低限対策

  • prepared statement / placeholder(? $1)を絶対に使う
  • 文字列連結でSQLを組み立てない
  • 入力検証(許可リスト / allowlist)も併用
  • ORM の生SQL機能を使う場合は特に注意
  • 詳細は次レッスン 1-5 SQL Injection

A04: Insecure Design(安全でない設計)

A04 の本質

コード単体ではなく、設計レベルで セキュリティ要件が抜けている問題。Top 10 に2021年から新登場。

パターン:

  • 「パスワードリセット」のフローが甘い(ヒント質問が「母の旧姓」など特定容易)
  • 「電話番号でアカウント復旧」させる仕様(SIMスワップで乗っ取られる)
  • レート制限の欠如(ログイン試行・SMS送信が無制限)
  • 削除機能の認可が「IDが一致するだけ」(CSRFと組み合わせて他人に削除される)

コードがきれいでも、仕様が壊れていれば脆弱

実例: Twitterの「SMS復旧」乗っ取り

2019年頃から多発した、SIMスワップ攻撃による著名人アカウントの乗っ取り。CEOのジャック・ドーシー本人も被害に。

「電話番号で復旧できる」という仕様自体が脆弱だった。SMS自体は技術的に攻撃されていない、設計が悪い。

A04 の最低限対策

  • 設計段階で脅威モデリング(STRIDE)1-1で扱った)
  • デフォルト安全な仕様(オプトインではなくオプトアウト)
  • 多層防御(defense in depth): 1つの仕組みが破られても他で守れる
  • レート制限・MFA・監査ログを設計時から組み込む

A05: Security Misconfiguration(設定の不備)

A05 の本質

ソフトウェアの 設定 が安全でない状態。コードに穴がなくても設定で穴を開けてしまうパターン。

パターン:

  • デフォルトパスワード で運用(admin/admin)
  • デバッグモード本番有効化: スタックトレースが攻撃者に丸見え
  • 不要な機能が有効: 管理コンソール、サンプルアプリ、デフォルトアカウント
  • HTTPヘッダー欠如: CSP、X-Frame-Options、X-Content-Type-Options
  • クラウドストレージ公開: S3バケットを誤って public にしてデータ全公開
  • Docker イメージに認証情報埋め込み

実例: Capital One (2019)

1億件流出。AWS の WAF 設定ミスで、攻撃者が EC2 のメタデータエンドポイントから一時認証情報を取得し、S3 にアクセスできた。コードのバグというより設定ミス

元AWS従業員が攻撃者で、社内事情を知っていたため発見できた。

A05 の最低限対策

  • Infrastructure as Code(Terraform 等)で設定を明示
  • 本番でデバッグモード絶対オフ
  • 使わない機能・ポートはすべて閉じる(最小権限の原則)
  • クラウドのデフォルト公開設定に注意(S3、GCSは作成時に明示的にprivate)
  • セキュリティヘッダーをチェック(securityheaders.com で診断可能)

セッション②: A06〜A10(25-30分)

A06: Vulnerable and Outdated Components(脆弱・古いコンポーネント)

A06 の本質

自分のコードではなく、使っているライブラリ/フレームワーク に脆弱性があるパターン。

現代のWebアプリはコード行数の 9割が依存ライブラリ。これらに既知のCVE(脆弱性)があれば、自分のコードがどんなに完璧でもアウト。

パターン:

  • npm / pip / Go modules で古いバージョンを使い続けている
  • 「動いてるから触らない」運用
  • Docker のベースイメージが古い
  • OS パッケージのアップデートをサボっている

実例: Equifax (2017)

1.5億件の信用情報流出。Apache Struts 2 の脆弱性(CVE-2017-5638)が原因。パッチは攻撃の2ヶ月以上前に公開されていた が、適用されなかった。

「セキュリティパッチを当てるだけで防げた」事件。アメリカの個人情報漏洩史上トップクラスの事故。

A06 の最低限対策

  • npm audit / pip-audit / govulncheck を定期実行
  • Dependabot / Renovate で自動PRを受け取る
  • 依存をできるだけ少なく(左寄せの原則)
  • CVE情報をウォッチ(重要ライブラリは公式アカウントフォロー)
  • 古いランタイム(EOL過ぎたNode、Python)を本番で動かさない

A07: Identification and Authentication Failures(認証の不備)

A07 の本質

認証(AuthN)の仕組み自体に問題があるケース。

パターン:

  • クレデンシャル・スタッフィング許可: 他社流出パスワードのリストでログイン試行し放題
  • 弱いパスワードポリシー: 「abc123」が通る
  • セッションIDの推測可能: 連番、タイムスタンプベース
  • セッション固定攻撃: ログイン後にセッションIDを更新していない
  • MFAが任意: 攻撃対象になりやすい管理者アカウントも素のパスワードのみ
  • パスワードリセットフローの脆弱性(トークン長すぎ短すぎ、期限なし、ワンタイムでない)

実例: Dropbox (2012) からの連鎖被害

Dropbox から漏洩したパスワードハッシュリストが、その後 LinkedIn・GitHub などへの クレデンシャル・スタッフィング攻撃 に使われた。ユーザーがパスワード使い回しているため、1社の漏洩が他社の侵害につながる。

同様の事件は毎月どこかで起きている。

A07 の最低限対策

  • bcrypt / argon2id でハッシュ化(既出)
  • 流出パスワードDB(Have I Been Pwned API)と照合して登録時に弾く
  • レート制限: 5回失敗で15分ロック
  • MFA を提供、管理者には強制
  • セッションID は暗号学的乱数、ログイン成功時に再生成

A08: Software and Data Integrity Failures(整合性の不備)

A08 の本質

コード/データの「正しさ」が検証されていない 問題。サプライチェーン攻撃が主軸。

パターン:

  • 信頼できないソースからプラグイン/ライブラリを取得
  • CI/CD パイプラインに署名検証がない
  • 自動アップデートに署名検証がない
  • JWT の署名検証をスキップalg: none を許容)
  • シリアライズデータ(pickle、Java Serialization)の改ざんを検知しない

実例: SolarWinds (2020)

SolarWinds社のITソフトウェア「Orion」のアップデートにマルウェアが混入。正規の署名付きでアップデートが配布されたため、米連邦政府含む18000組織が侵害された。

ビルドパイプラインそのものが攻撃された、史上最悪級のサプライチェーン攻撃。

実例: event-stream (2018)

npm パッケージ event-stream のメンテナが別人に引き継いだ後、悪意あるコードが混入。ビットコインウォレットを盗む処理が仕込まれた。人気パッケージのメンテナ権限を譲るリスクを示した。

A08 の最低限対策

  • 依存ライブラリのバージョンを lock ファイルで固定(package-lock.json、go.sum)
  • subresource integrity (SRI): CDN から JS を読み込むとき integrity 属性でハッシュ検証
  • コンテナイメージに署名(Sigstore、cosign)
  • JWT のアルゴリズムを明示alg: none 拒否)

A09: Security Logging and Monitoring Failures(ログと監視の不備)

A09 の本質

攻撃を 検知できない 問題。

一般的な侵入から発見までの中央値は 200日以上(業界調査)。これは「ログを取っていない」「取っているが見ていない」「アラートが鳴らない」のいずれかが原因。

パターン:

  • 認証失敗・成功のログがない
  • 重要な操作(削除、権限変更、設定変更)のログがない
  • ログがアクセス可能な場所に保存(攻撃者が消せる)
  • アラート設定がない(あっても誤検知だらけで無視されている)
  • ログの長期保管(最低1年)がされていない

A09 の最低限対策

  • 認証イベント・認可失敗・重要操作を必ずログ化
  • ログは別ストレージに(攻撃者から守る)
  • 異常検知アラート(同一IPから連続失敗、深夜の管理者ログインなど)
  • SIEM(Splunk、Datadog Security、CloudWatch Logs Insights)への集約
  • インシデント対応プレイブック(事故発生時の手順書)を事前作成

A10: Server-Side Request Forgery (SSRF)

A10 の本質

アプリに 「指定されたURLを取りに行く」 機能があり、そのURLを攻撃者が 内部リソースに向けさせる 攻撃。

シナリオ:

  1. アプリに「画像URLを指定すればプロキシしてくれる」機能がある
  2. 攻撃者が http://169.254.169.254/latest/meta-data/ (AWS EC2 のメタデータエンドポイント)を指定
  3. アプリが内部から取得して結果を返す
  4. 攻撃者がEC2の一時認証情報を取得

実例: Capital One (2019、再登場)

上の A05 で書いたのと同じ事件。SSRF も同時に絡んでいた。WAF サーバーから内部メタデータエンドポイントへのリクエストを許してしまったのが原因。

A10 の最低限対策

  • ユーザー入力URLは必ず allowlist で検証
  • 内部IPアドレス(10.0.0.0/8、169.254.169.254 など)への接続をブロック
  • DNS解決結果も検証(外部ドメインのフリして内部IPを返すDNSリベインディング攻撃)
  • クラウドのメタデータエンドポイントは IMDSv2 を使う(AWSの場合、トークン必須)

まとめ表

略号名前一言で
A01Broken Access Control認可漏れ・IDOR
A02Cryptographic Failures暗号化サボり・平文
A03InjectionSQLi、コマンドi、XSSなど
A04Insecure Design設計レベルの欠陥
A05Security Misconfigurationデフォ設定・S3公開・デバッグON
A06Vulnerable Componentsライブラリの脆弱性
A07Authentication Failuresクレデンシャルスタッフィング・MFAなし
A08Integrity Failuresサプライチェーン・JWT署名スキップ
A09Logging and Monitoring Failures攻撃に気づけない
A10SSRFサーバー経由で内部に侵入

覚え方

1認可、2暗号、3注入、4設計、5設定、6依存、7認証、8整合、9監視、10SSRF」と数字とセットで唱える。面接でも頻出。


練習課題

# 自サービス(架空でOK、TaskNote と仮定)の Top 10 自己点検
touch ~/learn/security/day04_owasp/checklist.md

チェックリストのテンプレ

# TaskNote セキュリティ自己点検(OWASP Top 10 / 2021)
 
## A01 Broken Access Control
- [ ] 各APIで「リソース所有者かチェック」を実装している
- [ ] ユーザーIDはUUID
- [ ] 管理画面エンドポイントでロール検証
 
## A02 Cryptographic Failures
- [ ] HTTPS 必須化
- [ ] パスワード bcrypt
- [ ] 秘密鍵は環境変数、コミットしていない
 
## A03 Injection
- [ ] prepared statement のみ使用
- [ ] 入力検証(allowlist)
 
## A04 Insecure Design
- [ ] パスワードリセットがワンタイム・期限付き
- [ ] レート制限実装
 
## A05 Security Misconfiguration
- [ ] 本番でデバッグモードオフ
- [ ] セキュリティヘッダー設定
- [ ] S3バケットは private 確認
 
## A06 Vulnerable Components
- [ ] Dependabot 有効
- [ ] `npm audit` / `govulncheck` を CI で実行
 
## A07 Authentication Failures
- [ ] 流出パスワードチェック(HIBP API)
- [ ] 5回失敗で15分ロック
- [ ] MFA 提供
 
## A08 Integrity Failures
- [ ] package-lock.json / go.sum コミット
- [ ] CDN リソースに SRI
 
## A09 Logging and Monitoring
- [ ] ログイン成功/失敗をログ化
- [ ] 認可失敗アラート
- [ ] ログ集約先(CloudWatch等)あり
 
## A10 SSRF
- [ ] 外部URL指定機能がある場合、allowlist で制限
- [ ] 内部IP(169.254.169.254 等)アクセス禁止

締め: 振り返り(10分)

1. セッション録画を終了

exit

2. 今日の発見

- 自分が一番ピンと来た項目(一番怖い):
- 自分が一番盲点だった項目:
- 自社サービス(or 過去のプロジェクト)で当てはまっていた弱点:
- 次に深掘りしたい項目:

チェックリスト

  • A01〜A10 を見ずに3つ以上挙げられる
  • それぞれ「実例事件」を1つ挙げられる
  • 自サービスの自己点検チェックリストを書いた
  • 一番自分のチームに不足している項目を特定した

詰まった時のチートシート

略号一言メモ
A01「他人のIDで叩いたら見える」を絶対防ぐ
A02HTTPS + bcrypt + 秘密はリポ外
A03prepared statement、文字列連結禁止
A04設計の段階でSTRIDE、MFA、レート制限
A05設定が公開・デフォになっていないか
A06ライブラリの更新・脆弱性スキャン
A07パスワードハッシュ、MFA、レート制限
A08署名検証、lock ファイル、SRI
A09ログ取って監視して通知
A10外部URL取得は内部IPブロック

「実務OK」基準

  • OWASP Top 10 という言葉に動じない: 面接でも会議でも普通に出る
  • コードレビューで該当項目を指摘できる
  • 自分のプロジェクトの弱点を Top 10 にマッピングして説明できる
  • 「これは A01 だね」と項目番号で会話できる(業界共通言語)

メタ認知: 自分の理解度を診断する

30秒セルフテスト

  1. A01〜A10 のうち、ここ数年で 「常に1位」 は何で、その理由は?
  2. A03 (Injection) の代表3つを挙げよ
  3. A05 (Security Misconfiguration) の「最も典型的なやらかし」を1つ
  4. A06 (Vulnerable Components) で具体的に何をする習慣が必要?
  5. A10 (SSRF) はクラウド時代に重要性が増したのはなぜ?

5問中3問以上スラスラ言えるか がライン。詰まったらその項目を再読。

次のレッスン

1-5 SQL Injection でA03の代表選手SQLiに深掘り。次の 1-6 XSS で同じくA03のXSSを扱う。Top 10 の中でも開発者が日常的に遭遇する2大脆弱性を、コード例とともに体得する。

間隔反復ポイント

Top 10 の 項目名と番号 は業界共通言語。1ヶ月後にこの章の表だけ眺める を習慣化すれば、ミーティングで「これ A01 だね」と即座に出るようになる。