公開日:2007年6月28日
独立行政法人情報処理推進機構
セキュリティセンター
本ページの情報は2007年6月時点のものです。
記載の資料は資料公開当時のもので、現在は公開されていないものも含みます。
HTMLドキュメント内には、スクリプトを記述し実行できる箇所(コンテキスト)が数多く存在する。例えば次のような箇所である(図7-3)。
攻撃者は、スクリプトが実行されるこれらの箇所にJavaScriptプログラムの文字列をあてはめるか、何も無いところにこのような構文が作り出されるようデータを工夫して送り込んでくる。
攻撃者がWebアプリケーションプログラムにエコーバックさせるべく投入してくる攻撃文字列には多くのバリエーションがありえる。主なものを挙げると、次のようなものがある。
テキスト部分に直接タグを挿入する
攻撃文字列の例: <script>document.cookie='jsessionid=BAD'</script>
引用符と>を用いタグ属性値から脱出して<script>タグを挿入する
攻撃文字列の例: '"><script>document.cookie='jsessionid=BAD'</script>
javascript:等スクリプトを起動するスキームを用いた文字列をタグのURL属性の値として与える
攻撃文字列の例: javascript:document.cookie='jsessionid=BAD'
expression()を用いてスタイル中にスクリプトを記述する
攻撃文字列の例: red;z:expression(document.cookie='jsessionid=BAD')
タグのイベントハンドラ属性内の文字列定数'xxx'から脱出してスクリプトを記述する
攻撃文字列の例: ';document.cookie='jsessionid=BAD
<script>...</script>の内側の文字列定数'xxx'から脱出してスクリプトを記述する
攻撃文字列の例: ';document.cookie='jsessionid=BAD (コンテキスト5と同一)
スクリプト注入は、攻撃者が送り込んでくる文字列がHTMLドキュメントの一部となるように合成されて、その部分がブラウザによってスクリプトとして解釈される構文となることによって成立する。スクリプト注入対策は、これを阻止することである。
プログラム中のデータをHTMLドキュメントに出力する際には、攻撃文字列が混入しているおそれがあるので、タやと属性値を表現する次の記号(特殊文字)についてHTMLエンティティを表現する記法に置換する。
データの中の文字
|
HTMLに出力する文字列
|
<
|
<
|
>
|
>
|
"
|
"
|
'
|
'
|
&
|
&
|
この対策は、コンテキスト1とコンテキスト2に有効である。
次のような箇所については、この対策は効果をもたない。
次の箇所にはプログラムから動的に値を書き出さない。
ただし、アプリケーションによっては何らかの識別子を<script>...</script>の内側等に文字列定数 'xxx' の形で埋め込む必要に迫られることもあり得る。そのような場合は以下の要注意箇所への出力を行う必要に迫られている場合の対策を実施する。
URLを値として持ち得るタグ属性値、style属性値、イベントハンドラ属性値においては、<script>等のタグを書かなくてもスクリプトを記述し動作させることができる。タグ属性値の中で用いられたエンティティ表現('等)は、それが表す特殊記号そのものとして扱われる。すなわち、置換を行ってもJavaScriptプログラムの意味を失わせることにならず、スクリプト実行を阻害できない。
そのような場合は、値を書き出す箇所への文字列埋め込みを慎重に行う。具体的には、次のような対策を行う。
URLを値としてもち得るタグ属性値にプログラムから動的に値を与える場合、その属性値の先頭が必ず下記のいずれかのスキームで始まるように限定する。
下記の箇所にプログラムから動的に値を与える場合
埋め込む値中に下記のような、タグ、style および JavaScriptの構文として意味をもつ特殊記号が含まれないようにする。
Webアプリケーションの入出力データとしてタグを含むHTML文字列を扱わない。
ただし、掲示板、ブログ、ショッピングカタログ構築キット等、HTMLタグを含む文字列データの取り扱いが不可避のアプリケーションもありえる。その場合は以下の入出力データとしてタグを含むHTMLデータを扱う必要にせまられている場合の対策を実施する。
そのような場合は、HTMLデータからのスクリプトを排除する。 具体的には、次のような対策を行う。
タグを含むHTMLドキュメントまたはその一部をアプリケーションの入出力データとして取り扱う場合、入力されたHTMLドキュメントを構文解析し、スクリプトを含んでいる場合データとして受け付けないか、スクリプトを削除してから使用する。
WebアプリケーションがHTMLドキュメントを内容とするHTTPレスポンスを送出する際には、必ず使用文字セットを明示するようにする。
何らかのエンコード形式を用いることにより、入力検査や特殊記号の置換措置を迂回できてしまうおそれがある。例えば、 UTF-7 では、記号 < は +ADwA- のように表記できる。Webアプリケーションが、文字セットの種類を(Content-Typeのcharsetで)明示しないままブラウザにHTMLドキュメントを送信している場合、ブラウザによっては UTF-7 エンコード形式と見なせる文字列を自動判別してデコードし、別の文字として解釈するおそれがある。
スクリプト注入されうる脆弱性をWebアプリケーションから根絶することは必ずしも容易ではない。なぜならば、掲示板等のアプリケーションプログラムには入力データをエコーバックする場面は多く存在しており、対策漏れが起こりうるからである。
プログラムがHTMLドキュメント内に値を出力するあらゆる場面に注意を払う必要がある。
可能であれば、特定の特殊記号がエンティティ表現に自動で変換される出力APIを用意して、それ以外の出力APIを使わない等のコーディングルールを設けて、コーディイングするように促すのがよい。