この文書は2016年以降更新されていません

クロスサイトスクリプティング (XSS) 対策チートシート

OWASP 作成
ジャンプ先: 移動検索
Cheatsheets-header.jpg

最終改訂日 (yy/mm/dd):2015/12/01

はじめに

この資料では、適切に出力のエスケープ / エンコードを使用した XSS 対策について、シンプルかつポジティブなモデルを紹介します。極めて多くの XSS 攻撃ベクトルがありますが、いくつかのシンプルなルールに従うことで、この重大な攻撃を完全に防ぐことができます。この資料では、XSS の技術的な影響、ビジネスへの影響は扱いません。XSS を使用すれば、攻撃者は、被害者がブラウザーを使用して実行可能なあらゆる行為を行うことができるとだけ、ここでは述べておきます。

反射型 XSS と格納型 XSS の両方ともに、サーバー側で適切な検証とエスケープを実行することで対応できます。DOM ベース XSS には、DOM ベース XSS 対策チートシートで説明する特殊なルールのサブセットにより対応できます。

XSS 関連の攻撃ベクトルについてのチートシートは、XSS フィルター回避チートシートを参照してください。ブラウザーセキュリティおよびさまざまなブラウザーについてより詳細な情報は、ブラウザーセキュリティハンドブックを参照してください。

このチートシートを読む前に、インジェクションのセオリーについてしっかり理解しておくことが重要です。

ポジティブ XSS 対策モデル

この資料では、HTML ページをテンプレートと同じように扱います。スロットがあり、開発者はそのスロットに信頼されていないデータを配置できます。これらのスロットは、開発者が信頼されていないデータを配置する可能性のある一般的な場所の大半を網羅しています。信頼されていないデータを HTML の他の場所に配置することは許可されません。これは "ホワイトリスト" モデルであり、ここで明示的に許可されているもの以外はすべて拒否されます。

ブラウザーによる HTML の解析を想定すれば、異なる種類のスロットごとに、少しずつ異なるセキュリティルールがあります。これらのスロットに信頼されていないデータを配置するとき、特定の手順を踏んで、データがスロットの外に抜け出して、コードの実行が可能なコンテキストに入らないようにする必要があります。ある意味で、このアプローチは、HTML ドキュメントをパラメーター化されたデータベースクエリと同じように扱います。データは特定の場所に保持され、エスケープによってコードコンテキストから分離されます。

このドキュメントでは、最も一般的な種類のスロットと、そのスロットに信頼されていないデータを安全に配置するためのルールを提示します。さまざまな仕様、既知の XSS ベクトル、すべての一般的なブラウザーを使用した大量の手動テストに基づいて、ここで提案するルールが安全と判断しました。

スロットの定義、そのいくつかの例を提示しています。開発者は、極めて慎重に分析し、安全であることを確認しない限り、絶対に他のスロットにデータを置いてはいけません。ブラウザーによる HTML の解析処理はとても複雑 であり、一見無害に見える多くの文字が、コンテキストによっては極めて重要になる場合があります。

信頼されていないデータを単純に HTML エンティティエンコードしてはならない理由

HTML エンティティエンコードは、<div> タグ内など、HTML ドキュメントの本文に信頼されていないデータを配置する場合には有効です。また、属性を必ず引用符で囲むようにしている場合、属性に信頼されていないデータを配置するときに効果を発揮します。しかし、任意の場所の <script> タグ、onmouseover などのイベントハンドラ属性、CSS や URL の中に信頼されていないデータを置く場合には、HTML エンティティエンコードは適切に機能しません。そのため、データを配置する場所を考慮せずに HTML エンティティエンコードを行っている場合は、 XSS に対して脆弱なままになります。信頼されていないデータを配置する HTML ドキュメントの場所に合わせたエスケープ構文を使用しなければなりません。以下のルールはこのことをより具体的に説明するものです。

セキュリティエンコードライブラリが必要

これらのエンコーダーを作成するのはさほど難しくはありませんが、いくつかの落とし穴があります。たとえば、JavaScript で \" などのエスケープショートカットを使用したいと考えるかもしれません。しかし、これらの値は危険であり、ブラウザーのネストされたパーサーが誤って解釈する可能性があります。また、エスケープ文字のエスケープを失念する場合があります。攻撃者はこれを利用して、ユーザーの安全対策を無力化できます。OWASP は、セキュリティに特化したエンコードライブラリを使用し、ルールが適切に実装されるようにすることを推奨します。

