search
LoginSignup
63
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

posted at

[Chrome 45+][Firefox 43+][Opera 32+] CDNからのXSSを防ぐ

CDN

外部のURIを使ってライブラリなどのダウンロードを高速化する仕組み。

<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">

見ての通り、CDNサービスがハックされてファイルが改竄されたりするとXSSが起こる。

Subresource Integrity

ファイルのハッシュをHTMLに書いておいて改竄を検出する仕組み。

<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"
        integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS"
        crossorigin="anonymous"></script>
<link rel="stylesheet"
      href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"
      integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7"
      crossorigin="anonymous">

integrity属性にはファイルのハッシュとハッシュを作るのに使ったハッシュ関数を書いておく。
crossorigin属性はCORS[1]に関係する属性で、integrity属性を使う場合は必須。
[2]によれば、crossorigin属性はCross-origin data leakageという脆弱性が生まれてしまうのを防ぐために必要なのだそうだ(よく分かってない)。
[3]によれば、crossorigin="anonymous"は、Cookieや認証情報のような、ユーザとCDNを利用しているドメインとを関連付けることを可能にする情報を、CDNサービスに送信しないことを意味し、これによってCross-origin data leakageを防ぐことができるという。

ハッシュ関数として何を使うかは、SHA-256、SHA-384、SHA-512の中から選ぶことができる。
例えばSHA-384をハッシュとして使う場合のintegrity属性の値は以下のコマンドで求めることができる。

echo sha384-"$(openssl dgst -sha384 -binary bootstrap.min.js | openssl base64 -A)"

わざわざローカルにファイルをダウンロードするのが面倒なら以下のようなコマンドも使える。

# Wget版
echo sha384-"$(wget -nv -O - https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js | openssl dgst -sha384 -binary | openssl base64 -A)"

# cURL版
echo sha384-"$(curl -s -S -f https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js | openssl dgst -sha384 -binary | openssl base64 -A)"

コマンドを打つのも面倒なら以下のサイトを使うことができる。
SRI Hash Generator

ブラウザの対応状況

Subresource Integrityが有効に働くためにはユーザがSubresource Integrityを実装したブラウザを使っている必要がある。
[4]によれば、この記事執筆時のブラウザの対応状況は、Chrome 45以上、Firefox 43以上、Opera 32以上。
まだ仕様が策定段階なので[2]、IEなどは実装していない。

以下のサイトを使うことで、あなたのブラウザがSubresource Integrityをサポートしているかどうかについては確認することができる。
Subresource Integrity

フォールバック

ファイルが改竄されていた場合、そのファイルはロードされないのでサイトの表示が崩れることになる。
JavaScriptについては以下のようなフォールバック策があるようだ[5]

<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"
        integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS"
        crossorigin="anonymous"></script>
<script>window.jQuery.fn.modal || document.write('<script src="bootstrap.min.js"><\/script>')</script>

CSSについては以下のようなフォールバック策があるようだ[6]

<link rel="stylesheet"
      href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"
      integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7"
      crossorigin="anonymous">
<script>
for (var i = 0; i < document.styleSheets.length; i++) {
    var sheet = document.styleSheets[i];
    if (sheet.href == "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css") {
        var rules = sheet.rules ? sheet.rules : sheet.cssRules;
        if (rules.length == 0) {
            var link = document.createElement("link");
            link.setAttribute("rel", "stylesheet");
            link.setAttribute("href", "bootstrap.min.css");
            document.getElementsByTagName("head")[0].appendChild(link);
        }
    }
}
</script>

まとめ

書いておいて損は無いので今からでもintegrity属性とcrossorigin属性を書いておきましょう。

References

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
63
Help us understand the problem. What are the problem?