Subresource Integrity (SRI)は、CDNなどから受信するファイルが意図しない改ざんをされていないかをブラウザが検証するためのセキュリティ機能です。SRIは受信したファイルのハッシュ値と一致すべきハッシュ値を与えることにより機能します。
なぜSubresource Integrityが必要なのか
複数のサイトで使われるようなスクリプトやスタイルシートなどのファイルをContent Delivery Networks (CDNs)にホストすることによってサイトの読み込み時間や使用帯域を減らすことができます。しかし、CDNはリスクにもなりえます。仮に攻撃者がCDNを掌握できれば、攻撃者はCDN上のファイルに悪意あるコンテンツを挿入することにより(あるいは完全に置き換えることにより)CDNからファイルを読み込む全てサイトを手中に収めることが可能となります。Subresource IntegrityはWebアプリケーションやWebドキュメントがCDNを含む、あらゆる場所から読み込むファイルが第三者によって改ざんされていないかを検証することにより、このような攻撃のリスクを軽減します。
Subresource Integrityの使い方
ブラウザが読み込むリソース(ファイル)のbase64エンコードされたハッシュ値を<script>
や<link>
要素のintegrity属性の値に指定することによりSubresource Integrityの機能を使うことができます。
integrity属性の値はハッシュアルゴリズムを示すプレフィックス(今のところsha256
とsha384
, sha512
がサポートされています)とbase64でエンコードされたハッシュ値をダッシュでつなげた文字列です。
integrity属性の値はホワイトスペースで句切られた複数のハッシュ値を含むことができます。リソースはこれらのハッシュ値のどれかに一致した場合に読み込まれます。
base64でエンコードされたsha384ハッシュを含むintegrity文字列の例:
sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC
integrityのハッシュのパートは厳密に言うと、あるハッシュ関数にデータを入力(スクリプトやスタイルシートファイル)することにより生成された暗号学的ダイジェスト値です。しかし暗号学的ダイジェスト値はハッシュと呼ぶほうが一般的であるため本記事でもそのように呼んでいます。
SRIハッシュを生成するツール
次のopensslコマンドによりSRIハッシュを生成することができます:
cat FILENAME.js | openssl dgst -sha384 -binary | openssl enc -base64 -A
また、SRI Hash Generator (https://srihash.org/)によりオンラインでSRIハッシュを生成することもできます。
例
以下の例では、example-framework.js
のSHA-384ハッシュ値がoqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wCであり、
https://example.com/example-framework.jsにホストされているものとします。
例: script要素のSubresource Integrity
次の<script>
要素によりブラウザにhttps://example.com/example-framework.jsを実行する前に、まず想定されるハッシュ値とスクリプトのハッシュ値が一致することを確認させることができます。
<script src="https://example.com/example-framework.js"
integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC
"
crossorigin="anonymous"></script>
crossorigin属性についてはCORS settings attributesを参照してください。
Subresource Integrityのブラウザでの扱い
ブラウザはSRIを以下により扱います:
- ブラウザはintegrity属性を持った
<script>
か<link>
属性を見つけるとスクリプトや<link>
属性で定義されたいかなるスタイルシートを適用する前に、integrity値のハッシュ値とスクリプトやスタイルシートのハッシュ値を比較しなくてはなりません。 - スクリプトやスタイルシートがそれと対応するintegrity値と一致しない場合、ブラウザはスクリプトを実行したりスタイルシートを適用してはいけません。その代わりにスクリプトやスタイルシートの取得が失敗したというネットワークエラーを返さなくてはなりません。
仕様
仕様 | ステータス | コメント |
---|---|---|
Subresource Integrity | 勧告 | |
Fetch | 現行の標準 |
ブラウザ互換性
機能 | Chrome | Firefox (Gecko) | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|
<script> と<link> のintegrity属性 |
45.0 | 43 (43) | 未サポート | 32 | 未サポート [1] |
機能 | Chrome for Android | Firefox Mobile (Gecko) | IE Mobile | Opera Mobile | Safari Mobile |
---|---|---|---|---|---|
<script> と<link> のintegrity属性 |
45.0 | 43.0 (43) | 未サポート | 未サポート | 未サポート [1] |