正解:ウ
各選択肢の解説
ア「javascript:」という文字列を含むURLを見つけたら、登録を拒否する。
誤り。危ない書き方を列挙して弾く方式は、大文字を混ぜる、途中に空白や 制御文字を挟むといった変形ですり抜けられることがあります。IPAが求める のは、許可する形を決めてそれ以外を通さない方式です。禁止する側から 決めるのか、許可する側から決めるのかで区別します。
イ登録されたURLの先にあるページを定期的に巡回し、不審な内容があれば削除する。
誤り。これはリンク先のサイトが危険かどうかの監視で、自社のページに スクリプトを埋め込まれる問題とは別です。「javascript:」のリンクは どこのページにも行かずに、クリックした場で動きます。
ウ「http://」か「https://」で始まるURLだけを許可し、それ以外は出力しない。
正解。IPAは、URLを出力するときは「http://」や「https://」で始まるものだけを 許可する方式を根本的解決に挙げています。「javascript:」のように、 リンクとして書くだけでスクリプトになる文字列を締め出せます。
エセッション用のCookieにHttpOnly属性を付け、スクリプトから読めないようにする。
誤り。IPAの区分では保険的対策です。スクリプトが動いたときにCookieを 盗まれる被害は減りますが、リンクに仕込まれたスクリプトが実行される こと自体は止まりません。原因を断つ対策ではありません。
理解を深めるために
リンク先は「どこへ行くか」だけでなく「何が起きるか」
リンクのURLは、ふつうは移動先の住所です。ところが「javascript:」で始まる 文字列をリンク先に書くと、クリックした瞬間にその場でスクリプトが動きます。 住所の欄に、住所ではなく「この場で鍵を開けよ」という命令を書けてしまうような ものです。利用者にURLを登録させる機能では、この穴をふさぐ必要があります。
なぜエスケープだけでは足りないのか
IPAの「安全なウェブサイトの作り方」は、クロスサイト・スクリプティングの 根本的解決として、出力時のエスケープに加えて、URLの出力の制限を挙げています。
- エスケープは
<>&"などの記号を文字参照に置き換え、タグや属性の 区切りとして解釈されないようにする - 「javascript:alert(1)」のような文字列には置き換える記号がほとんど無く、 エスケープしても形が変わらない
- そこでIPAは、「http://」や「https://」で始まるURLだけを許可する ホワイトリスト方式で実装するよう求めている
危ないものを列挙して弾く方式は、書き方の変形ですり抜けられます。 許可する形を決めて、それ以外を通さないほうが漏れがありません。
混同しやすいものとの違い
| 対策 | 区分 | この機能での効き方 |
|---|---|---|
| URLを http:// https:// に限る | 根本的解決 | javascript: のリンクを出力させない |
| 「javascript:」を含むURLの拒否 | 禁止する形の列挙 | 大文字や空白を混ぜた変形ですり抜けられる |
| HttpOnly属性 | 保険的対策 | Cookieの窃取だけを防ぐ |
| リンク先の巡回監視 | 該当しない | 外部サイトの危険度を見るだけ |
設問の状況のように、出力時のエスケープを済ませていても残る穴があります。 根本的解決は1つとは限らず、出力する場所がHTMLの本文か、リンク先のURLかで、 必要な対策が変わります。