SRIによってCDN上のスクリプト改ざんを検知する
背景:CDNを使うメリットと注意点
動的なWebページをデザインする場合、JavaScriptやCSSをCDNから読み込むようにすることで、主に以下のようなメリットがある。
- サイトを越えてキャッシュが効く(ユーザのページ読み込み時間の短縮)
- Webサーバのリクエスト・トラフィック削減
- Webサーバ上のデータ量削減
- バージョンの切り替え作業が簡易化
一方でCDN上のJavaScriptやCSSが改ざんされると意図しない動作を引き起こすことになるため、注意が必要。
そのため、CDNにアクセスするURLはhttpsプロトコル(SSL/TLS)を使用するのが一般的。
httpsプロトコル(SSL/TLS)を使用しないと発信元サーバを証明できないため、中間者攻撃によってスクリプトを改ざんされる可能性がある。
SRIの生成方法
SRI(Subresource Integrity)という枠組みがあり、スクリプトのハッシュ値を計算することによって改ざんされていないかどうか検証することができる。
SRIは以下のサイトで生成するのが簡単。(ただし、生成する際にCDNのスクリプトが改ざんされていないことが前提)
https://www.srihash.org/
実際に生成すると、以下の出力が得られる。
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js" integrity="sha384-3ceskX3iaEnIogmQchP8opvBy3Mi7Ce34nWjpBIwVTHfGYWQS9jwHDVRnpKKHJg7" crossorigin="anonymous"></script>
なおcrossorigin属性は、リクエストに認証情報をセットするかどうかを指定する。
CDNは認証情報を必要としないものが一般的だと思うので、anonymousのままでOK。
SRIが一致しない場合の挙動
試しに生成したハッシュの一部を書き換えてみたところ、Google ChromeでJavaScriptが実行されないことを確認できた。
このとき、以下のようなメッセージがコンソールに表示される。
Failed to find a valid digest in the 'integrity' attribute for resource 'https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js' with computed SHA-256 integrity 'hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8='. The resource has been blocked.