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

HTML5 セキュリティに関するチートシート

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

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

はじめに

以下のチートシートは、HTML 5 をセキュアに実装するためのガイドの役割を果たします。

通信 API

Web メッセージング

Web メッセージング (クロスドメインメッセージングとも呼ばれます) は、オリジンが異なるドキュメント間で、従来使用されてきたさまざま手法よりも安全に、メッセージをやり取りする手段を提供します。ただし、留意すべきアドバイスがいくつかあります。

  • メッセージをポストする際には、想定するオリジンを postMessage の第 2 引数 として、 明示的に指定します。これにより、リダイレクト後や、他の何らかの方法でターゲットウィンドウのオリジンが変更された後で、不明なオリジンにメッセージが送信されるのを防止できます。
  • 受信側のページでは、以下のことを必ず実行してください。
    • 送信側の origin 属性を調べて、データの生成元が所期の場所であることを確認します。
    • イベントの data 属性に対して入力検証を実行し、適切な形式であることを確認します。
  • data 属性を制御できると思い込まないでください。送信側ページにクロスサイトスクリプティングの不備が 1 つでもあれば、攻撃者は任意の形式のメッセージを送信できます。
  • どちらのページでも、やり取りするメッセージをデータとしてのみ解釈してください。受け取ったメッセージをコードとして評価したり ( eval() などを使用)、ページ DOM に挿入したり ( innerHTML などを使用) すると、DOM ベースの XSS 脆弱性を引き起こすので、絶対にしないでください。詳細については、「DOM ベース XSS 対策チートシート」を参照してください。
  • 要素にデータ値を割り当てるときは、 element.innerHTML = data; のような危険な方法ではなく、より安全な方法である element.textContent = data; を使用します。
  • origin プロパティが所期の完全修飾ドメイン名 (FQDN) と完全に一致していることを確認してください。次のコード if(message.orgin.indexOf(".owasp.org")!=-1) { /* ...*/ } は非常に危険であり、正しく動作しません。なぜなら、 www.owasp.org.attacker.com と一致するからです。
  • 外部コンテンツや信頼できないガジェットを埋め込み、ユーザーが制御するスクリプトを許可する必要がある場合は (これはまったくお勧めできません)、Google Caja などの JavaScript リライトフレームワークの使用を検討するか、「サンドボックス化フレーム」の情報を確認してください。

クロスオリジンリソース共有 (CORS)

  • XMLHttpRequest.open に渡された URL を検証してください。現行のブラウザーでは、これらの URL がクロスドメインであることを許可しています。この挙動は、リモート攻撃者によるコードインジェクションをもたらすおそれがあります。特に、絶対 URL に注意してください。
  • Access-Control-Allow-Origin: * に対応する URL に機密の内容や情報はいっさい含めないでください。攻撃者のさらなる攻撃を助けることになります。 Access-Control-Allow-Origin ヘッダーは、クロスドメインアクセスが必要な特定の URL でのみ使用します。このヘッダーをドメイン全体に使用しないでください。
  • 選別した、信頼できるドメインだけを Access-Control-Allow-Origin ヘッダーで許可してください。ドメインをブラックリスト化したり、すべてのドメインを許可したりするのではなく、ホワイトリスト化することをお勧めします ( * ワイルドカードの使用や、 Origin ヘッダーの内容をチェックなしでむやみに返すことはしないでください)。
  • 要求されたデータが認証されていない場所に送信されないように CORS 自体が防止することはないので注意してくだい。そのため、サーバーで通常の CSRF 対策を実施することがやはり重要です。
  • RFC では OPTIONS 動詞を使用したプリフライトリクエストを推奨していますが、現在の実装ではこのリクエストが実行できない場合があります。そのため、"通常" の (GET POST) リクエストで必要なすべてのアクセス制御を行うことが重要です。
  • HTTPS オリジンを含むプレーン HTTP 経由で受け取ったリクエストを破棄することにより、混合コンテンツのバグを予防してください。
  • アクセス制御チェックで Origin ヘッダーを信用しないでください。ブラウザーは常にこのヘッダーを CORS リクエストに入れて送信しますが、ブラウザー外でのなりすましの危険性があります。機密データの保護にはアプリケーションレベルのプロトコルを使用する必要があります。

