SRIとCSPの違い

# 比較
## 結論

||SRI|CSP|
|:--------------|---|----|
|目的|外部リソースの改ざん検知|Webコンテンツに関するセキュリティポリシー定義|
|詳細|意図したリソースを使っていることを保証|意図したセキュリティレベルでリソースを扱っていることを保証|
|セキュリティ上の意図|XSS対策|・XSS対策<br/>・コンテンツインジェクション|
|対象|・`link`<br/> ・`script`|Webコンテンツを対象。<br />正確な定義は[ディレクティブ](https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/Content-Security-Policy#directives)参照。| 
|定義単位|リソース|ページ|
|制御単位|リソース|・スキーマ(schema-source)<br/>・ホスト(host-source)<br/>・キーワード(keyword-source)<br/>・リソース(hash-source)<br/>・リクエスト(nonce-source)|
|MDN|[link](https://developer.mozilla.org/ja/docs/Web/Security/Subresource_Integrity)|[link](https://developer.mozilla.org/ja/docs/Web/HTTP/CSP)|
|W3C|[link](https://w3c.github.io/webappsec-subresource-integrity/)|・[CSP version2](https://www.w3.org/TR/CSP2/)<br/>・[CSP version3(working draft)](https://www.w3.org/TR/CSP3/)|

## 比較の動機
CSPのポリシー定義の方法はいくつかあるが、その一つに`hash-source`によるJavaScriptの許容がある。
これはSRIの`hash-source`の考え方と全く同じで、ハッシュアルゴリズム＋ハッシュ値の文字列を以ってJavaScriptの動作を許容するものである。
これが似ていた（というか部分的には同じ）ので改めて棚卸ししてみた。

結果的には、`hash-source`部分に関しては、SRIのW3CからCSPのW3Cへ参照があり、同一のものを指していた。
が、CSPのversion2における`hash-source`の対象はあくまでHTML内のインラインスクリプトに限定されている。CSPのversion3では、インラインスクリプトの他、外部リソースも対象にすることが可能となる。[^1]

* SRIは、`hash-source`をベースに改ざん検知・実行抑止を行う
* CSPは、オリジンベースや`hash-source`ベース、など制御の範囲を選択可能。`hash-source`は、インラインスクリプト限定で対象とすることが可能。CSP3ではSRIの`hash-source`とほぼ同じ動きになる。

----
詳細は以下参照。

# 定義
## SRI（サブリソース完全性）
### W3C
https://w3c.github.io/webappsec-subresource-integrity/

### MDN
https://developer.mozilla.org/ja/docs/Web/Security/Subresource_Integrity

### 概要
ブラウザの機構である。MDNを見れば分かるが、IEは対応していない。
外部リソースの完全性を担保するための仕組みである。
`src`属性を持つようなタグ（`link`,`script`）で`integrity`属性にソース由来のハッシュ値を付加し、
ブラウザにて、改ざんされている疑いがある場合、そのリソースファイルは利用できない。

### 対象
* `link`
* `script`

> この2つのみ？

### 利用シーン
* CDN経由でJSライブラリやスタイルシートなどを利用する場合
* 異なるオリジンからJSライブラリやスタイルシートを利用する場合

### 防ぐ攻撃
* XSS（クロスサイトスクリプティング）

### 詳細
制御単位は、タグ単位。
対象のリソースファイルの内容をハッシュ化した文字列をBase64エンコードし、その先頭にハッシュ計算アルゴリズムを付けたものを該当タグの`integrity`属性に設定する。

`crossorigin`属性は、リソースの取得の際に、認証情報を併せて送るかを制御する。
`anonymous`は[認証情報](https://fetch.spec.whatwg.org/#credentials)を送らない。
`use-credentials`は[認証情報](https://fetch.spec.whatwg.org/#credentials)を送る。
ここで語られている認証情報は、https://fetch.spec.whatwg.org/#credentials で定義されている。

> リソース提供ホストが認証不要でアクセス可能なら、`anonymous`

#### 例
以下はBootstrapの公式よりCDNからJSをダウンロードする際の記述。
`integrity`属性には、`sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW`とあり、これがハッシュ計算アルゴリズムと計算結果のBase64エンコードした値である。

```
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.bundle.min.js" 
    integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW" 
    crossorigin="anonymous"></script>
```

## CSP
### W3C
https://www.w3.org/TR/CSP3/

### MDN
https://developer.mozilla.org/ja/docs/Web/HTTP/CSP

割と膨大なのでかいつまんで記載。

### 概要
> W3Cの序文が分かりやすい（機械翻訳）ので、そのまま。

:::note info
このドキュメントでは、開発者がさまざまな方法でアプリケーションをロックダウンし、クロスサイトスクリプティングなどのコンテンツインジェクションの脆弱性のリスクを軽減し、アプリケーションの実行特権を減らすために使用できるツールであるコンテンツセキュリティポリシー（CSP）を定義します。

CSPは、コンテンツインジェクションの脆弱性に対する最初の防衛線として意図されたものではありません。代わりに、CSPは多層防御として最適に使用されます。悪意のあるインジェクションが引き起こす可能性のある害を軽減しますが、注意深い入力検証と出力エンコーディングの代わりにはなりません。

このドキュメントは、コンテンツセキュリティポリシーレベル2の反復であり、一方ではCSP、HTML、およびFetch間の相互作用をより明確に説明し、他方ではモジュールの拡張性のための明確なフックを提供することを目的としています。理想的には、これにより、新しい機能を構築できる安定したコアが形成されます。
:::

ブラウザの機構である。
XSS 攻撃の軽減と報告を第一目的とする。
ポリシーに準拠しないコンテンツは、実行時にエラーとなり動作しない。
実行しないがポリシー違反している場合は、ブラウザのデバッグツール上にアラートが上がる。
これ以外に指定したエンドポイントを定義しているとブラウザから違反情報の送信が可能でこれが[違反報告](https://developer.mozilla.org/ja/docs/Web/HTTP/CSP#enabling_reporting)という機能。

> どうもブラウザとは初期状態がなんでも行えすぎる特権状態であるという観点があるように感じる。
CSPはこれを適切な許容範囲に閉じて制御するための機構、というように思える。

### 対象
[ディレクティブ](https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/Content-Security-Policy#directives)を参照。
SRIと違い、ほぼすべてのリソースを対象にすることが可能。

### 利用シーン
* ページごとにJS実行時のセキュリティレベルを制御したい場合
* CSPレポートを受信することでセキュリティ監視を強化したい場合

> 開発時に適宜開発者コンソールでチェック可能だが、レポートするエンドポイントを建てておけば割と便利？

### 防ぐ攻撃
* XSS（クロスサイトスクリプティング）
* データ注入

### 詳細
制御単位はリソース単位まで選択可能だが、定義単位はページ単位になる。
主たるHTMLページのレスポンスヘッダー（`Content-Security-Policy`）もしくは`meta`タグにて定義・返却することで、ブラウザ上で動作する。


[^1]: https://triple-underscore.github.io/CSP3-ja.html#external-hash