問題 10★★★

会員がプロフィールに登録したURLを、他の会員向けにリンクとして表示する機能がある。 出力時のエスケープは実施済みだが、「javascript:」で始まる文字列を登録すると クリックした会員の画面でスクリプトが動くと分かった。IPA「安全なウェブサイトの 作り方」に沿って追加で求める対策はどれか。

正解:ウ

各選択肢の解説

  1. ア「javascript:」という文字列を含むURLを見つけたら、登録を拒否する。

    誤り。危ない書き方を列挙して弾く方式は、大文字を混ぜる、途中に空白や 制御文字を挟むといった変形ですり抜けられることがあります。IPAが求める のは、許可する形を決めてそれ以外を通さない方式です。禁止する側から 決めるのか、許可する側から決めるのかで区別します。

  2. イ登録されたURLの先にあるページを定期的に巡回し、不審な内容があれば削除する。

    誤り。これはリンク先のサイトが危険かどうかの監視で、自社のページに スクリプトを埋め込まれる問題とは別です。「javascript:」のリンクは どこのページにも行かずに、クリックした場で動きます。

  3. ウ「http://」か「https://」で始まるURLだけを許可し、それ以外は出力しない。

    正解。IPAは、URLを出力するときは「http://」や「https://」で始まるものだけを 許可する方式を根本的解決に挙げています。「javascript:」のように、 リンクとして書くだけでスクリプトになる文字列を締め出せます。

  4. エセッション用の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かで、 必要な対策が変わります。

前の問題へ次の問題へ