Slide 1

Slide 1 text

Content Security Policy入門
 セキュリティ設定と
 違反レポートのはじめ方
 uskey512 / Yusuke Uehara @JJUG CCC 2024 Fall 2024-10-27

Slide 2

Slide 2 text

自己紹介
 
 @uskey512 / Yusuke Uehara
 STORES 株式会社 決済グループ所属
 バックエンド7年/フロントエンド1年弱
 開発したり、監査対応したり
 2

Slide 3

Slide 3 text

発表のきっかけ・モチベーション
 PCI DSSという監査基準の大幅アップデート(v3.2.1->v4.0.1)
 フロントエンドセキュリティとより一層向き合う必要が出てきた
 一部要件の対応でContent Security Policy(CSP)を導入
 ⬇⬇⬇
 CSPのキャッチアップ・導入・運用を通じてその良さが少しずつわかってきた
 あまり普及していないが、普及するとセキュリティ的に良いのでは🤔
 
 
 3

Slide 4

Slide 4 text

本発表の主なターゲット・ゴール
 主なターゲット
 ● フロントエンドやセキュリティに興味のあるバックエンドエンジニア
 ● 運営しているサービスのセキュリティが気になっているエンジニア
 本発表では皆さんが20分で以下の状態になるための情報を提供します
 ● CSPの基礎がわかる
 ● CSPの導入方法と動作イメージがわかる
 ● CSPのレポート運用と既存サイトへの導入に向けた手順がわかる
 4

Slide 5

Slide 5 text

目次
 ● CSPの基礎
 ○ CSPの基本概念
 ○ CSPの構造・ポリシーディレクティブ 
 ● CSPの導入方法と構成
 ○ サイトの構成にあわせたCSPの導入方法 
 ○ CSPの構成例と動作イメージ 
 ● CSPのレポート運用と既存サイトへの導入に向けた手順
 ○ CSP Report-Only 構成例 
 ○ CSP違反レポートの読み方と実際のCSP違反レポート 
 ○ より良い運用と、既存サイトへの段階的な導入手順 
 5

Slide 6

Slide 6 text

目次
 ● CSPの基礎 
 ○ CSPの基本概念 
 ○ CSPの構造・ポリシーディレクティブ 
 ● CSPの導入方法と構成
 ○ サイトの構成にあわせたCSPの導入方法 
 ○ CSPの構成例と動作イメージ 
 ● CSPのレポート運用と既存サイトへの導入に向けた手順
 ○ CSP Report-Only 構成例 
 ○ CSP違反レポートの読み方と実際のCSP違反レポート 
 ○ より良い運用と、既存サイトへの段階的な導入手順 
 6

Slide 7

Slide 7 text

Content Security Policy (CSP) とは何か
 MDN Web Docs での説明
 
 
 
 
 
 
 
 コンテンツセキュリティポリシー (CSP) は、クロスサイトスクリプティング (Cross-site_scripting) やデータインジェクション攻撃などのような、特定の種類の攻 撃を検知し、影響を軽減するために追加できるセキュリティレイヤーです。 これらの攻 撃はデータの窃取からサイトの改ざん、マルウェアの拡散に至るまで、様々な目的に 用いられます。 https://developer.mozilla.org/ja/docs/Web/HTTP/CSP 7

Slide 8

Slide 8 text

Content Security Policy (CSP) とは何か
 MDN Web Docs での説明
 
 
 
 
 
 
 = Webブラウザに対して制限・許可したいことを伝える仕組み
 コンテンツセキュリティポリシー (CSP) は、クロスサイトスクリプティング (Cross-site_scripting) やデータインジェクション攻撃などのような、特定の種類の攻 撃を検知し、影響を軽減するために追加できるセキュリティレイヤーです。 これらの攻 撃はデータの窃取からサイトの改ざん、マルウェアの拡散に至るまで、様々な目的に 用いられます。 https://developer.mozilla.org/ja/docs/Web/HTTP/CSP 8

Slide 9

Slide 9 text

Content Security Policy (CSP) とは何か
 Webブラウザに対して制限・許可したいことを伝える仕組み
 
 具体的に何ができるか?
 ● リソースの種別毎に取得や読み込み先をホワイトリストで許可
 ● Webブラウザの挙動を制限
 
 
 
 
 
 
 
 
 9

Slide 10

Slide 10 text

