Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
63
Help us understand the problem. What is going on with this article?

More than 5 years have passed since last update.

@anqooqie

[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

63
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
63
Help us understand the problem. What is going on with this article?