Microsoft は、.NET プラットフォーム向けに Microsoft Anti-Cross Site Scripting Library というエンコードライブラリを提供しています。また、ASP.NET フレームワークには、ValidateRequest 関数が組み込み済みで、限定的なサニタイズを可能としています。

OWASP ESAPI プロジェクトでは、Java 用のエスケープライブラリを作成しています。また、ハイパフォーマンスなエンコーダーを作成する OWASP Java Encoder プロジェクトも活動しています。

XSS 対策ルール

以下のルールは、アプリケーションにおける、あらゆる XSS を防ぐことを目的としています。これらのルールでは、信頼されていないデータを HTML ドキュメントに自由に配置することを禁止しています。これにより、一般的なユースケースの大半に対処できるはずです。組織で必ずしもすべてのルールを適用する必要はありません。多くの組織では、ルール 1 とルール 2 を適用するだけで十分にニーズを満たすと思われます。頻繁に必要となりエスケープによって安全に保護できる追加コンテキストがある場合は、ディスカッションページに書き加えてください。

これらのルールで指定されている、一連のサンプル文字を単純にエスケープすることはしないでください。ここで例示したものをエスケープするだけでは不十分です。ブラックリストアプローチは脆弱です。ホワイトリストルールは、ブラウザーの変更によって将来新たに発生する可能性のある脆弱性に対する保護も提供できるように、注意深く設計されています。

ルール 0 - 許可された場所以外に信頼されていないデータを挿入しない

1 番目のルールは、すべてを拒否することです。ルール 1 からルール 5 で定義されたスロット以外の、HTML ドキュメントのどの場所にも信頼されていないデータを置いてはいけません。ルール 0 を設定する理由は、HTML には厄介なコンテキストが多すぎて、エスケープルールのリストが複雑になるためです。これらのコンテキストに信頼されていないデータを置く妥当な理由が見当たりません。対象のコンテキストには、javascript 内の URL など、"ネストされたコンテキスト" も含まれます。この場所にエンコードルールを設定するのは問題が多く、危険です。どうしてもネストされたコンテキストに信頼されていないデータを置きたい場合は、十分にクロスブラウザーテストを実施してください。

 <script>...NEVER PUT UNTRUSTED DATA HERE...</script>   スクリプト内に直接
 
 <!--...NEVER PUT UNTRUSTED DATA HERE...-->             HTML コメントのなか
 
 <div ...NEVER PUT UNTRUSTED DATA HERE...=test />       属性名の一部として
 
 <NEVER PUT UNTRUSTED DATA HERE... href="/test" />   タグ名の一部として
 
 <style>...NEVER PUT UNTRUSTED DATA HERE...</style>   CSS 内に直接

最も重要なのは、絶対に、信頼されていないソースから JavaScript コード自体を受け入れて実行しないことです。たとえば、"callback" というパラメーターには、JavaScript コードスニペットが含まれています。どれだけエスケープしても、これを修正することはできません。

ルール 1 - 信頼されていないデータを HTML 要素コンテンツに挿入する前に HTML エスケープする

ルール 1 は、信頼されていないデータを HTML 本文のどこかに直接置きたい場合を対象にしています。これには、div、p、b、td など、通常の内部タグが含まれます。多くの Web フレームワークは、以下に説明する文字に対して HTML エスケープする方法を備えています。しかし、これだけでは他の HTML コンテキストに対して十分ではありません。ここで説明する他のルールも実装する必要があります。

 <body>...ESCAPE UNTRUSTED DATA BEFORE PUTTING HERE...</body>
 
  <div>...ESCAPE UNTRUSTED DATA BEFORE PUTTING HERE...</div>
 
 その他の通常の HTML 要素