WebSocket

  • 実装されたクライアント / サーバーでの下位互換性を捨てて、hybi-00 より新しいバージョンのプロトコルのみを使用します。一般的な Hixie-76 バージョン (hiby-00) とそれより前のバージョンは既に古く、安全ではありません。
  • すべての現行ブラウザーの最新版でサポートされている推奨バージョンは RFC 6455 です (Firefox 11 以上、Chrome 16 以上、Safari 6、Opera 12.50、IE10 でサポート)。
  • WebSocket (VNC、FTP) を介して TCP サービスをトンネルするのは比較的簡単ですが、そうすると、クロスサイトスクリプティング攻撃の場合に、トンネルしたサービスへのアクセスをブラウザー内の攻撃者に許すことになります。これらのサービスが悪意のあるページやプログラムから直接呼び出される危険もあります。
  • このプロトコルは認可や認証には対応していません。機密データを転送する場合は、アプリケーションレベルのプロトコルで別途、その処理を行う必要があります。
  • WebSocket で受け取ったメッセージはデータとして処理します。受け取ったメッセージを DOM に直接割り当てたり、コードとして評価したりしないでください。応答が JSON の場合は、安全でない eval() 関数を絶対に使用しないでください。代わりに、安全なオプションである JSON.parse() を使用します。
  • ws:// プロトコルを介して公開されたエンドポイントは、プレーンテキストに簡単に戻すことができます。中間者攻撃を防ぐために、必ず wss:// (WebSockets over SSL/TLS) を使用してください。
  • ブラウザー外でクライアントになりすますことが可能なため、WebSocket サーバーは不正 / 悪質な入力に対処できる必要があります。リモートサイトからの入力は、改ざんされているおそれがあるので、必ず検証してください。
  • サーバーの実装時には、Websocket ハンドシェークの Origin: ヘッダーを確認してください。ブラウザー外でなりすまされる可能性はありますが、ブラウザーは Websocket 接続を開始したページのオリジンを必ず追加します。
  • ブラウザー内の WebSocket クライアントは JavaScript 呼び出しでアクセスできるので、どの WebSocket 通信も クロスサイトスクリプティングによってなりすまされたり、ハイジャックされたりする危険があります。WebSocket 接続経由で受信するデータは、必ず検証してください。

サーバー送信イベント

  • オリジンが同じ URL のみを許可している場合でも、 EventSource コンストラクターに渡された URL を検証してください。
  • 前述のとおり、メッセージ (event.data) はデータとして処理します。その内容を HTML やスクリプトコードとして絶対に評価しないでください。
  • メッセージの origin 属性 (event.origin) を調べて、そのメッセージが信頼できるドメインから来たことを確認します。ホワイトリスト方式を採用してください。

ストレージ API