Content Security Policy (CSP) とは何か
 Webブラウザに対して制限・許可したいことを伝える仕組み
 
 具体的に何ができるか?
 ● リソースの種別毎に取得や読み込み先をホワイトリストで許可
 ● Webブラウザの挙動を制限
 
 ウェブサイトに対する一般的な攻撃の一例
 
 
 
 
 
 
 10

Slide 11

Slide 11 text

Content Security Policy (CSP) とは何か
 Webブラウザに対して制限・許可したいことを伝える仕組み
 
 具体的に何ができるか?
 ● リソースの種別毎に取得や読み込み先をホワイトリストで許可
 ● Webブラウザの挙動を制限
 
 ウェブサイトに対する一般的な攻撃の一例
 ● Webページを何らかの方法で書き換えて…
 
 
 
 
 
 11

Slide 12

Slide 12 text

Content Security Policy (CSP) とは何か
 Webブラウザに対して制限・許可したいことを伝える仕組み
 
 具体的に何ができるか?
 ● リソースの種別毎に取得や読み込み先をホワイトリストで許可
 ● Webブラウザの挙動を制限
 
 ウェブサイトに対する一般的な攻撃の一例
 ● Webページを何らかの方法で書き換えて…
 ○ あやしいサーバにformの内容を送信
 ○ あやしいプラグインを読み込ませて脆弱性を利用
 ○ あやしいスクリプトを実行
 
 
 12

Slide 13

Slide 13 text

Content Security Policy (CSP) とは何か
 Webブラウザに対して制限・許可したいことを伝える仕組み
 
 具体的に何ができるか?
 ● リソースの種別毎に取得や読み込み先をホワイトリストで許可
 ● Webブラウザの挙動を制限
 
 ウェブサイトに対する一般的な攻撃の一例
 ● Webページを何らかの方法で書き換えて…
 ○ あやしいサーバにformの内容を送信
 ○ あやしいプラグインを読み込ませて脆弱性を利用
 ○ あやしいスクリプトを実行
 ■ データの窃取 (例 : カード情報・認証情報など)
 
 13

Slide 14

Slide 14 text

Content Security Policy (CSP) とは何か
 Webブラウザに対して制限・許可したいことを伝える仕組み
 
 具体的に何ができるか?
 ● リソースの種別毎に取得や読み込み先をホワイトリストで許可
 ● Webブラウザの挙動を制限
 
 ウェブサイトに対する一般的な攻撃の一例
 ● Webページを何らかの方法で書き換えて…
 ○ あやしいサーバにformの内容を送信
 ○ あやしいプラグインを読み込ませて脆弱性を利用
 ○ あやしいスクリプトを実行
 ■ データの窃取 (例 : カード情報・認証情報など)
 ➡ これらのリスクを防げる (リスクを軽減する)
 14

Slide 15

Slide 15 text

Content Security Policy (CSP) とは何か
 Webブラウザに対して制限・許可したいことを伝える仕組み
 
 どのようにCSPを適用するか?
 サーバ側からコンテンツを返す際のHTTP レスポンスヘッダに設定
 (またはhtmlファイル内のタグ内に記載)
 
 
 
 
 
 
 
 
 15 https://a.example.com 
 Web ブラウザ

Slide 16

Slide 16 text

Content Security Policy (CSP) とは何か
 Webブラウザに対して制限・許可したいことを伝える仕組み
 
 どのようにCSPを適用するか?
 サーバ側からコンテンツを返す際のHTTP レスポンスヘッダに設定
 (またはhtmlファイル内のタグ内に記載)
 
 
 
 
 
 
 
 
 
 16 https://a.example.com 
 Web ブラウザ HTTP Request

Slide 17

Slide 17 text

HTTP Response Content Security Policy (CSP) とは何か
 Webブラウザに対して制限・許可したいことを伝える仕組み
 
 どのようにCSPを適用するか?
 サーバ側からコンテンツを返す際のHTTP レスポンスヘッダに設定
 (またはhtmlファイル内のタグ内に記載)
 
 
 
 
 
 
 
 
 17 https://a.example.com 
 Web ブラウザ index
 .html
 HTTP Request

Slide 18

Slide 18 text

