【エスアールアイ】

SRI(サブリソース完全性) とは?

💡 外部ファイルの指紋照合、すり替え防止の最後の砦
📌 このページのポイント
SRI によるファイル改ざん検知 HTML <script src="cdn/lib.js" integrity="sha384-abc..." crossorigin="anonymous"> CDN lib.js を配信 (外部サーバー) ブラウザ ダウンロード後 ハッシュ値を照合 ハッシュ一致(正常) sha384-abc... 期待値 = sha384-abc... 実際の値 読み込み許可 ハッシュ不一致(改ざん) sha384-abc... 期待値 sha384-xyz... 実際の値 読み込みブロック! CDNが攻撃されてもブラウザ側で改ざんを検知し、悪意あるコードの実行を防止
SRI(サブリソース完全性)によるファイル改ざん検知のイメージ
ひよこ ひよこ

SRIって何なの?外部ファイルの改ざんを防ぐって聞いたけど。

ペンギン先生 ペンギン先生

SRIは、CDNなど外部サーバーから読み込むJavaScriptCSSファイルが本物かどうかをハッシュ値で検証する仕組みだよ。HTMLのscriptタグに integrity="sha384-xxxx..." みたいな属性を付けておくと、ブラウザがダウンロードしたファイルのハッシュを計算して、一致しなければ読み込みを拒否してくれるんだ

ひよこ ひよこ

なんでそんな仕組みが必要なの?CDNって信頼できるサービスじゃないの?

ペンギン先生 ペンギン先生

CDN自体は信頼できるけど、万が一CDNサーバーが攻撃されてファイルが書き換えられたらどうなる?世界中のWebサイトが同じCDNからjQueryやBootstrapを読み込んでいるから、1つのファイルを改ざんするだけで数百万のサイトに悪意のあるコードを配布できちゃうんだ。これがサプライチェーン攻撃だよ

ひよこ ひよこ

そんなこと本当に起きるの?

ペンギン先生 ペンギン先生

実際に起きているよ。2018年にはイベント配信サービスのCDNが攻撃されて、仮想通貨を盗むスクリプトが仕込まれた事例があるし、npmパッケージの改ざん事件も何度も起きている。SRIがあれば、たとえCDNが攻撃されてもブラウザ側で検知して読み込みをブロックできるんだ

ひよこ ひよこ

使い方は難しいの?

ペンギン先生 ペンギン先生

すごく簡単だよ。たとえば <script src="https://cdn.example.com/lib.js" integrity="sha384-abc123..." crossorigin="anonymous"></script> みたいに書くだけ。ハッシュ値はshasum コマンドやオンラインツールで生成できるし、cdnjsやjsDelivrなどの主要CDNコピペ用のintegrity付きタグを提供してくれているよ

ひよこ ひよこ

crossoriginも一緒に書くのはなんでなの?

ペンギン先生 ペンギン先生

SRIの検証にはファイルの中身をバイト単位で読み取る必要があるんだけど、別ドメインリソースCORSの制限で中身にアクセスできないことがある。crossorigin="anonymous" を付けることで、CORSリクエストとして読み込んでハッシュ検証が正しく動作するようになるんだ

ひよこ ひよこ

ハッシュのアルゴリズムはどれを使えばいいの?

ペンギン先生 ペンギン先生

SHA-256、SHA-384、SHA-512が使えるけど、W3Cの仕様ではSHA-384が推奨されているよ。SHA-256でも十分安全だけど、SHA-384はパフォーマンスと安全性のバランスが良いとされているんだ。ちなみにintegrityには複数のハッシュをスペース区切りで書けて、ブラウザは最も強いアルゴリズムを優先して検証するよ

ひよこ ひよこ

SRIを導入するときに気をつけることってあるの?

ペンギン先生 ペンギン先生

CDN側がファイルを正規にアップデートしたらハッシュが変わるから、integrityの値も更新しないとサイトが壊れる可能性があるよ。だからバージョン固定のURLを使うのが鉄則だね。あとContent Security Policyのrequire-sri-forディレクティブを使えば、SRIなしの外部リソース読み込みを一律ブロックすることもできるよ

ペンギン
まとめ:ざっくりこれだけ覚えればOK!
「SRI」って出てきたら「外部ファイルの改ざんをハッシュ値で検知するブラウザの仕組み」と思えればだいたいOK!
📖 おまけ:英語の意味
「Subresource Integrity」 = サブリソースの完全性
💬 subresource(副リソース)はHTMLから読み込まれるJS・CSSなどの外部ファイルのこと。integrity(完全性)はデータが改ざんされていない状態を指す言葉で、「外部ファイルが本物かどうかを保証する」という意味の名前だよ
← 用語集にもどる