2012年4月16日月曜日

情報処理試験問題に学ぶJavaScriptのXSS対策

平成24年度春期の情報処理技術者試験の問題と解答(一部)が公開されていますね。情報セキュリティスペシャリスト試験(SC)の午後Ⅰ(全4問中2問を選択)では、問1と問2がWebアプリケーションに関する問題でした。このエントリでは問1について書きます。

問1は、インターネット通販A社のサイトで脆弱性検査を実施したところ、指摘事項2点が報告されたところから始まります。

指摘事項A:画面の遷移の中で、暗号化通信と非暗号化通信が混在しているが、暗号化通信でだけ使用されるべきクッキーに、(   a   )属性が設定されていないページが存在する。
指摘事項B:任意のスクリプトが実行可能であるページが存在する。

指摘事項A中の(a)は、他を見なくても「セキュア」属性だと分かりますね。徳丸本(体系的に学ぶ 安全なWebアプリケーションの作り方)では、4.8.2クッキーのセキュア属性不備(P209)に説明があります。

指摘事項Bは、ここだけ読むと、XSSのようでもあり、サーバーサイドのスクリプトインジェクションのようでもありますが、検査ログからXSSであることがわかります(下図はIPAからの引用)。XSSは、徳丸本4.3.1クロスサイトスクリプティング(基本編)と4.3.2クロスサイトスクリプティング(発展編)にて説明しています。


ここまでは、ごく基本的な問題ですが、問題文P6に出てくる以下の部分は、少しだけひねってますね。
このプログラムは、利用者が入力した文字列をダイアログに表示するために、受け取ったパラメタの値をスクリプトに埋め込み、動的にスクリプトを生成する。図4の(   c    )行目では、通常のHTMLにパラメタの値を埋め込むときと同じ方法でエスケープ処理を行っていたことから、生成されるスクリプトに問題が生じてしまうことが分かった。
JavaScriptの文字列リテラルにパラメータを埋め込んでいる箇所を探すと、37行目であることが分かります。
37:  out.println("<a name=\"#\" onclick= \"alert('" + escape(word) + "')\">");
これは、徳丸本では、◆イベントハンドラのXSS(P109)に説明がある内容です。
イベントハンドラのJavaScript文字列リテラルの中味を動的生成する場合は、徳丸本P110に説明するように、二段階でエスケープしなければなりません。

①まず、データをJavaScript文字列リテラルとしてエスケープする
②この結果HTMLエスケープする

情報処理試験の問題文もそうなっていますが、問題はエスケープする文字です。徳丸本では、最低限エスケープが必要な文字として以下の4種を挙げています。


これに対して、情報処理試験の問題文では、エスケープすべき文字を2種類に限定しています。従って、上記4文字から2文字を除外する必要があります。
まず除外できるのがダブルクォート「"」です。JavaScriptの文字列リテラルは、シングルクォートでもダブルクォートでも囲むことができるので、両方の場合に対応する前提では、両方の引用符をエスケープする必要があります。しかし、この問題では、シングルクォートで文字列を囲っていることが分かっているので、ダブルクォートの方は、エスケープ対象から除外することができます。
残り3文字のうち、シングルクォート「'」とバックスラッシュ「\」はエスケープしないとXSS脆弱性となるので、この2文字が解答でしょうね。

なお、バックスラッシュのエスケープを怠ると、以下の文字列で攻撃が可能です。
\');alert("XSS");//
この場合、シングルクォートのみがエスケープされると、生成されるJavaScriptは下記となります。
alert('\\');alert("XSS");//')
攻撃文字列先頭の「\」と、シングルクォートのエスケープの「\」があわせて「\」一文字と解釈され、後続のシングルクォートがエスケープされない状態で余ります。このため、文字列リテラルが終端され、その後ろはJavaScriptのコマンドとして解釈されます。すなわち、スクリプトのインジェクションができたことになります。

一方、改行については、エスケープしなくても上記のような攻撃には至りませんが、JavaScriptのエラーにはなります。また、JavaScriptの文字列リテラルの引用符をシングルクォートで統一しているプロジェクトはマレだと思われるので、徳丸本の基準に従うのが実務上はよいと思います。あくまで、テストとして、エスケープの原理を理解していることを問う問題と考えるべきでしょう。

twitter等でたまに「情報処理試験対策のために徳丸本読んでる」等のツイートを見かけることがありますが、私は「試験対策になるのだろうか」と思っておりました。この問題を見る限り、情報セキュリティスペシャリスト試験(SC)の対策になる場合もありそうですね。但し、今回引用していませんが、実際に攻撃があったかどうかをログから判定する問題など、徳丸本の知識だけでは解答出来ないものも当然あります。

追記(2012/04/30)

水無月ばけらさんから指摘がありました。「平成24年度春期情報セキュリティスペシャリスト試験のXSS問題
  • 「このコードに限定した話」という仮定を置かない場合、escape2は単引用符、バックスラッシュ、改行に加え、二重引用符などもエスケープする必要があるかもしれない。
  • 「このコードに限定した話」と仮定し、かつ「不具合なく動作する」ことを想定した場合、escape2は単引用符、バックスラッシュ、改行をエスケープする必要がある。
  • 「このコードに限定した話」かつ「攻撃さえ防げれば良く、不具合があっても良い」と想定した場合、escape2は少なくとも単引用符をエスケープする必要がある。
    • 単引用符を「\'」にエスケープすれば、バックスラッシュのエスケープも必須になる
    • 単引用符を「\u0027」にエスケープすれば、バックスラッシュのエスケープは必要ないかもしれない (見落としがある? 突破できる?)
たしかにそうですね。
ということは、上記に指摘した解以外に、複数の解が正答になってしまうということで、問題としてはよろしくない、ということになります。この問題については全員を正解とするか、理論的に正答と見なせる解(何種類かありそうですが)を全て正答にする、という対処が必要になりそうです。IPAとしてはどうするのでしょうか。

追記(2012/06/08)

IPAから正答が公開されました。これを読むと、設問3(2)はやはりシングルクォートとバックスラッシュのエスケープを想定正解としていますね。\u0027にエスケープするとした人はいなかったのでしょうか。

[PR]
WAF始めました。詳しくはHASHコンサルティング株式会社まで。
安全なWebアプリケーションの作り方DRMフリーのPDFによる電子版もあります。

0 件のコメント:

コメントを投稿

フォロワー

ブログ アーカイブ