Content Security Policy (CSP) とは何か
 Webブラウザに対して制限・許可したいことを伝える仕組み
 
 どのようにCSPを適用するか?
 サーバ側からコンテンツを返す際のHTTP レスポンスヘッダに設定
 (またはhtmlファイル内のタグ内に記載)
 
 
 
 
 
 
 
 
 18 https://a.example.com 
 Web ブラウザ index
 .html
 Content-Security-Policy: script-src a.example.com; HTTP Request HTTP Response HTTP Response Header

Slide 19

Slide 19 text

CSPの基本構成
 ポリシーの設定例
 scriptはa.example.comからのみ取得可、imageは無制限に取得可 (未設定)
 
 
 
 
 Content-Security-Policy: script-src a.example.com; 19

Slide 20

Slide 20 text

CSPの基本構成
 Web ブラウザ ポリシーの設定例
 scriptはa.example.comからのみ取得可、imageは無制限に取得可 (未設定)
 
 
 
 
 
 
 
 Content-Security-Policy: script-src a.example.com; index
 .html
 https://a.example.com 
 https://a.example.com 
 https:// b.example.com 
 .js
 .png
 .js
 .png
 20

Slide 21

Slide 21 text

CSPの基本構成
 Web ブラウザ ポリシーの設定例
 scriptはa.example.comからのみ取得可、imageは無制限に取得可 (未設定)
 
 
 
 
 
 
 
 Content-Security-Policy: script-src a.example.com; index
 .html
 https://a.example.com 
 https://a.example.com 
 https:// b.example.com 
 .js
 .png
 .js
 .png
 21

Slide 22

Slide 22 text

CSPの基本構成
 Web ブラウザ ポリシーの設定例
 scriptはa.example.comからのみ取得可、imageは無制限に取得可 (未設定)
 
 
 ポリシーディレクティブ(または単にディレクティブ)
 と呼ばれる単位でルールを列挙して設定していく
 
 
 
 
 Content-Security-Policy: script-src a.example.com; index
 .html
 https://a.example.com 
 https://a.example.com 
 https:// b.example.com 
 .js
 .png
 .js
 .png
 22

Slide 23

Slide 23 text

CSPの基本構成
 Web ブラウザ ポリシーの設定例
 scriptはa.example.comからのみ取得可、imageは無制限に取得可 (未設定)
 
 
 ポリシーディレクティブ(または単にディレクティブ)
 と呼ばれる単位でルールを列挙して設定していく
 
 各ディレクティブは対象をホワイトリストで指定し
 指定されていないリソースには影響しない
 
 
 Content-Security-Policy: script-src a.example.com; index
 .html
 https://a.example.com 
 https://a.example.com 
 https:// b.example.com 
 .js
 .png
 .js
 .png
 23

Slide 24

Slide 24 text

CSPの基本構成
 Web ブラウザ ポリシーの設定例
 scriptはa.example.comからのみ取得可、imageは無制限に取得可 (未設定)
 
 
 ポリシーディレクティブ(または単にディレクティブ)
 と呼ばれる単位でルールを列挙して設定していく
 
 各ディレクティブは対象をホワイトリストで指定し
 指定されていないリソースには影響しない
 
 CSPの影響範囲はレスポンス単位
 この例ではindex.htmlのみ
 Content-Security-Policy: script-src a.example.com; index
 .html
 https://a.example.com 
 https://a.example.com 
 https:// b.example.com 
 .js
 .png
 .js
 .png
 24

Slide 25

Slide 25 text

ディレクティブの種別
 MDN Web Docs で記載されているディレクティブは30種類弱
 4分類に分けられる
 
 ● Fetch Directive
 ○ リソース種別の読み込みを制御する 
 ● Document Directive
 ○ ドキュメントの状態に対する操作を制御する
 ● Navigation Directive
 ○ フォームの送信やナビゲーションを制御する
 ● Reporting Directive
 ○ CSP違反が起きた際の挙動を制御する
 25

Slide 26

Slide 26 text

ディレクティブの一覧 (一部省略)
 
 
 
 26 Policy Directive Fetch Directive Report Directive Navigation Directive Document Directive report-uri report-to form-action frame-ancestors base-uri sandbox default-src connect-src child-src img-src frame-src font-src worker-src media-src script-src object-src script-src-elem manifest-src script-src-attr prefetch-src style-src style-src-elem style-src-attr

Slide 27

Slide 27 text

