SNSボタンが表示されない＆GoogleAnalytics（GAタグ）が動かない時はContent-Security-Policyの設定を確認する


# SNSのボタンが表示されない

テスト環境はちゃんと**TwitterやらLINEのシェアボタン**が表示されてたのに本番環境(WindowsサーバーIIS)へ上げると表示されない問題が発生。
→ ブラウザのコンソールを見てみると

```console
Refused to load the script 'https://platform.twitter.com/widgets.js' because it violates the following Content Security Policy directive: "script-src 'self' 'unsafe-inline' 'unsafe-eval'". Note that 'script-src-elem' was not explicitly set, so 'script-src' is used as a fallback.

(index):1 Refused to load the script 'https://d.line-scdn.net/r/web/social-plugin/js/thirdparty/loader.min.js' because it violates the following Content Security Policy directive: "script-src 'self' 'unsafe-inline' 'unsafe-eval'". Note that 'script-src-elem' was not explicitly set, so 'script-src' is used as a fallback.
```

やら

```console
Refused to load the script 'https://www.google-analytics.com/analytics.js' because it violates the following Content Security Policy directive: "script-src 'self' 'unsafe-inline' 'unsafe-eval' platform.twitter.com d.line-scdn.net www.googletagmanager.com". Note that 'script-src-elem'  was not explicitly set, so 'script-src' is used as a fallback.
```

やらのエラーが出てました。
パッと見、**外部のJSが読み込めてない**ぽい

# Google翻訳


```
スクリプト「https://platform.twitter.com/widgets.js」の読み込みを拒否しました。コンテンツセキュリティポリシーのディレクティブ "script-src 'self' 'unsafe-inline' 'unsafe-eval'"に違反しています。 'script-src-elem'は明示的に設定されていないため、 'script-src'がフォールバックとして使用されます。

（index）：1スクリプト 'https://d.line-scdn.net/r/web/social-plugin/js/thirdparty/loader.min.js'の読み込みを拒否しました。次のコンテンツセキュリティポリシーのディレクティブに違反しています "：" script-src 'self' '安全でないインライン' 'unsafe-eval' " 'script-src-elem'は明示的に設定されていないため、 'script-src'がフォールバックとして使用されます。
```

```
次のコンテンツセキュリティポリシーの指令に違反しているため、スクリプト「https://www.google-analytics.com/analytics.js」の読み込みを拒否しました：「script-src 'self' 'unsafe-inline' 'unsafe-eval'プラットフォーム .twitter.com d.line-scdn.net www.googletagmanager.com "＃：。 'script-src-elem'は明示的に設定されていないため、 'script-src'がフォールバックとして使用されます。
```

どうやら**コンテンツセキュリティポリシー（Content-Security-Policy）**とやらに違反してるぽい

# 調査

> HTTP の Content-Security-Policy レスポンスヘッダーは、ウェブサイト管理者が、あるページにユーザーエージェントが読み込みを許可されたリソースを管理できるようにします。いくつかの例外を除いて、大半のポリシーにはサーバーオリジンとスクリプトエンドポイントの指定を含んでいます。これはクロスサイトスクリプティング攻撃 (XSS) を防ぐのに役立ちます。

引用：[Content-Security-Policy - HTTP | MDN](https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/Content-Security-Policy)

どうやら**HTTPヘッダ**に問題があるぽい

# web.configの調整

`web.config`を開いて以下`Content-Security-Policy`の部分、`script-src`と`img-src`と`frame-src`にポリシー違反として出てきたURLを追加（＝こいつらは読み込んでいいというリスト）をすればちゃんと表示されるようになりました。

**Twitterボタン**：
**`platform.twitter.com`**を`script-src`と`img-src`と`frame-src`に、
**`syndication.twitter.com`**を`img-src`に追加

**LINEボタン**：
**`d.line-scdn.net`**を`script-src`、
**`social-plugins.line.me`**を`frame-src`にそれぞれ追加

**Facebookボタン**：
**`connect.facebook.net`**を`script-src`、
**`staticxx.facebook.com`と`www.facebook.com`**を`frame-src`にそれぞれ追加

**GoogleAnalytics**：
**`www.googletagmanager.com`**と**`www.google-analytics.com`**を`script-src`へ、
**`www.google-analytics.com`**を`img-src`へ追加


```xml:web.config
<httpProtocol>
    <customHeaders>
        <clear />
        <add name="X-Frame-Options" value="SAMEORIGIN"/>
        <add name="Strict-Transport-Security" value="max-age=31536000"/>
        <add name="Content-Security-Policy" value="default-src 'self'; 
        script-src 'self' 'unsafe-inline' 'unsafe-eval' platform.twitter.com d.line-scdn.net www.googletagmanager.com www.google-analytics.com connect.facebook.net; 
        frame-src 'self' platform.twitter.com social-plugins.line.me staticxx.facebook.com www.facebook.com; 
        style-src 'self' 'unsafe-inline'; 
        img-src 'self' data: platform.twitter.com syndication.twitter.com www.google-analytics.com; 
        font-src 'self'; 
        " />
        <add name="X-XSS-Protection" value="1; mode=block"/>
        <add name="X-Content-Type-Options" value="nosniff"/>
    </customHeaders>
</httpProtocol>
```

