6-2. 演習問題
問題1:選択問題
Section titled “問題1:選択問題”1-1. OWASP Top 10 の主な役割として最も適切なのはどれか。
- A. 重要な Web アプリケーションリスクを整理し、開発者の注意点を共有すること
- B. Git のブランチ名を統一すること
- C. データベースの正規化だけを評価すること
解答と解説
正解:A. 重要な Web アプリケーションリスクを整理し、開発者の注意点を共有すること
- A が正しい。OWASP Top 10 は、重要なセキュリティリスクを整理した代表的な啓発資料である。
- B は誤り。ブランチ運用のルールではない。
- C は誤り。データベース設計専用の資料ではない。
OWASP Top 10 の価値は、設計・実装・レビュー・テストの各場面で「何を疑うべきか」を共有できる点にある。
1-2. 現行の OWASP Top 10:2025 で SQL Injection と XSS が主に含まれるカテゴリとして最も適切なのはどれか。
- A.
A05: Injection - B.
A02: Security Misconfiguration - C.
A09: Security Logging & Alerting Failures
解答と解説
正解:A. A05: Injection
- A が正しい。現行の 2025 版では、SQLi と XSS は主に
Injectionのカテゴリで捉えられる。 - B は誤り。設定不備の話ではない。
- C は誤り。ログや通知の不備とも別問題である。
SQLi と XSS は見た目は違うが、どちらも「入力が構文や命令として解釈される」という共通点を持つ。
1-3. 現行の OWASP Top 10:2025 における CSRF の扱いとして最も適切なのはどれか。
- A. 現在も単独の Top 10 項目である
- B.
Broken Access Controlに含まれる関連リスクとして扱われる - C. もう対策不要なので一覧から外れた
解答と解説
正解:B. Broken Access Control に含まれる関連リスクとして扱われる
- B が正しい。現行の 2025 版では、CSRF は単独項目ではなく
Broken Access Controlの文脈で扱われる。 - A は誤り。古い資料の印象をそのまま引きずっている。
- C は誤り。単独項目でないことと、重要でないことは別である。
現在の OWASP Top 10 は、攻撃名そのものよりも、より根本原因に近いカテゴリで整理する傾向が強い。
1-4. SQL Injection への対策として最も適切なのはどれか。
- A. パラメータ化クエリを使い、データとクエリ構造を分離する
- B. 入力を文字列連結したあとで見た目だけ確認する
- C. クライアント側の入力チェックだけに任せる
解答と解説
正解:A. パラメータ化クエリを使い、データとクエリ構造を分離する
- A が正しい。SQLi の本質的な対策は、データと SQL 構造を分けることにある。
- B は誤り。見た目を確認しても、危険な結合方法そのものは残る。
- C は誤り。クライアント側の検証は攻撃者に回避されうる。
「入力をどう制限するか」より前に、「危険な結合方法をしない」ことが重要である。
1-5. XSS を防ぐ表示方法として最も適切なのはどれか。
- A. 信頼できない入力をそのまま
innerHTMLへ入れる - B. 出力エンコーディングや
textContentのような安全な API を使う - C. ログイン済みユーザーの入力なら無条件で表示する
解答と解説
正解:B. 出力エンコーディングや textContent のような安全な API を使う
- B が正しい。XSS の対策では、出力文脈に応じて無害化し、安全な API を使うことが重要である。
- A は誤り。
innerHTMLへ無警戒に渡すと、HTML として解釈される危険がある。 - C は誤り。ログイン済みユーザー入力でも危険な内容は入りうる。
入力元を過信するのではなく、出力時の扱いを安全にする発想が必要である。
1-6. Broken Access Control の例として最も適切なのはどれか。
- A. URL の
bookIdを変えたら他人の本の編集画面が開けた - B. 画像が少しぼやけて表示された
- C. ダークモードの設定が保存されなかった
解答と解説
正解:A. URL の bookId を変えたら他人の本の編集画面が開けた
- A が正しい。これは権限外の閲覧や操作を許しており、Broken Access Control の典型例である。
- B は誤り。表示品質の問題であり、セキュリティカテゴリではない。
- C は誤り。設定保存の不具合であり、直接の権限制御問題ではない。
「自分が見てよいものだけ見える」「自分がしてよい操作だけできる」が守られているかが access control の要点である。
問題2:穴埋め問題
Section titled “問題2:穴埋め問題”次の文章の空欄を埋めてください。
- OWASP Top 10 で、SQLi や XSS が主に含まれるカテゴリを ( ) という。
- 権限外の操作や閲覧を許してしまうカテゴリを ( ) という。
- SQL の構造とデータを分ける代表的な対策を ( ) クエリという。
- XSS 対策として、表示文脈に応じて文字を無害化する考え方を ( ) という。
- CSRF への代表的な対策の 1 つは、状態変更リクエストに ( ) を付けて正当性を確認する方法である。
- OWASP Top 10 は、10 個だけ覚えれば終わりの完全な ( ) ではない。
解答と解説
-
Injection
SQLi や XSS など、入力が構文や命令として解釈される問題群をまとめるカテゴリである。
-
Broken Access Control
権限外の閲覧や更新、管理機能への侵入などを許してしまう問題群である。
-
パラメータ化
SQL の構造と値を分離し、入力がクエリの一部として解釈されにくくする基本対策である。
-
出力エンコーディング
表示先に応じて危険な文字を無害化し、ブラウザに命令として解釈させにくくする考え方である。
-
トークン
フォームやリクエストごとにトークンを埋め込み、状態変更リクエストが本当に正当な画面から送られたものかを確かめる代表的な仕組みである。
-
チェックリスト
OWASP Top 10 は参考になるが、10 項目だけ見れば終わり、という完全な表ではない。
問題3:記述問題
Section titled “問題3:記述問題”3-1. なぜ OWASP Top 10 を「攻撃名の暗記表」としてではなく、「根本原因を考える資料」として使うべきなのか説明してください。
解答と解説
個別の攻撃名だけを暗記しても、なぜ起きるのかや、どう再発防止するかが見えにくいからである。 たとえば「外部入力をそのまま混ぜる」という同じ根本原因が、SQLi や XSS など複数の問題を生む。 そのため、OWASP Top 10 は「どんな名前の攻撃があるか」より、「どんな設計や実装が危険か」を考えるために使うべきである。
3-2. SQL Injection と XSS の共通点と違いを説明してください。
解答と解説
共通点は、どちらも信頼できない入力が、解釈器に命令や構文として扱われることにある。 SQLi ではデータベースが SQL を解釈し、XSS ではブラウザが HTML / JavaScript を解釈する。 つまり本質は同じ Injection だが、攻撃される対象の解釈器と影響の出方が違う。
3-3. CSRF が、ログイン済みのブラウザを使う Web アプリで起こりやすい理由を説明してください。
解答と解説
ブラウザは正規サイトへログインしていると、Cookie などの認証情報を自動で送ることがある。 その状態で悪意あるページから状態変更リクエストを誘発されると、サーバーは本人の正当な操作と誤認しやすい。 そのため、ログイン済みであること自体が CSRF 悪用の前提になりうる。
3-4. なぜログやアラート、例外時の安全な停止もセキュリティの一部なのか説明してください。
解答と解説
攻撃や異常は、起きること自体をゼロにできない場合があるため、発見と影響抑制の仕組みが必要になる。 ログやアラートが弱いと侵害に気づけず、異常時の処理が危険だと情報漏えいや権限逸脱が起こりやすい。 そのため、セキュリティは「侵入を防ぐ」だけでなく、「異常時に安全側へ倒れ、気づけるようにする」ことまで含む。
問題4:ハンズオン
Section titled “問題4:ハンズオン”安全側のTODOを実装し、危険な実装との出力の違いを確認せよ。SQLite のプレイグラウンドでも同様に攻撃文字列の影響を観察する。
取り組む内容
Section titled “取り組む内容”buildSafeSearchQueryでSQL文と値を分離した{ sql, params }オブジェクトを返すverifyCsrfでoriginとsessionToken === requestTokenの両方を確認してtrue/falseを返す- 実装後に実行し、
unsafe(危険)とsafe(安全)の出力の違いを確認する
確認したいポイント
Section titled “確認したいポイント”unsafe queryでは攻撃文字列がSQL本文に混入し、safe queryでは値として分離されることunsafe htmlにはタグが残り、safe htmlではエンコードされることcsrf accepted (evil origin)はfalse、csrf accepted (valid)はtrueになること
⑥ SQLite で危険な検索結果を確認する
次は SQLite 上で、同じ攻撃文字列が「SQL の一部になった場合」と「値として扱われた場合」で結果がどう変わるかを見ます。 まずは危険な文字列連結で出来上がった SQL を実行する。
次の SQL が実行できれば成功:
SELECT id, titleFROM booksWHERE title = '' OR '1'='1'ORDER BY id;結果は次のようになれば成功:
+----+------------------+| id | title |+----+------------------+| 1 | Git || 2 | JavaScript入門 || 3 | Network設計 |+----+------------------+攻撃文字列により、WHERE 条件が常に真になり、全件が返ってしまうことを確認する。
⑦ SQLite で対策クエリの結果を確認する
次は、同じ攻撃文字列 ' OR '1'='1 を、プレースホルダ ? に値として渡す対策クエリを実行する。
この下のプレイグラウンドでは、? へ固定でその文字列が渡される。
次の SQL が実行できれば成功:
SELECT id, titleFROM booksWHERE title = ?ORDER BY id;結果欄に 0 行でした。 と表示されれば成功:
- 同じ攻撃文字列でも、SQL の構造ではなく「本のタイトルの値」として扱われる
- その文字列と一致するタイトルは存在しないため、全件取得にはならない
⑧ プレースホルダへ渡った値そのものも確認する
対策クエリ側の SQL を次のように書き換えて、もう一度実行する。
SELECT ? AS attack_input;結果は次のようになれば成功:
+----------------+| attack_input |+----------------+| ' OR '1'='1 |+----------------+つまり、対策クエリでは攻撃文字列が「命令」ではなく、1つの値として扱われていると分かる。
実務では、この考え方を手書きエスケープではなく、プレースホルダ付きのパラメータ化クエリで実現する。
解答と解説
② そのまま実行したときの見方
unsafe query SELECT * FROM books WHERE title = '' OR '1'='1'safe query {"sql":"SELECT * FROM books WHERE title = ?","params":["' OR '1'='1"]}unsafe html <p><img src=x onerror="alert(1)"></p>safe html <p><img src=x onerror="alert(1)"></p>csrf request accepted falseunsafe query では、攻撃文字列が SQL 本文へ直接入り込んでいる。
一方 safe query では、SQL の構造は固定で、値が別の params として扱われている。
unsafe html はタグをそのまま含むが、safe html は < や " がエスケープされ、文字列として表示される前提になっている。
csrf request accepted false は、送信元やトークンが正しくなければ状態変更を受け付けない、という考え方を表している。
③ 普通の検索語に変えたとき
unsafe query SELECT * FROM books WHERE title = 'JavaScript入門'safe query {"sql":"SELECT * FROM books WHERE title = ?","params":["JavaScript入門"]}普通の値に見えても、危険なのは「攻撃文字列かどうか」だけではなく、「文字列連結で構造へ混ぜる書き方」である。 つまり脆弱性は入力値だけでなく、実装パターンにある。
④ コメント表示を変えたとき
unsafe html <p>Hello <b>team</b></p>safe html <p>Hello <b>team</b></p>unsafe html は <b> をタグとして扱える形のまま残している。
safe html はタグを文字列へ変えているため、ブラウザが構文として解釈しにくい。
XSS 対策では、危険な入力を「見えないようにする」のではなく、「構文として扱わせない」ことが重要である。
⑤ CSRF 検証を通したとき
csrf request accepted trueこの結果は、送信元とトークンの両方が正当であるときだけリクエストを通す、という考え方を示している。
実際のフレームワークでは、CSRF トークン、SameSite Cookie、Origin / Referer 確認などを組み合わせることが多い。
重要なのは「ログイン済みだから許可」ではなく、「その操作が正当な画面から来たものか」を追加確認することである。
⑥-⑧ SQLite で SQL Injection の結果差を確認したとき
危険な連結結果では、次の SQL がそのまま実行される。
SELECT id, titleFROM booksWHERE title = '' OR '1'='1'ORDER BY id;この WHERE 条件は実質的に常に真になるため、全件が返ってしまう。
つまり攻撃文字列が「タイトルの値」ではなく、SQL の条件そのものへ入り込んでいる。
一方、対策クエリでは次の SQL を使う。
SELECT id, titleFROM booksWHERE title = ?ORDER BY id;ここで ? へ渡されるのは ' OR '1'='1 という 1 つの文字列値である。
そのため SQLite は、それを条件式として実行するのではなく、「そのタイトルと等しい行を探す」だけになる。
一致するタイトルがなければ 0 行でした。 となり、全件取得にはならない。
さらに SELECT ? AS attack_input; を実行すると、攻撃文字列がそのまま 1 つの値として返る。
これが、危険な連結とパラメータ化クエリの決定的な違いである。
図で見る
SQLi: 入力が SQL の一部になるXSS : 入力が HTML / JS の一部になるCSRF: ログイン済みブラウザが意図せずリクエストを送る3つとも有名な名前だが、見るべき点は「どこで境界が崩れたか」である。