ディレクティブのフォールバック
 ディレクティブには親子関係があり、特定のディレクティブが指定されない場合
 フォールバック先のディレクティブの値が参照されるものがある
 
 例:以下の2つのポリシーは等価
 27 Content-Security-Policy: default-src 'self'; script-src other.example.com; Content-Security-Policy: connect-src 'self'; child-src 'self'; style-src 'self'; media-src 'self'; font-src 'self'; object-src 'self'; connect-src 'self'; prefetch-src 'self'; manifest-src 'self'; script-src other.example.com;

Slide 28

Slide 28 text

ディレクティブのフォールバック
 28 default-src connect-src font-src img-src prefetch-src object-src media-src manifest-src child-src script-src script-src-attr script-src-elem worker-src style-src style-src-attr style-src-elem frame-src 凡例 直接設定されたディレクティブ 影響を受けるディレクティブ

Slide 29

Slide 29 text

ディレクティブのフォールバック
 29 default-src connect-src font-src img-src prefetch-src object-src media-src manifest-src child-src script-src script-src-attr script-src-elem worker-src style-src style-src-attr style-src-elem frame-src 凡例 直接設定されたディレクティブ 影響を受けるディレクティブ

Slide 30

Slide 30 text

ディレクティブのフォールバック
 30 default-src connect-src font-src img-src prefetch-src object-src media-src manifest-src child-src script-src script-src-attr script-src-elem worker-src style-src style-src-attr style-src-elem frame-src 凡例 直接設定されたディレクティブ 影響を受けるディレクティブ

Slide 31

Slide 31 text

ディレクティブのフォールバック
 31 default-src connect-src font-src img-src prefetch-src object-src media-src manifest-src child-src script-src script-src-attr script-src-elem worker-src style-src style-src-attr style-src-elem frame-src 凡例 直接設定されたディレクティブ 影響を受けるディレクティブ

Slide 32

Slide 32 text

目次
 ● CSPの基礎
 ○ CSPの基本概念
 ○ CSPの構造・ポリシーディレクティブ 
 ● CSPの導入方法と構成 
 ○ サイトの構成にあわせたCSPの導入方法 
 ○ CSPの構成例と動作イメージ 
 ● CSPのレポート運用と既存サイトへの導入に向けた手順
 ○ CSP Report-Only 構成例 
 ○ CSP違反レポートの読み方と実際のCSP違反レポート 
 ○ より良い運用と、既存サイトへの段階的な導入手順 
 32

Slide 33

Slide 33 text

CSPの導入方法
 CSPについて、その構成や動作・種類などが理解できた
 
 各サイトへの導入にあたっては
 CSPポリシーをHTTPレスポンスヘッダに設定する仕組み上
 導入するサイトの構成で設定方法が異なる
 
 2つの構成について導入方法を紹介
 ● 1. バックエンド/フロントエンドが分離していないMPA
 ● 2. フロントエンドが分離していてCDNを経由して配布されているSPA
 33

Slide 34

Slide 34 text

CSPの導入方法 - MPA (Spring Security) - 1
 バックエンドとフロントエンドの実装が分かれていない
 バックエンドアプリケーションがhtmlを直接配布するようなMPA
 アプリケーション内でHTTPレスポンスヘッダを設定する
 
 
 
 
 
 
 Spring Boot x Thymeleaf の1台構成のような構成
 Spring Securityの機能でCSPを設定することができる
 34 Web ブラウザ サーバー リクエスト レスポンス

Slide 35

Slide 35 text

CSPの導入方法 - MPA (Spring Security) - 2
 Spring Securityでの設定例
 
 
 35 @Configuration @EnableWebSecurity public class WebSecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http // ... .headers(headers -> headers .contentSecurityPolicy(csp -> csp .policyDirectives("script-src 'self'; object-src 'src';") ) ); return http.build(); } }

Slide 36

Slide 36 text

CSPの導入方法 - MPA (Spring Security) - 3
 Spring Securityでの設定例
 
 
 36 @Configuration @EnableWebSecurity public class WebSecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http // ... .headers(headers -> headers .contentSecurityPolicy(csp -> csp .policyDirectives("script-src 'self'; object-src 'src';") ) ); return http.build(); } } 文字列でヘッダ名を除いたポリシー全体を渡すだけ

Slide 37

Slide 37 text

