正解:エ
各選択肢の解説
ア登録時のチェックを強め、「<」や「>」を含む投稿はすべて受け付けないようにする。
誤り。入力値の内容チェックは、IPAの区分では保険的対策です。入口で弾けば 済むように見えますが、文字種を広く許す仕様では効果が限られ、チェックを 通らない経路で登録された値も表示されます。入口か出口かで区別します。
イセッション用のCookieにHttpOnly属性を付け、スクリプトから読めないようにする。
誤り。これも保険的対策です。スクリプトが動いたときにCookieを盗まれる 被害を減らす手当てで、スクリプトが実行されること自体は止まりません。 偽の画面を出すなど、Cookie以外の被害は残ります。
ウ投稿をデータベースへ登録する前に、SQLで意味を持つ特殊文字をエスケープする。
誤り。これはSQLインジェクションへの対策です。同じ「エスケープ」でも、 対象がデータベースに渡すSQL文なので、ブラウザがHTMLとして解釈する 記号は無害になりません。何に渡す文字列かで対策の場所が変わります。
エデータベースから読み出した値も含め、画面に出力する値を出力時にエスケープする。
正解。IPAは、データベースやファイルから読み込んだ文字列も含め、ウェブ ページに出力するすべての要素にエスケープを施すことを根本的解決としています。 スクリプトが動く場所は出力先なので、出力の直前で無害化します。
理解を深めるために
「入口で調べた」は「出口で安全」にならない
クロスサイトスクリプティング(XSS)は、Webページに埋め込まれたスクリプトが、 そのページを見た利用者のブラウザで動いてしまう脆弱性です。スクリプトが動くのは ページを表示する瞬間なので、対策もそこで打ちます。 郵便物にたとえると、受付で中身を確かめても、配達の途中で別の荷物が混ざれば 意味がありません。届ける直前に確かめるのが確実です。
なぜ出力時のエスケープが根本的解決なのか
IPAの「安全なウェブサイトの作り方」は、XSSの根本的解決の1つ目に 「ウェブページに出力する全ての要素に対して、エスケープ処理を施す」を挙げています。
<>&などをHTMLの文字参照に置き換えると、ブラウザはタグではなく ただの文字として表示する- エスケープが必須の対象には、利用者からの入力値だけでなく、 データベースやファイルから読み込んだ文字列も含まれる
- データベースの中身は、別の画面・一括取込み・過去の不具合など、 登録時のチェックを通らない経路でも入りうる
設問の説明は「データベースの値は安全」という前提に立っており、 ここが崩れると表示した時点でスクリプトが動きます。
混同しやすいものとの違い
| 対策 | 区分 | 何に効くか |
|---|---|---|
| 出力時のエスケープ | 根本的解決 | 表示の瞬間に、スクリプトとして解釈される原因をなくす |
| 入力値の内容チェック | 保険的対策 | 入口で一部を弾く。仕様次第で効果が限られる |
| HttpOnly属性 | 保険的対策 | Cookieの窃取を防ぐ。スクリプトの実行は止まらない |
| SQL用の特殊文字のエスケープ | 別の脆弱性の対策 | SQLインジェクションを防ぐ。HTMLとしては無害にならない |
「エスケープ」という言葉が出てきたら、何に渡す文字列を無害化するのかを確かめます。 XSSならブラウザに渡すHTML、SQLインジェクションならデータベースに渡すSQL文です。