以下各項目

**script-src**：JavaScript に対して有効なソースを指定する
**img-src** : 画像やfaviconに対して有効なソースを定義する
**frame-src**：`<frame>`や`<iframe>`のような要素によってロードされる入れ子状のコンテンツの閲覧に対して有効なソースを指定する

そのほかは以下参照

 - [Content-Security-Policy - HTTP | MDN](https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/Content-Security-Policy#Directives)


# ついでに他の設定も確認しておく

## X-Frame-Options

> HTTP の X-Frame-Options レスポンスヘッダーは、ブラウザーがページを `<frame>`, `<iframe>`, `<object>` の中に表示することを許可するかどうかを示すために使用されます。サイトはコンテンツが他のサイトに埋め込まれないよう保証することで、クリックジャッキング攻撃を防ぐためにこれを使用することができます。
> 
> 強化されたセキュリティは、ユーザーが X-Frame-Options に対応したブラウザーを使用して文書にアクセスした場合のみ提供されます。

引用：[X-Frame-Options - HTTP | MDN](https://developer.mozilla.org/ja/docs/Web/HTTP/X-Frame-Options)

### 設定値
`value="SAMEORIGIN"`
> `SAMEORIGIN`　ページは同じオリジンのページに含まれるページのフレーム内でのみ表示されます。

## Strict-Transport-Security

> HTTP の Strict-Transport-Security レスポンスヘッダー (しばしば HSTS と略されます) は、ウェブサイトがブラウザーに HTTP の代わりに HTTPS を用いて通信を行うよう指示するためのものです。

引用：[Strict-Transport-Security - HTTP | MDN](https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/Strict-Transport-Security)

### 設定値

> `max-age=<expire-time>`　秒単位で、そのサイトに HTTPS だけで接続することをブラウザーが記憶する時間です。

`value="max-age=31536000"`：1年間設定

## X-XSS-Protection

> HTTP の X-XSS-Protection レスポンスヘッダーは Internet Explorer, Chrome, Safari の機能で、反射したクロスサイトスクリプティング (XSS) 攻撃を検出したときに、ページの読み込みを停止するためのものです。強い Content-Security-Policy をサイトが実装して、インライン JavaScript の使用を無効にしていれば ('unsafe-inline')、現在のブラウザーではこれらの防御は大枠で不要なものですが、まだ CSP に対応していない古いウェブブラウザーを使用しているユーザーには防御になります。

引用：[X-XSS-Protection - HTTP | MDN](https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/X-XSS-Protection)

### 設定値
`value="1; mode=block"`
> `1; mode=block`　XSS フィルタリングを有効化します。攻撃を検知すると、ページをサニタイジングするよりも、ページのレンダリングを停止します。

## X-Content-Type-Options

> The X-Content-Type-Options response HTTP header is a marker used by the server to indicate that the MIME types advertised in the Content-Type headers should not be changed and be followed. This allows to opt-out of MIME type sniffing, or, in other words, it is a way to say that the webmasters knew what they were doing.
> 
> This header was introduced by Microsoft in IE 8 as a way for webmasters to block content sniffing that was happening and could transform non-executable MIME types into executable MIME types. Since then, other browsers have introduced it, even if their MIME sniffing algorithms were less aggressive.
> 
> Site security testers usually expect this header to be set.

（まだ翻訳されてないみたいです）
引用：[X-Content-Type-Options - HTTP | MDN](https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/X-Content-Type-Options)

なので以下参考

引用：[セキュリティを強化する7つの便利なHTTPヘッダ](https://devcentral.f5.com/articles/7http)

> 　Webブラウザは本来、サーバから送られてきたHTTPレスポンスに記述されている「Content-Type」に基づいて、HTTPレスポンスをどのように処理するのかを決定します。 　例えば「Content-Type:text/plain」であれば、Webブラウザはこれをテキストとして扱い、レスポンスの中にスクリプト記述があってもスクリプトとしては実行しません。しかしWebブラウザの中には、HTTPレスポンス全体を検査（sniffing）してコンテンツ タイプを判断し、「Content-Type」を無視した動作を行うものも存在します。このような実装はWebアプリケーション開発者の意図しない動作を引き起こし、セキュリティ上の問題につながると指摘されてきました。このsniffingを防止するのが「X-Content-Type-Options」です。「X-Content-Type-Options : nosniff」とすることでsniffingをやめさせ、「Content-Type」に合致しない動作を回避できます。
> 
> 　また以下のヘッダもセキュリティ強化に役立ちますが、実際に利用した際に問題が発生しないかどうか、慎重に検討する必要があります。

### 設定値

`value="nosniff"`
> `value="nosniff"` sniffingをやめさせ、「Content-Type」に合致しない動作を回避できます

# おわり

- ネット上にあまり情報がなくて困ったので残しておきます