CSPの導入方法 - SPA (CDN CloudFront) - 1
 バックエンドとフロントエンドが分離していてAPIで通信をしている場合
 フロントエンドのhtmlファイルを配布する側で設定を行う
 
 
 
 
 
 
 
 例えばCDNでindex.htmlや各種jsファイルを配布している場合
 CDN側のHTTPレスポンスヘッダの設定にCSPを設定する
 37 Web ブラウザ API サーバー CDN 静的リソースの取得は CDN (index.html, *.js, *.css) 静的リソース以外の取得、 API通信 (Fetch, XMLHttpRequest 等) は CDN経由 または 直接APIサーバーに

Slide 38

Slide 38 text

CSPの導入方法 - SPA (CDN CloudFront) - 2
 AWS CloudFrontの場合
 CloudFront > ポリシー > レスポンスヘッダ > レスポンスヘッダポリシー
 38

Slide 39

Slide 39 text

CSPの動作確認
 様々な外部リソースを読み込むページを作成して
 その通信をCSPでブロックする/しないの2パターンを評価
 
 読み込む外部リソースは
 画像・動画・音声・フォント・スタイル・外部スクリプト
 GitHub APIの利用など
 
 CSPが動作するときにどのような挙動を取るか確認する
 39

Slide 40

Slide 40 text

CSPの動作確認 - 1
 様々な外部リソースを読み込むページ
 
 
 
 
 
 
 
 
 
 
 https://uskey512.github.io/csp-sample/csp-disable.html 
 
 画像・動画・音声・フォント・スタイル
 外部スクリプト、GitHub APIの利用など
 40

Slide 41

Slide 41 text

CSPの動作確認 - 2
 様々な外部リソースを読み込 めない ページ
 
 
 
 
 
 
 
 
 
 
 https://uskey512.github.io/csp-sample/csp-enable.html 
 
 
 
 
 41 Content-Security-Policy: default-src 'self';

Slide 42

Slide 42 text

CSPによって通信が制限されている
 CSPの動作確認 - 3
 42 Web ブラウザ index
 .html
 .css
 .jpg
 .js
 .ttf
 .wav
 GitHub
 API


Slide 43

Slide 43 text

CSPを安全に導入したい
 最終的にCSPを導入したいが…
 
 
 
 
 
 
 
 
 
 
 
 43

Slide 44

Slide 44 text

CSPを安全に導入したい
 最終的にCSPを導入したいが…
 
 ● 本番環境への導入にハードルがある
 ○ 通信が意図せず制御されてしまうと何かが壊れる = 障害 
 
 
 
 
 
 
 
 
 44

Slide 45

Slide 45 text

CSPを安全に導入したい
 最終的にCSPを導入したいが…
 
 ● 本番環境への導入にハードルがある
 ○ 通信が意図せず制御されてしまうと何かが壊れる = 障害 
 
 ● ポリシー作成が難しい
 ○ サイトが大規模すぎる
 ○ 読み込まれるリソースとして何があるのか把握できていない 
 
 
 
 
 45

Slide 46

Slide 46 text

CSPを安全に導入したい
 最終的にCSPを導入したいが…
 
 ● 本番環境への導入にハードルがある
 ○ 通信が意図せず制御されてしまうと何かが壊れる = 障害 
 
 ● ポリシー作成が難しい
 ○ サイトが大規模すぎる
 ○ 読み込まれるリソースとして何があるのか把握できていない 
 
 CSPをレポート通知のみで適用する方法がある
 CSPの評価結果をレポート通知だけを行って通信の制御をしない →Content-Security-Policy-Report-Only というヘッダがある
 46

Slide 47

Slide 47 text

目次
 ● CSPの基礎
 ○ CSPの基本概念
 ○ CSPの構造・ポリシーディレクティブ 
 ● CSPの導入方法と構成
 ○ サイトの構成にあわせたCSPの導入方法 
 ○ CSPの構成例と動作イメージ 
 ● CSPのレポート運用と既存サイトへの導入に向けた手順 
 ○ CSP Report-Only 構成例 
 ○ CSP違反レポートの読み方と実際のCSP違反レポート 
 ○ より良い運用と、既存サイトへの段階的な導入手順 
 47

Slide 48

Slide 48 text

Report-Onlyでの運用 - 1
 Report-Only ヘッダでレポート通知だけを行う
 
 既存サイトの機能・表示を壊さず
 作成したポリシーの妥当性を確認しながら確認・調整が行える
 CSPに違反した内容はコンソール・指定したエンドポイントに通知される
 
 これまでの設定内容に加えてレポート運用に必要になるのは
 ● レポート先ヘッダの設定 (Report-To/Reporting-Endpoints)
 ● CSP違反レポートを受け取るサーバ
 48