ローカルストレージ

  • オフラインストレージ、Web ストレージとも呼ばれます。基となるストレージの仕組みがユーザーエージェントによって異なる可能性があります。言い換えれば、データが保存されているマシンに対してローカル権限を持つユーザーなら、アプリケーションから要求されるあらゆる認証を回避することができます。このため、ローカルストレージには機密情報をいっさい保存しないことをお勧めします。
  • 永続的に保存する必要がない場合は、localStorage オブジェクトではなく、sessionStorage オブジェクトを使用します。sessionStorage オブジェクトを使用できるのはそのウィンドウ/タブのみに限られ、ウィンドウが閉じるまでしか使えません。
  • たった 1 つのクロスサイトスクリプティングで、これらのオブジェクト内のデータをすべて盗み出すことができます。したがって、くれぐれも、機密情報をローカルストレージに保存しないようにしてください。
  • 同様に、たった 1 つのクロスサイトスクリプティングで、悪意のあるデータをこれらのオブジェクトにロードすることもできます。このため、オブジェクト内のデータが信頼できるとは思わないでください。
  • HTML5 ページに実装された "localStorage.getItem" 呼び出しと "setItem" 呼び出しに特に注意を払ってください。これは、機密情報をローカル ストレージに保存するソリューションを開発者がいつ構築したかを調べるのに役立ちます。ローカルストレージへの保存は悪しき慣行です。
  • セッション ID をローカルストレージに保存しないでください。このデータは JavaScript でいつでもアクセスできます。Cookie の httpOnly フラグを使用すると、このリスクを軽減できます。
  • HTTP Cookie の path 属性の場合と同様に、オブジェクトの可視性を特定のパスに限定する方法はありません。すべてのオブジェクトは 1 つのオリジン内で共有され、同じオリジンポリシーで保護されます。複数のアプリケーションを同じオリジンにホストするのは避けてください。どのアプリケーションも同じ localStorage オブジェクトを共有することになってしまいます。代わりに、別々のサブドメインを使用してください。

クライアント側データベース

  • 2010 年 11 月、W3C が Web SQL Database (リレーショナル SQL データベース) は廃止予定の仕様であると発表しました。新しい標準の Indexed Database API (IndexedDB、旧称 WebSimpleDB) は現在開発中です。これは、キーバリュー型のデータベースストレージと、高度なクエリを実行するためのメソッドを提供します。
  • 基となるストレージの仕組みがユーザーエージェントによって異なる可能性があります。言い換えれば、データが保存されているマシンに対してローカル権限を持つユーザーなら、アプリケーションから要求されるあらゆる認証を回避することができます。このため、ローカルストレージには機密情報をいっさい保存しないことをお勧めします。
  • 使用した場合、クライアント側の WebDatabase コンテンツが SQL インジェクション攻撃を受けやすくなるおそれがあるため、適切な検証とパラメーター化が必要になります。
  • ローカルストレージと同様に、たった 1 つのクロスサイトスクリプティングで、悪意のあるデータを Web データベースにもロードできます。Web データベース内のデータが信頼できるとは思わないでください。

位置情報

  • 位置情報の RFC では、位置を計算する前にユーザーエージェントがユーザーの許可を求めるよう推奨しています。これを実装するか否か、およびその実装方法はブラウザーによって異なります。ユーザーエージェントの中には、ユーザーの許可なしに位置情報を取得する機能をオフにするには、ページを再訪問するようユーザーに要求するものもあります。そのため、プライバシー上の理由から、 getCurrentPosition または watchPosition を呼び出す前にユーザー入力を求めることをお勧めします。

Web Worker

  • Web Worker は、 XMLHttpRequest オブジェクトを使用してドメイン内リクエストとクロスオリジンリソース共有 (CORS) リクエストを実行できます。このチートシートの当該セクションを参照して、CORS のセキュリティを確保してください。
  • Web Worker には呼び出し元ページの DOM へのアクセス権はありませんが、悪意のある Web Worker が演算に過剰な CPU を消費して DoS 状態に陥れたり、CORS をさらなる攻撃に悪用したりするおそれがあります。どの Web Worker のコードにも悪意がないことを確認してください。ユーザーが行った入力から Web Worker スクリプトを作成できないようにしてください。
  • Web Worker とやり取りしたメッセージを検証してください。Javascript のスニペットを交換して eval() などで評価しようとしないでください。DOM ベースの XSS に対する脆弱性が生じる危険があります。

サンドボックス化フレーム

  • 信頼できないコンテンツに対しては、iframe の sandbox 属性を使用します。
  • iframe の sandbox 属性を使用すると、iframe 内のコンテンツを制限することが可能になります。sandbox 属性を設定すると、以下の制限が有効になります。
    1. すべてのマークアップをただ 1 つのオリジンに由来するものとして扱う。
    2. すべてのフォームとスクリプトを無効にする。
    3. どのリンクも他の閲覧コンテキストをターゲットにできないようにする。
    4. 自動的に起動される機能をすべてブロックする。
    5. すべてのプラグインを無効にする。

