JavaScriptセキュリティの基礎知識

第2回 Webセキュリティのおさらい その2 XSS

この記事を読むのに必要な時間:およそ 4 分

文字のエスケープは開発言語やフレームワークの機能を用いて行う

エスケープが必要な文字は,通常は以下の5種類です。

文字エスケープした表現
&&
<&lt;
>&gt;
"&quot;
'&#x27;

これらの文字を正しくエスケープし,また属性値を引用符で囲んだ場合,先の例で生成されるHTMLはそれぞれ

語句「<span class="keyword">&lt;script&gt;alert(1)&lt;script&gt;</span>」を検索しました。20件の文書が見つかりました。

および

<input type="text" value="&quot;onmouseover=alert(1)//">

のようになり,攻撃者の指定した文字列がJavaScriptとして解釈されることはありません。

文字列をエスケープするには,たとえばPHPであればhtmlspecialcharsを用いて,以下のようにします。

htmlspecialchars( $str, ENT_QUOTES, "UTF-8" );

ただし一般的には,文字列のエスケープにはWebアプリケーションを開発する言語やフレームワークで用意されている機能を用いたり,パラメータがすべて自動でエスケープされるテンプレートエンジンを使用するのがいいでしょう。文字列を出力するすべての箇所で確実にエスケープを行うというのは,Webアプリケーション内で1か所でも漏れがあった場合にはXSSの発生へとつながってしまうためです。

リンクを生成する際には,URLをhttpあるいはhttpsスキームのみに限定する

テキストノードおよび属性値のエスケープ漏れ,引用符の漏れ以外にも,XSSの原因としては「リンクのURLとしてjavascriptスキームを許容している」という場合があります。たとえば,以下のようなHTMLを生成するWebアプリケーションがあったとします。

<a href="ここに攻撃者は自由に文字列を設定できる">外部へのリンク</a>

ここで,攻撃者がjavascript:alert(1)のようなURLを与えた場合,生成されるHTMLは

<a href="javascript:alert(1)">外部へのリンク</a>

となり,このリンクをユーザーがクリックしてしまうと,攻撃者の作成したJavaScriptコードがユーザーのブラウザで動作することになります。

このため,文字列をURLとみなしてリンクを生成する際には,URLはhttpあるいはhttpsスキームのみに限定する,すなわちその文字列が「http://」あるいは「https://」から始まっていることを確認するといった対策が必要となります。

Cookieには必ずhttponly属性をつける

仮にXSSが発生した場合であっても可能な限り被害を軽減させるために,Cookieには必ずhttponly属性をつけるようにしましょう。

Set-Cookie: sessionid=25283FB24C9DEE32; httponly

httponlyがつけられたCookieは,JavaScriptからdocument.cookieを使って参照することができないので,仮にXSSが存在したとしても,Cookie内のセッション情報の漏洩といった被害を抑えることができます。

反射型XSSと蓄積型XSS

ここまで説明してきたような従来から存在する一般的なXSSは,大きく分けて「反射型XSS」と呼ばれるものと「蓄積型XSS」と呼ばれるものに分けて考えられます。

反射型XSS

反射型XSSとは,罠ページの訪問や罠リンクのクリックにより,攻撃者の用意したJavaScriptコードやHTML断片がユーザーからのHTTPリクエストに含まれてサーバへ送信され,サーバからのレスポンスにそのJavaScriptコードやHTML断片が含まれて発生するタイプのXSSです。反射型XSSの典型的な例には,以下のものがあります。

  • サイト内の検索ページでのXSS
  • 問い合わせフォームに入力した値の確認ページでのXSS

反射型XSSでは,ユーザーのブラウザからのリクエストと,それに対応するサーバからのレスポンスのどちらにも,攻撃者の準備したJavaScriptコードやHTML断片が含まれています。

最近の多くのブラウザでは,リクエストとレスポンスの双方に同じJavaScriptコードやHTML断片が含まれていないかを監視し,もし同一の文字列が含まれている場合には※2)⁠反射型XSSが発生したとしてそれらのJavaScript等の実行を遮断することで,XSSの被害を軽減するための機構が含まれています。これらの機構は,IEではXSSフィルター,ChromeやOpera,SafariではXSS Auditorと呼ばれています。

※2)
正確には,リクエストとレスポンスで異なるエスケープなどがされている場合もあるので,⁠同一の意味を持つ文字列が含まれている場合」となります。

蓄積型XSS

一方,蓄積型XSSとは,攻撃者の用意したJavaScriptコードやHTML断片が対象となるWebサーバ上にいったん格納され,ユーザーがそのページを開いた際にそのJavaScriptコードやHTML断片が含まれて発生するタイプのXSSです。蓄積型XSSの典型的な例としては,Webメールや掲示板でのXSSなどがあります。

蓄積型のXSSでは,攻撃者がサーバへJavaScriptコードなどを送信して攻撃を仕掛けるタイミングと,ユーザーがそのページを開いてXSSの被害が発生するタイミングとに時間差があっても攻撃が成立し,サーバ上にそのページが存在する限り永続的にXSSが発生することにもなり,一般的に反射型XSSに比べると被害が大きくなります。

反射型XSSと蓄積型XSS以外にJavaScriptが引き起こすXSSとして,DOM-based XSSと呼ばれるものもあります。これについては本連載の主要なテーマであるため,回を改めてより詳細に解説します。

次回は,Webアプリケーションにおける代表的な受動的攻撃の解説の続きとして,CSRF,オープンリダイレクト,クリックジャッキングを取り上げます。本来のテーマであるJavaScriptのセキュリティまでなかなかたどり着きませんが,もう少しだけおつきあいいただければと思います。

著者プロフィール

はせがわようすけ

株式会社セキュアスカイ・テクノロジー常勤技術顧問。 Internet Explorer,Mozilla FirefoxをはじめWebアプリケーションに関する多数の脆弱性を発見。 Black Hat Japan 2008,韓国POC 2008,2010,OWASP AppSec APAC 2014他講演多数。 OWASP Kansai Chapter Leader / OWASP Japan Board member。

URL:http://utf-8.jp/