Slide 49

Slide 49 text

Report-Onlyでの運用 - 2 - ヘッダへの追記 
 違反レポートの送信先をReport-Toヘッダで設定して
 CSPヘッダのreport-toディレクティブで指定
 49 Report-To: { "group": "csp-endpoint", "max_age": 10886400, "endpoints": [ { "url" : "https://a.example.com/csp-reports" } ] } Content-Security-Policy-Report-Only: default-src a.example.com; report-to csp-endpoint; report-uri /csp-reports; ① CSP違反レポート用のグループを定義 ③ 定義したグループを report-to ディレクティブで指定 古いブラウザとの互換性のために report-uriも指定 ② ヘッダをReport-Onlyに変更

Slide 50

Slide 50 text

Report-Onlyでの運用 - 3 - CSP違反レポートの内容
 CSP違反レポートの送信
 CSP違反が発生するとWebブラウザはCSP違反レポートを送信するようになる
 (違反レポートはjson形式でPOSTメソッドで送信される)
 
 違反レポートには下記のような項目が含まれる
 ● document-uri
 ○ 違反が発生したドキュメントのURI
 ● blocked-uri
 ○ 読み込みがブロックされるリソースのURI
 ● violated-directive
 ○ 違反したディレクティブの名前
 50

Slide 51

Slide 51 text

Report-Onlyでの運用 - 4 - CSP違反レポートサーバー
 発生したCSP違反レポートを受け取るためのエンドポイントが必要
 
 監視系のSaaSはCSP違反レポートを受け取るエンドポイントを提供している
 ● Sentry
 ● Datadog
 
 POSTでjson形式のデータを受け取るだけなので
 CSP違反レポートを受け取るエンドポイントを自作しても基本的に問題はない
 
 大量にCSP違反レポートが来ることが想定される場合
 集計や分析を行える仕組みがあった方がその後の運用を進めやすい
 51

Slide 52

Slide 52 text

CSP Report-Onlyの動作確認サイトを作る
 コンテンツ配信を行いCSP違反レポートも受け取るサイトを作る
 
 52 Web ブラウザ サーバー リクエスト レスポンス CSP違反レポート https://github.com/uskey512/csp-sample

Slide 53

Slide 53 text

CSP Report-Onlyの動作確認サイトを作る
 コンテンツ配信を行いCSP違反レポートも受け取るサイトを作る
 ● http://localhost:8080/index 
 ○ htmlファイルをThymeleafで配布
 
 53 Web ブラウザ サーバー リクエスト レスポンス CSP違反レポート https://github.com/uskey512/csp-sample

Slide 54

Slide 54 text

CSP Report-Onlyの動作確認サイトを作る
 コンテンツ配信を行いCSP違反レポートも受け取るサイトを作る
 ● http://localhost:8080/index 
 ○ htmlファイルをThymeleafで配布
 ● http://localhost:8080/api/csp_reports 
 ○ POST で CSP違反レポートを受け取る
 ○ 受け取ったレポートはログに吐き出す
 54 Web ブラウザ サーバー リクエスト レスポンス CSP違反レポート https://github.com/uskey512/csp-sample

Slide 55

Slide 55 text

CSP違反レポートをうけとる - 1 - WebSecurityConfig
 55 @Configuration @EnableWebSecurity public class WebSecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { var cspDirectives = List.of( "default-src 'self'", "report-uri /api/csp_reports" ); http .csrf(AbstractHttpConfigurer::disable) .headers(headers -> headers .contentSecurityPolicy(csp -> csp .policyDirectives(String.join("; ", cspDirectives)) .reportOnly() ) ); return http.build(); } } 'self' 以外をすべて制限 report-uriでCSP違反レポートを 送信するエンドポイントを設定 reportOnly()でReport-Onlyに変更

Slide 56

Slide 56 text