sandbox 属性の値を使用して、iframe の機能をきめ細かく管理できます。

  • この機能に対応していない古いバージョンのユーザーエージェントでは、この属性は無視されます。この機能を追加の保護レイヤーとして利用するか、ブラウザーがサンドボックス化フレームに対応しているかどうかを確認して、対応している場合のみ、信頼できないコンテンツを表示します。
  • この属性のほかに、クリックジャッキングや迷惑なフレーム化を防止するために、ヘッダーの X-Frame-Options の使用をお勧めします。これは、 deny same-origin という値をサポートしています。他にも、フレームを壊す if(window!== window.top) { window.top.location = location; } のような対策を推奨します。

オフラインアプリケーション

  • オフライン閲覧用のデータを保存する許可をユーザーエージェントがユーザーに求めるかどうかや、このキャッシュをいつ削除するかは、ブラウザーによって異なります。安全でないネットワークを経由してユーザーが接続する場合、キャッシュポイズニングが問題となります。そのため、プライバシー上の理由から、 manifest ファイルを送信する前にユーザー入力を求めることをお勧めします。
  • ユーザーは、信頼できる Web サイトのみをキャッシュするようにし、オープンなネットワークや安全でないネットワークを介して閲覧した後にはキャッシュを消去する必要があります。

プログレッシブエンハンスメントとグレイスフルデグラデーションのリスク

  • 現時点のベストプラクティスは、ブラウザーが対応している機能を識別し、直接対応していない機能については、何らかの代替機能で補うことです。これは、タマネギのように層状の要素 (たとえば、<video> タグに対応していなければ、Flash Player まで落とすなど) を意味する場合もあれば、さまざまなソースからのスクリプティングコードの追加を意味する場合もあります。スクリプティングコードはレビューが必要です。

セキュリティを強化する HTTP ヘッダー

X-Frame-Options

  • 最新ブラウザーでは、このヘッダーを使用してクリックジャッキングを防止できます。
  • same-origin 属性を使用してオリジンが同じ URL からのフレーム化を許可するか、 deny を使用してすべてをブロックします。例: X-Frame-Options: DENY
  • クリックジャッキング対策の詳細については、「クリックジャッキング対策に関するチートシート」を参照してください。

X-XSS-Protection

  • XSS フィルターを有効にします (反射型 XSS にのみ機能します)。
  • 例: X-XSS-Protection: 1; mode=block

厳重な転送セキュリティ

  • すべてのブラウザーリクエストを強制的に TLS/SSL 経由で送信させます (これで SLL ストリップ攻撃を防御できます)。
  • includeSubDomains を使用します。
  • 例: Strict-Transport-Security: max-age=8640000; includeSubDomains

コンテンツセキュリティポリシー

  • Web リソースに対する一連のコンテンツ制限を定義するポリシー。クロスサイトスクリプティングといった Web アプリケーションの脆弱性を軽減することを目的としています。
  • 例: Content-Security-Policy: allow 'self'; img-src *; object-src media.example.com; script-src js.example.com

Origin

  • CORS/WebSocket リクエストによって送信されます。
  • このヘッダーを利用して CSRF 攻撃を軽減するという提案がありますが、この目的での実装はまだベンダーが行っていません。

Authors and Primary Editors

First Last Email
Mark Roxberry mark.roxberry [at] owasp.org
Krzysztof Kotowicz krzysztof [at] kotowicz.net
Will Stranathan will [at] cltnc.us
Shreeraj Shah shreeraj.shah [at] blueinfy.net
Juan Galiana Lara jgaliana [at] owasp.org

Other Cheatsheets

Developer Cheat Sheets (Builder)

Assessment Cheat Sheets (Breaker)

Mobile Cheat Sheets

OpSec Cheat Sheets (Defender)

Draft Cheat Sheets