HTML エンティティエンコードにより、次の文字をエスケープして、スクリプト、スタイル、イベントハンドラなど、実行コンテキストへの切り替えを防ぎます。仕様では、16進数のエンティティを使用することが推奨されています。XML で重要な 5 つの文字 (&、<、>、"、') に加えて、HTML エンティティの終了を示すスラッシュ文字を含めます。

 & --> &amp;
 < --> &lt;
 > --> &gt;
 " --> &quot;
 ' --> &#x27;     &apos; は HTML 仕様にないため推奨されません (セクション 24.4.1 を参照)。 &apos; は、XML および XHTML の仕様にあります。
 / --> &#x2F;  スラッシュは、HTML エンティティの終了を示すための文字として使われます。

HTML エンティティのエスケープとアンエスケープについて ESAPI 参照実装を参照してください。

 String safe = ESAPI.encoder().encodeForHTML( request.getParameter( "input" ) );

ルール 2 - 信頼されていないデータを HTML 共通属性に挿入する前に属性エスケープする

ルール 2 は、信頼されていないデータを、width、name、value など標準的な属性値に置く場合を対象にしています。href、src、style などの複合属性や、onmouseover などのイベントハンドラに使用してはいけません。イベントハンドラ属性は、HTML JavaScript データ値に関するルール 3 に従うことが、極めて重要です。

 <div attr=...ESCAPE UNTRUSTED DATA BEFORE PUTTING HERE...>content</div>     引用符のない属性内
 
 <div attr='...ESCAPE UNTRUSTED DATA BEFORE PUTTING HERE...'>content</div>   一重引用符で囲まれた属性内
 
 <div attr="...ESCAPE UNTRUSTED DATA BEFORE PUTTING HERE...">content</div>    二重引用符で囲まれた属性内

英数字を除き、ASCII 値(文字コード) 256 未満のすべての文字を &#xHH; 形式 (または使用可能な場合は名前付きエンティティ) でエスケープして、属性から抜け出してコンテキストを切り替えるのを防ぎます。このルールの範囲が極めて広いのは、開発者が属性を引用符で囲まないままにする場合が多いためです。適切に引用符で囲まれた属性は、対応する引用符だけでエスケープできます。属性が引用符で囲まれていない場合、 [space] % * + , - / ; < = > ^ および | など、多くの文字を使用してコンテキストを変更する ことができます。

HTML エンティティのエスケープとアンエスケープについて ESAPI 参照実装を参照してください。

 String safe = ESAPI.encoder().encodeForHTMLAttribute( request.getParameter( "input" ) );

ルール 3 - 信頼されていないデータを JavaScript データ値に挿入する前に JavaScript エスケープする

ルール 3 は、動的に生成された JavaScript コード (スクリプトブロックとイベントハンドラ属性の両方) に関連したルールです。これらの Javascript コードの中で信頼されていないデータを置くことができる安全な場所は、引用符で囲まれた "データ値" 内のみです。他の JavaScript コンテキスト内に信頼されていないデータを含めるのは非常に危険です。セミコロン、等号、スペース、プラス記号、その他多くの文字を使用して、極めて簡単に実行コンテキストに切り替えることができます。そのため、慎重に使用してください。

 <script>alert('...ESCAPE UNTRUSTED DATA BEFORE PUTTING HERE...')</script>     引用符で囲まれた文字列内
 
 <script>x='...ESCAPE UNTRUSTED DATA BEFORE PUTTING HERE...'</script>          引用符で囲まれた式の片側
 
 <div onmouseover="x='...ESCAPE UNTRUSTED DATA BEFORE PUTTING HERE...'"</div>  引用符で囲まれたイベントハンドラ内

JAVASCRIPT エスケープを行っていても、一部の JavaScript 関数では、信頼されていないデータを入力データとして安全に使用できない場合があることに注意してください。

次に例を示します。

 <script>
 window.setInterval('...EVEN IF YOU ESCAPE UNTRUSTED DATA YOU ARE XSSED HERE...');
 </script>

英数字を除き、256 文字未満のすべての文字を \xHH 形式でエスケープして、データ値からスクリプトコンテキストまたは他の属性へコンテキストを切り替えるのを防ぎます。\" などのエスケープショートカットを使用しないでください。 先に実行されているHTML 属性パーサーが引用符文字の突き合わせを行う ためです。また、これらのエスケープショートカットは、"escape-the-escape" 攻撃にさらされる可能性が高くなります。すなわち、攻撃者が \" を送信することで、脆弱なコードはこれを \\" に変換し、引用符で囲むことができてしまいます。

イベントハンドラが適切に引用符で囲まれている場合、対応する引用符がなければ抜け出すことはできません。しかし、イベントハンドラ属性は引用符で囲まないままにされている場合が多いため、このルールをあえて広く設定しました。引用符で囲まれていない属性は、[space] % * + , - / ; < = > ^ および | など、多くの文字を使用して抜け出すことができます。また、HTML パーサーは JavaScript パーサーより前に実行されるため、</script> 終了タグは、引用符で囲まれた文字列内にあってもスクリプトブロックを閉じると解釈されます。

JavaScript のエスケープとアンエスケープについて ESAPI 参照実装を参照してください。

 String safe = ESAPI.encoder().encodeForJavaScript( request.getParameter( "input" ) );

ルール 3.1 - HTML コンテキストの JSON 値を HTML エスケープし、 JSON.parse を使用してデータを読み取る

Web 2.0 の世界では、Javascript コンテキストでアプリケーションにデータを動的に生成させることが一般的に求められます。一つの戦略は、AJAX 呼び出しを作成して値を取得するというものですが、この方法は常に高性能とは限りません。多くの場合、JSON の最初のブロックがページに読み込まれ、複数の値を格納するための単一の場所としての役割を果たします。このデータを、値の形式や内容を壊すことなく正確にエスケープするのは、不可能ではありませんが非常に困難です。

返される Content-Type ヘッダーは、text/html ではなく、application/json でなければなりません。 これにより、ブラウザーはコンテキストを誤って解釈することなく、挿入されたスクリプトを実行します。

誤った HTTP レスポンス:

   HTTP/1.1 200
   Date: Wed, 06 Feb 2013 10:28:54 GMT
   Server: Microsoft-IIS/7.5....
   Content-Type: text/html; charset=utf-8 <-- 誤ったヘッダーです
   ....
   Content-Length:373
   Keep-Alive: timeout=5, max=100
   Connection: Keep-Alive
   {"Message":"No HTTP resource was found that matches the request URI 'dev.net.ie/api/pay/.html?HouseNumber=9&AddressLine
   =The+Gardens<script>alert(1)</script>&AddressLine2=foxlodge+woods&TownName=Meath'.","MessageDetail":"No type was found
   that matches the controller named 'pay'."}   <-- このスクリプトがポップアップされます。
   

正しい HTTP レスポンス

   HTTP/1.1 200
   Date: Wed, 06 Feb 2013 10:28:54 GMT
   Server: Microsoft-IIS/7.5....
   Content-Type: application/json; charset=utf-8 <-- 正しいヘッダーです
   .....
   .....

よくあるアンチパターン:

   <script>
     var initData = <%= data.to_json %>; // 以下に挙げる技法のいずれかを使用してデータをエンコードしない限り、これは行わないでください。
   </script>

JSON エンティティエンコード

JSON エンコードのルールは、出力エンコードのルールの要約を参照してください。この方法では、CSP 1.0 で提供されている XSS 保護を使用できないことに注意してください。

HTML エンティティエンコード

この技法には、HTML エンティティエスケープが広くサポートされており、コンテキスト境界を横断することなく、サーバー側コードからデータを分離できるという利点があります。通常の要素と同じように JSON ブロックをページに配置し、innerHTML を解析してコンテンツを取得することを想定してください。スパンを読み取る Javascript を、外部ファイルに存在させることができるため、CSP 強制の実装がより容易です。

 <script id="init_data" type="application/json">
    <%= html_escape(data.to_json) %>
 </script>
 // external js file
 var dataElement = document.getElementById('init_data');
 // unescape the content of the span
 var jsonText = dataElement.textContent || dataElement.innerText  
 var initData = JSON.parse(html_unescape(jsonText));

JavaScript で直接 JSON をエスケープ / アンエスケープする代わりに、サーバー側で "<" を "\u003c" に変換して JSON データを正規化してからブラウザーに渡す方法もあります。

ルール 4 - 信頼されていないデータを HTML スタイルプロパティ値に挿入する前に、CSS エスケープして厳格に検証する

ルール 4 は、信頼されていないデータをスタイルシートまたはスタイルタグに置きたい場合を対象にしています。CSS は極めて強力で、極めて多くの攻撃で使用されます。そのため、信頼されていないデータはプロパティのでのみ使用し、スタイルデータの他の場所に入れないことが重要です。信頼されていないデータを、url、behavior、custom (-moz-binding) などの複合プロパティに置くことは避けてください。また、JavaScript を許可している IE の式プロパティ値に、信頼されていないデータを置くのも避けてください。

 <style>selector { property : ...ESCAPE UNTRUSTED DATA BEFORE PUTTING HERE...; } </style>     property value
<style>selector { property : "...ESCAPE UNTRUSTED DATA BEFORE PUTTING HERE..."; } </style> property value
<span style="property : ...ESCAPE UNTRUSTED DATA BEFORE PUTTING HERE...">text</span> property value

CSS エスケープを適切に行っていても、CSS コンテキストによっては、信頼されていないデータを入力データとして安全に使用できない場合があることに注意してください。URL が "javascript" ではなく "http" で始まっていること、またプロパティが "expression" で始まっていないことを確認する必要があります。

次に例を示します。

 { background-url :"javascript:alert(1)"; }  // その他すべての URL
 { text-size:"expression(alert('XSS'))"; } // IE のみ

英数字を除き、ASCII 値 (文字コード) 256 文字未満のすべての文字を \HH エスケープ形式でエスケープします。\" などのエスケープショートカットを使用しないでください。先に実行されている HTML 属性パーサーが引用符文字の突き合わせを行う ためです。また、これらのエスケープショートカットは、"escape-the-escape" 攻撃にさらされる可能性が高くなります。すなわち、攻撃者が \" を送信することで、脆弱なコードはこれを \\" に変換し、引用符で囲むことができてしまいます。

属性が引用符で囲まれている場合、抜け出すには対応する引用符が必要です。すべての属性を引用符で囲む必要があります。ただし、信頼されていないデータが引用符で囲まれていないコンテキストに置かれている場合でも XSS を防ぐことができるような、十分に強いエンコードでなければなりません。引用符で囲まれていない属性は、[space] % * + , - / ; < = > ^ および | など、多くの文字を使用して抜け出すことができます。また、</style> タグは、HTML パーサーが JavaScript パーサーより前に実行されるため、引用符で囲まれた文字列内にあっても、スタイルブロックを閉じるために使用できます。引用符で囲まれた属性、囲まれていない属性の両方で、XSS 攻撃を防ぐために、アグレッシブな CSS エンコードと検証を推奨します。

CSS のエスケープとアンエスケープの ESAPI 参照実装を参照してください。

 String safe = ESAPI.encoder().encodeForCSS( request.getParameter( "input" ) );

ルール 5 - 信頼されていないデータを HTML URL パラメーター値に挿入する前に URL エスケープする

ルール 5 は、信頼されていないデータを HTTP GET パラメーター値に置きたい場合を対象にしています。

 <a href="http://www.somesite.com?test=...ESCAPE UNTRUSTED DATA BEFORE PUTTING HERE...">link</a >  

英数字を除き、ASCII 値 (文字コード) 256 文字未満のすべての文字を %HH エスケープ形式でエスケープします。信頼されていないデータをプロトコルスキーム data: の URL に含めないでください。URL からの切り替えを防ぎ、攻撃を無効化するための有効な手段がないためです。すべての属性を引用符で囲む必要があります。引用符で囲まれていない属性は、[space] % * + , - / ; < = > ^ および | など、多くの文字を使用して抜け出すことができます。このコンテキストでは、エンティティエンコードが役に立たないことに注意してください。

URL のエスケープとアンエスケープについて ESAPI 参照実装を参照してください。

 String safe = ESAPI.encoder().encodeForURL( request.getParameter( "input" ) );

警告:URL エンコードで、完全な URL または相対 URL をエンコードしないでください。信頼されていない入力が href、src、またはその他の URL ベースの属性内に置かれる場合、その入力を検証して、予期していないプロトコル、特に Javascript リンクを指していないことを確認する必要があります。それから、他のデータと同様に、URL は、表示のコンテキストに基づいて、エンコードする必要があります。たとえば、HREF リンク内のユーザー主導の URL は、エンコードされた属性でなければなりません。次に例を示します。

 String userURL = request.getParameter( "userURL" )
 boolean isValidURL = ESAPI.validator().isValidInput("URLContext", userURL, "URL", 255, false);
 if (isValidURL) {
     <a href="<%=encoder.encodeForHTMLAttribute(userURL)%>">link</a>
 }

ルール 6 - 専用に設計されたライブラリを使用して HTML マークアップをサニタイズする

アプリケーションでマークアップ (HTML が含まれることが想定される信頼されていない入力) を処理する場合、検証は非常に難しくなります。また、入力内に存在すると想定されるすべてのタグを壊す可能性があるため、エンコードも難しくなります。そのため、HTML 形式のテキストを解析し、クリーニングできるライブラリが必要になります。OWASP では、簡単に使用できるライブラリをいくつか用意しています。

HtmlSanitizer - https://github.com/mganss/HtmlSanitizer

オープンソースの .Net ライブラリです。HTML は、ホワイトリストアプローチによってクリーニングされます。許可されたすべてのタグと属性を構成できます。このライブラリは、OWASP XSS フィルター回避チートシートを使用して、単体テストが実施されています。

  var sanitizer = new HtmlSanitizer();
  sanitizer.AllowedAttributes.Add("class");
  var sanitized = sanitizer.Sanitize(html);

OWASP Java HTML Sanitizer - https://www.owasp.org/index.php/OWASP_Java_HTML_Sanitizer_Project

  import org.owasp.html.Sanitizers;
  import org.owasp.html.PolicyFactory;
  PolicyFactory sanitizer = Sanitizers.FORMATTING.and(Sanitizers.BLOCKS);
  String cleanResults = sanitizer.sanitize("<p>Hello, <b>World!</b>");

OWASP Java HTML Sanitizer のポリシー構築について詳しくは、http://owasp-java-html-sanitizer.googlecode.com/svn/trunk/distrib/javadoc/org/owasp/html/Sanitizers.html を参照してください。

Ruby on Rails SanitizeHelper - http://api.rubyonrails.org/classes/ActionView/Helpers/SanitizeHelper.html

SanitizeHelper モジュールは、不適切な HTML 要素のテキストをクリーンにするための一連の手法を提供します。

  <%= sanitize @comment.body, tags: %w(strong em a), attributes: %w(href) %>

HTML サニタイズを提供するその他のライブラリは、以下のとおりです。

PHP Html Purifier - http://htmlpurifier.org/
JavaScript/Node.JS Bleach - https://github.com/ecto/bleach
Python Bleach - https://pypi.python.org/pypi/bleach

ルール 7 - DOM ベース XSS の防止

DOM ベース XSS の詳細およびその対策については、DOM ベース XSS 対策チートシート を参照してください。

ボーナスルール 1: HTTPOnly Cookie フラグの使用

アプリケーションにおけるすべての XSS 欠陥を防ぐのは、ご承知のとおり困難です。サイトにおける XSS 欠陥の影響を軽減するために、OWASP は、セッション Cookieおよび Javascript からアクセスされることを想定していないカスタム Cookie に、HTTPOnly フラグを設定することを推奨します。.NET アプリケーションでは、この Cookie フラグは通常デフォルトで 設定されていますが、他の言語では手動で設定する必要があります。HTTPOnly Cookie フラグの機能など詳しくは、HTTPOnly に関する OWASP の資料を参照してください。

ボーナスルール 2: コンテンツセキュリティポリシー (CSP) の実装

XSS 欠陥の影響を軽減する優れた複合ソリューションとして、もう 1 つ、コンテンツセキュリティポリシー (CSP) が挙げられます。これは、ブラウザー側のメカニズムで、Web アプリケーションのクライアント側リソース (JavaScript、CSS、イメージなど) に関して、ソースのホワイトリストを作成できます。CSP は、特殊な HTTP ヘッダーを介して、特定のソースからリソースの実行やレンダリングを行うようにブラウザーに指示します。たとえば、以下の CSP があるとします。

Content-Security-Policy: default-src:'self'; script-src:'self' static.domain.tld

この CSP は、すべてのリソースをページと同一のオリジンから読み込むこと、および JavaScript ソースコードファイルを読み込む先としてはページと同一のオリジンに加えて static.domain.tld も許可するように指示します。コンテンツセキュリティポリシー (CSP) の機能や使用法など詳しくは、コンテンツセキュリティポリシー (CSP) に関する OWASP の資料を参照してください。

ボーナスルール 3: 自動エスケープテンプレートシステムの使用

多くの Web アプリケーションフレームワークは、コンテキストに応じて自動的にエスケープ処理を行う機能を提供しています。例えば、AngularJS のコンテキストに応じたエスケープ機能Go テンプレートなどがあります。使用可能な場合は、これらのテクノロジを使用してください。

ボーナスルール 4: X-XSS-Protection レスポンスヘッダーの使用

この HTTP レスポンスヘッダーを使用すると、最新のいくつかの Web ブラウザーで実装されているクロスサイトスクリプティング (XSS) フィルターを有効にできます。このヘッダーは、通常デフォルトで有効になっています。そのため、このヘッダーの役割は、XSSフィルターがユーザーによって無効に設定されている場合に、特定の Web サイトで XSS フィルターを再度有効にすることです。

XSS 対策ルールの要約

以下の HTML のスニペットは、さまざまな異なるコンテキストにおいて、信頼されていないデータをどのようにして安全にレンダリングするかを示しています。

安全な HTML 属性の例: align、alink、alt、bgcolor、border、cellpadding、 cellspacing、class、color、cols、colspan、coords、dir、face、height、hspace、ismap、lang、marginheight、marginwidth、multiple、nohref、noresize、noshade、nowrap、ref、rel、rev、rows、rowspan、scrolling、shape、span、summary、tabindex、title、usemap、valign、value、vlink、vspace、width

出力エンコードのルールの要約

クロスサイトスクリプティングに関連した出力エンコードの目的は、信頼されていない入力を、ブラウザーで入力がコードとして実行されることなく、データとしてユーザーに表示されるように、安全な形式に変換することです。以下の表は、クロスサイトスクリプティングを阻止するために必要な、重要な出力エンコード方式を一覧にしています。

エンコードタイプ エンコードメカニズム
HTML エンティティエンコード Convert & to &amp;
Convert < to &lt;
Convert > to &gt;
Convert " to &quot;
Convert ' to &#x27;
Convert / to &#x2F;
HTML 属性エンコード 英数字を除き、スペースを含む、HTML エンティティ &#xHH; 形式のすべての文字をエスケープします。(HH = 16 進値)
URL エンコード 標準的なパーセントエンコード (http://www.w3schools.com/tags/ref_urlencode.asp を参照)。URL エンコードは、パラメーター値のエンコードにのみ使用し、URL 全体や、URL のパスフラグメントに使用してはいけません。
JavaScript エンコード 英数字を除き、\uXXXX unicode エスケープ形式 (X は整数) のすべての文字をエスケープします。
CSS Hex エンコード CSS エスケープは、\XX および \XXXXXX をサポートします。2 文字エスケープを使用すると、次の文字がエスケープシーケンスを続行する場合に問題が発生する可能性があります。2 つの解決策があります。a) CSS エスケープの後にスペースを追加する (CSS パーサーによって無視されます)。b) 値にゼロを埋め込んで、可能な限り全部の CSS エスケープを使用する。

関連資料

XSS 攻撃に関するチートシート

次の資料は、さまざまな XSS 脆弱性がどのように利用されるかを説明しています。

Web アプリケーションフレームワークにおける XSS サニタイズの系統的分析

http://www.cs.berkeley.edu/~prateeks/papers/empirical-webfwks.pdf

XSS 脆弱性の説明

  • XSS 脆弱性に関する OWASP の資料

さまざまな XSS 脆弱性の種類に関するディスカッション

クロスサイトスクリプティングの脆弱性に関するコードのレビュー方法

クロスサイトスクリプティングの脆弱性に関するテスト方法

Authors and Primary Editors

Eoin Keary - eoin.keary[at]owasp.org
Jeff Williams - jeff.williams[at]owasp.org
Jim Manico - jim[at]owasp.org
Neil Mattatall - neil[at]owasp.org

Other Cheatsheets

Developer Cheat Sheets (Builder)

Assessment Cheat Sheets (Breaker)

Mobile Cheat Sheets

OpSec Cheat Sheets (Defender)

Draft Cheat Sheets