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.

参考

関連記事


  1. Spring Security + ThymeleafでAjaxリクエストにCSRF対策トークンを適用
  2. 一部のパスだけSpring SecurityのCSRF対策を無効化する
  3. OpenSSL+パスワードでファイルの暗号化/復号処理
  4. TrueCryptのレビューレポートを読んでみた
  5. Google ChromeのSSL/TLS暗号化アルゴリズム設定

tosi avatar
tosi
Web Application Engineer, Java / Spring / Azure / GCP
comments powered by Disqus