CSP違反レポートをうけとる - 2 - WebConfig
 
 56 @Configuration public class WebConfig implements WebMvcConfigurer { @Override public void configureContentNegotiation(ContentNegotiationConfigurer configurer) { configurer .mediaType("csp-report", MediaType.valueOf("application/csp-report")); } @Override public void configureMessageConverters(List> converters) { // Jacksonを使用するJSON用のHttpMessageConverterにカスタムメディアタイプを追加 MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter(); jsonConverter.setSupportedMediaTypes(List.of( MediaType.APPLICATION_JSON, // 既存のJSON MediaType.valueOf("application/csp-report") // カスタムメディアタイプ )); converters.add(jsonConverter); } } MediaType : "application/csp-report" を 処理出来るように設定を追加 設定しないと415 Unsupported Media Type 発生

Slide 57

Slide 57 text

CSP違反レポートをうけとる - 3 - RestController
 
 57 @RestController @RequestMapping("/api") public class CspReportController { // ... @PostMapping(value = "/csp_reports", consumes = { "application/csp-report" }) public ResponseEntity postCspReport( @RequestBody Object jsonData ) { try { String prettyJson = prettyWriter.writeValueAsString(jsonData); logger.info("Received JSON:\n{}", prettyJson); } catch (Exception e) { logger.error("Error processing JSON", e); return ResponseEntity.badRequest().body("Invalid JSON format"); } // Return a success response return ResponseEntity.ok("JSON received and logged"); } } "application/csp-report"を 処理することを明示

Slide 58

Slide 58 text

CSP Report-Onlyの動作確認 - 1
 58

Slide 59

Slide 59 text

CSP Report-Onlyの動作確認 - 2
 59

Slide 60

Slide 60 text

CSP違反レポートを読む
 60 { "csp-report" : { "document-uri" : "http://localhost:8080/index", "referrer" : "", "violated-directive" : "img-src", "effective-directive" : "img-src", "original-policy" : "default-src 'self'; report-uri /api/csp_reports", "disposition" : "report", "blocked-uri" : "https://upload.wikimedia.org/wikipedia/commons/thumb/6/69/June_odd-eyed-cat_cropped. jpg/512px-June_odd-eyed-cat_cropped.jpg?20120228074717", "line-number" : 20, "source-file" : "http://localhost:8080/index", "status-code" : 200, "script-sample" : "" } } 違反したディレクティブ 違反が発生した行数・ファイル名

Slide 61

Slide 61 text

実際のCSP違反レポートを見てみる
 実際に導入した際に届いた意外だったCSP違反レポートをいくつか紹介
 (問題のありそうなフィールドは隠します)
 
 
 61

Slide 62

Slide 62 text

実際のCSP違反レポート - 1 - Google翻訳
 62 { "csp-report": { "original-policy": " ", "source-file": " ", "document-uri": " ", "line-number": 386, "referrer": "", "status-code": 0, "violated-directive": "style-src-elem", "column-number": 32, "effective-directive": "style-src-elem", "blocked-uri": "https://www.gstatic.com/_/translate_http/_/ss/k=translate_http.tr.26tY-h6gH9w.L.W.O/ am=DAY/d=0/rs=AN8SPfrCcgxoBri2FVMQptvuOBiOsolgBw/m=el_main_css" } } と<link rel="stylesheet">を 制限・許可するディレクティブ www.gstatic.com...translateと読める Google翻訳に関連するcss

Slide 63

Slide 63 text

実際のCSP違反レポート - 2 - 拡張機能
 63 { "referrer": "", "disposition": "report", "originalPolicy": " ", "columnNumber": 433, "documentURL": " ", "effectiveDirective": "script-src", "lineNumber": 39, "sample": "", "sourceFile": "https://pwm-image.trendmicro.jp/5.8/extensionFrame/scout.bundle.js", "blockedURL": "eval", "statusCode": 200 } Trend Microのパスワードマネージャに関する 拡張機能のscriptファイル

Slide 64

Slide 64 text

CSPを導入・メンテナンスしていてわかったこと
 64

Slide 65

Slide 65 text

CSPを導入・メンテナンスしていてわかったこと
 ● 導入初期は大量にCSP違反レポートが出る
 ○ default-src:'self'などを設定すると更に大量に出る
 ○ 少しずつディレクティブを追加した方が効果を把握しやすい
 
 65

Slide 66

Slide 66 text

CSPを導入・メンテナンスしていてわかったこと
 ● 導入初期は大量にCSP違反レポートが出る
 ○ default-src:'self'などを設定すると更に大量に出る
 ○ 少しずつディレクティブを追加した方が効果を把握しやすい
 
 ● サイト由来でなく、攻撃でもないCSP違反レポートもかなり出る
 ○ Google翻訳 (font-src, connect-src, img-src, etc.)
 ○ 各ブラウザの拡張機能 (script-src)
 ○ アプリ内ブラウザに埋め込まれているスクリプト (script-src)
 66

Slide 67

Slide 67 text

既存サイトへのCSPを導入するには?
 CSPの既存サイトへの段階的な導入手順
 
 
 67

Slide 68

Slide 68 text

既存サイトへのCSPを導入するには?
 CSPの既存サイトへの段階的な導入手順
 1. ポリシーを小さく作って、Report-Onlyで導入する
 2. 上がってくるCSP違反レポートを読んで対応をする
 a. 問題の無い通信なら注意してポリシーを修正する
 b. 問題がありそうな通信ならサイト側の修正を考える
 3. CSP違反レポートが来ないようになったらReport-Onlyを外す
 
 ➡ Report-Onlyでもセキュリティを意識するきっかけになる
 
 68

Slide 69

Slide 69 text

まとめ
 本発表では皆さんが20分で以下の状態になるための情報を提供しました
 ● CSPの基礎がわかる
 ○ →CSPの基本概念の説明・ディレクティブ・フォールバックについて説明 
 ● CSPの導入方法と動作イメージがわかる
 ○ →サイトの構成ごとに異なる導入手順を紹介 
 ● CSPのレポート運用と既存サイトへの導入に向けた手順がわかる
 ○ →Report-Onlyで運用に必要なもの・レポートの例などを紹介 
 69

Slide 70

Slide 70 text

参考文献など
 Webサイト
 - MDN Web Docs: https://developer.mozilla.org/ja/docs/Web/HTTP/CSP
 書籍など
 - 『Webブラウザセキュリティ Webアプリケーションの安全性を支える仕組みを整理する』米内貴志 (ラ ムダノート, 2021)
 70

Slide 71

Slide 71 text

QA用スライド


Slide 72

Slide 72 text

とりあえず入れとけという設定
 1. object-src
 プラグインを利用したコンテンツの利用を制限する
 , , タグなどで利用するリソースの制限
 使っていないなら'none'を設定 (ほとんどのサイトがそう)
 2. base-uri
 タグの利用を制限
 全ての相対URLを書き換えられてしまうので使ってないなら'none'を設定
 3. frame-ancestors
 自サイトを別のページからiframe内に表示させてよいかを制限する
 iframeで表示されることを想定していないページなら'none'を設定
 クリックジャッキング攻撃対策になる
 72

Slide 73

Slide 73 text

CSP導入が難しいケースは?
 1. インラインスクリプト・インラインスタイルを活用している場合
 そのままだとscript-src, style-srcの適用ができない
 2. 動的コード評価を使っているライブラリなどの利用
 eval(), new Function()を利用しているとscript-srcを適用できない
 厳密には'unsafe-eval'を有効にすれば適用できるがリスクがある
 3. 動的にCSPの内容を変更したい場合でフロントエンドがSPAという構成
 マルチテナント型のサービスでクライアントごとにCSPの内容を変えたい時
 フロントエンドがSPAの場合だとバックエンドから制御ができない
 4. 広告ネットワークやGoogle Tag Managerなど外部からの動的ロードがある
 あらかじめホワイトリストを作るのが難しく、回避方法も複雑
 73

Slide 74

Slide 74 text

導入時に苦労したポイントは?
 1. Google Tag Manager(GTM)
 動的に色々なタグを導入されてしまうのでとても困る(場合による)
 社内の利用チームと調整してGoogle Tag Manager自体を外した
 広告ネットワーク・GTMがある場合、難易度が数段階上がりそう
 (特にscript-srcの適用)
 2. ポリシーの整理
 default-src:'self'を起点に始めて細分化していったので
 個別ディレクティブを指定した際'self'の追加を忘れて全拒否になったりした
 違反レポートでの運用なのでレポート量が増えた以外は問題なし
 74

Slide 75

Slide 75 text

参考情報


Slide 76

Slide 76 text

CSP構文チェッカ
 CSP Evaluator
 https://csp-evaluator.withgoogle.com/
 
 作成したCSPが適切かどうかを評価してくれるサイト・拡張機能
 構文レベルでのチェックに加えベストプラクティスに
 沿っていない内容について指摘をしてくれる
 
 
 76