$30 off During Our Annual Pro Sale. View Details »

Content Security Policy入門 セキュリティ設定と 違反レポートのはじめ方...

Content Security Policy入門 セキュリティ設定と 違反レポートのはじめ方 / Introduction to Content Security Policy Getting Started with Security Configuration and Violation Reporting

JJUG CCC 2024 Fallで発表したスライドです

Yusuke Uehara

October 27, 2024
Tweet

Other Decks in Programming

Transcript

  1. 目次
 • CSPの基礎
 ◦ CSPの基本概念
 ◦ CSPの構造・ポリシーディレクティブ 
 • CSPの導入方法と構成


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


    • CSPの導入方法と構成
 ◦ サイトの構成にあわせたCSPの導入方法 
 ◦ CSPの構成例と動作イメージ 
 • CSPのレポート運用と既存サイトへの導入に向けた手順
 ◦ CSP Report-Only 構成例 
 ◦ CSP違反レポートの読み方と実際のCSP違反レポート 
 ◦ より良い運用と、既存サイトへの段階的な導入手順 
 6
  3. Content Security Policy (CSP) とは何か
 MDN Web Docs での説明
 


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


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


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


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


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


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


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


    (またはhtmlファイル内の<meta>タグ内に記載)
 
 
 
 
 
 
 
 
 18 https://a.example.com 
 Web ブラウザ index
 .html
 Content-Security-Policy: script-src a.example.com; HTTP Request HTTP Response HTTP Response Header
  11. 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
  12. 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
  13. 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
  14. 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
  15. ディレクティブの種別
 MDN Web Docs で記載されているディレクティブは30種類弱
 4分類に分けられる
 
 • Fetch Directive


    ◦ リソース種別の読み込みを制御する 
 • Document Directive
 ◦ ドキュメントの状態に対する操作を制御する
 • Navigation Directive
 ◦ フォームの送信やナビゲーションを制御する
 • Reporting Directive
 ◦ CSP違反が起きた際の挙動を制御する
 25
  16. ディレクティブの一覧 (一部省略)
 
 
 
 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
  17. ディレクティブのフォールバック
 ディレクティブには親子関係があり、特定のディレクティブが指定されない場合
 フォールバック先のディレクティブの値が参照されるものがある
 
 例:以下の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;
  18. ディレクティブのフォールバック
 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 凡例 直接設定されたディレクティブ 影響を受けるディレクティブ
  19. ディレクティブのフォールバック
 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 凡例 直接設定されたディレクティブ 影響を受けるディレクティブ
  20. ディレクティブのフォールバック
 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 凡例 直接設定されたディレクティブ 影響を受けるディレクティブ
  21. ディレクティブのフォールバック
 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 凡例 直接設定されたディレクティブ 影響を受けるディレクティブ
  22. 目次
 • CSPの基礎
 ◦ CSPの基本概念
 ◦ CSPの構造・ポリシーディレクティブ 
 • CSPの導入方法と構成

    
 ◦ サイトの構成にあわせたCSPの導入方法 
 ◦ CSPの構成例と動作イメージ 
 • CSPのレポート運用と既存サイトへの導入に向けた手順
 ◦ CSP Report-Only 構成例 
 ◦ CSP違反レポートの読み方と実際のCSP違反レポート 
 ◦ より良い運用と、既存サイトへの段階的な導入手順 
 32
  23. CSPの導入方法 - MPA (Spring Security) - 1
 バックエンドとフロントエンドの実装が分かれていない
 バックエンドアプリケーションがhtmlを直接配布するようなMPA
 アプリケーション内でHTTPレスポンスヘッダを設定する


    
 
 
 
 
 
 Spring Boot x Thymeleaf の1台構成のような構成
 Spring Securityの機能でCSPを設定することができる
 34 Web ブラウザ サーバー リクエスト レスポンス
  24. 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(); } }
  25. 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(); } } 文字列でヘッダ名を除いたポリシー全体を渡すだけ
  26. 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サーバーに
  27. CSPの導入方法 - SPA (CDN CloudFront) - 2
 AWS CloudFrontの場合
 CloudFront

    > ポリシー > レスポンスヘッダ > レスポンスヘッダポリシー
 38
  28. CSPの動作確認 - 1
 様々な外部リソースを読み込むページ
 
 
 
 
 
 


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


    
 
 
 
 
 
 https://uskey512.github.io/csp-sample/csp-enable.html 
 
 
 
 
 41 Content-Security-Policy: default-src 'self';
  30. CSPを安全に導入したい
 最終的にCSPを導入したいが…
 
 • 本番環境への導入にハードルがある
 ◦ 通信が意図せず制御されてしまうと何かが壊れる = 障害 


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


    
 • ポリシー作成が難しい
 ◦ サイトが大規模すぎる
 ◦ 読み込まれるリソースとして何があるのか把握できていない 
 
 CSPをレポート通知のみで適用する方法がある
 CSPの評価結果をレポート通知だけを行って通信の制御をしない →Content-Security-Policy-Report-Only というヘッダがある
 46
  32. 目次
 • CSPの基礎
 ◦ CSPの基本概念
 ◦ CSPの構造・ポリシーディレクティブ 
 • CSPの導入方法と構成


    ◦ サイトの構成にあわせたCSPの導入方法 
 ◦ CSPの構成例と動作イメージ 
 • CSPのレポート運用と既存サイトへの導入に向けた手順 
 ◦ CSP Report-Only 構成例 
 ◦ CSP違反レポートの読み方と実際のCSP違反レポート 
 ◦ より良い運用と、既存サイトへの段階的な導入手順 
 47
  33. 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に変更
  34. Report-Onlyでの運用 - 3 - CSP違反レポートの内容
 CSP違反レポートの送信
 CSP違反が発生するとWebブラウザはCSP違反レポートを送信するようになる
 (違反レポートはjson形式でPOSTメソッドで送信される)
 
 違反レポートには下記のような項目が含まれる


    • document-uri
 ◦ 違反が発生したドキュメントのURI
 • blocked-uri
 ◦ 読み込みがブロックされるリソースのURI
 • violated-directive
 ◦ 違反したディレクティブの名前
 50
  35. Report-Onlyでの運用 - 4 - CSP違反レポートサーバー
 発生したCSP違反レポートを受け取るためのエンドポイントが必要
 
 監視系のSaaSはCSP違反レポートを受け取るエンドポイントを提供している
 • Sentry


    • Datadog
 
 POSTでjson形式のデータを受け取るだけなので
 CSP違反レポートを受け取るエンドポイントを自作しても基本的に問題はない
 
 大量にCSP違反レポートが来ることが想定される場合
 集計や分析を行える仕組みがあった方がその後の運用を進めやすい
 51
  36. 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
  37. 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に変更
  38. 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<HttpMessageConverter<?>> 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 発生
  39. CSP違反レポートをうけとる - 3 - RestController
 
 57 @RestController @RequestMapping("/api") public

    class CspReportController { // ... @PostMapping(value = "/csp_reports", consumes = { "application/csp-report" }) public ResponseEntity<String> 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"を 処理することを明示
  40. 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" : "" } } 違反したディレクティブ 違反が発生した行数・ファイル名
  41. 実際の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" } } <style>と<link rel="stylesheet">を 制限・許可するディレクティブ www.gstatic.com...translateと読める Google翻訳に関連するcss
  42. 実際の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ファイル
  43. まとめ
 本発表では皆さんが20分で以下の状態になるための情報を提供しました
 • CSPの基礎がわかる
 ◦ →CSPの基本概念の説明・ディレクティブ・フォールバックについて説明 
 • CSPの導入方法と動作イメージがわかる
 ◦

    →サイトの構成ごとに異なる導入手順を紹介 
 • CSPのレポート運用と既存サイトへの導入に向けた手順がわかる
 ◦ →Report-Onlyで運用に必要なもの・レポートの例などを紹介 
 69
  44. 参考文献など
 Webサイト
 - MDN Web Docs: https://developer.mozilla.org/ja/docs/Web/HTTP/CSP
 書籍など
 - 『Webブラウザセキュリティ

    Webアプリケーションの安全性を支える仕組みを整理する』米内貴志 (ラ ムダノート, 2021)
 70
  45. とりあえず入れとけという設定
 1. object-src
 プラグインを利用したコンテンツの利用を制限する
 <embed>, <applet>, <object>タグなどで利用するリソースの制限
 使っていないなら'none'を設定 (ほとんどのサイトがそう)
 2.

    base-uri
 <base>タグの利用を制限
 全ての相対URLを書き換えられてしまうので使ってないなら'none'を設定
 3. frame-ancestors
 自サイトを別のページからiframe内に表示させてよいかを制限する
 iframeで表示されることを想定していないページなら'none'を設定
 クリックジャッキング攻撃対策になる
 72
  46. CSP導入が難しいケースは?
 1. インラインスクリプト・インラインスタイルを活用している場合
 そのままだとscript-src, style-srcの適用ができない
 2. 動的コード評価を使っているライブラリなどの利用
 eval(), new Function()を利用しているとscript-srcを適用できない


    厳密には'unsafe-eval'を有効にすれば適用できるがリスクがある
 3. 動的にCSPの内容を変更したい場合でフロントエンドがSPAという構成
 マルチテナント型のサービスでクライアントごとにCSPの内容を変えたい時
 フロントエンドがSPAの場合だとバックエンドから制御ができない
 4. 広告ネットワークやGoogle Tag Managerなど外部からの動的ロードがある
 あらかじめホワイトリストを作るのが難しく、回避方法も複雑
 73
  47. 導入時に苦労したポイントは?
 1. Google Tag Manager(GTM)
 動的に色々なタグを導入されてしまうのでとても困る(場合による)
 社内の利用チームと調整してGoogle Tag Manager自体を外した
 広告ネットワーク・GTMがある場合、難易度が数段階上がりそう


    (特にscript-srcの適用)
 2. ポリシーの整理
 default-src:'self'を起点に始めて細分化していったので
 個別ディレクティブを指定した際'self'の追加を忘れて全拒否になったりした
 違反レポートでの運用なのでレポート量が増えた以外は問題なし
 74