Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Secure な UX のために Content Security Policy について知っておこう

Takuya Eguchi (Akagire)
December 10, 2023
27

Secure な UX のために Content Security Policy について知っておこう

Takuya Eguchi (Akagire)

December 10, 2023
Tweet

Transcript

  1. Web アプリケーションが「取れうる」セキュリティ対策いろいろ 一般的に知られている脅威 • DDoS • バッファオーバーフロー • ディレクトリ・トラバーサル •

    OSコマンドインジェクション • SQLインジェクション • アクセス制御不備 • セッション管理不備 • CSRF • クロスサイトスクリプティング • クリックジャッキング • etc…
  2. Web アプリケーションが「取れうる」セキュリティ対策いろいろ 一般的に知られている脅威 • DDoS • バッファオーバーフロー • ディレクトリ・トラバーサル •

    OSコマンドインジェクション • SQLインジェクション • アクセス制御不備 • セッション管理不備 • CSRF • クロスサイトスクリプティング • クリックジャッキング • etc… サーバー アプリケーション ブラウザ
  3. Web アプリケーションが「取れうる」セキュリティ対策いろいろ 一般的に知られている脅威 • DDoS • バッファオーバーフロー • ディレクトリ・トラバーサル •

    OSコマンドインジェクション • SQLインジェクション • アクセス制御不備 • セッション管理不備 • CSRF • クロスサイトスクリプティング • クリックジャッキング • etc… CDN、LB 要件(ユーザーがOSコマンド・パスを指定できるような要件を排除) 実装(エスケープ、プレースホルダー) 適切な権限設定(実行ユーザーに用途以外のbinをさわれなくしておく等) 要件(入力値を <script> や <style> で実行したいような要件を排除) 実装(token、パスワード再入力、メール案内、サニタイズ等) HTTP header 設定(X-Frame-Options、Content-Security-Policy等)
  4. Web アプリケーションが「取れうる」セキュリティ対策いろいろ 一般的に知られている脅威 • DDoS • バッファオーバーフロー • ディレクトリ・トラバーサル •

    OSコマンドインジェクション • SQLインジェクション • アクセス制御不備 • セッション管理不備 • CSRF • クロスサイトスクリプティング • クリックジャッキング • etc… CDN、LB 要件(ユーザーがOSコマンド・パスを指定できるような要件を排除) 実装(エスケープ、プレースホルダー) 適切な権限設定(実行ユーザーに用途以外のbinをさわれなくしておく等) 要件(入力値を <script> や <style> で実行したいような要件を排除) 実装(token、パスワード再入力、メール案内、サニタイズ等) HTTP header 設定(X-Frame-Options、Content-Security-Policy等) ここの話をします
  5. XSSやクリックジャッキングが起こってしまう理由(近年の実例) サニタイズで対策を している掲示板サービス “while (true) { window.alert(‘pgr’) }” “while &#40;true&#41;&#123

    ;window.alert&#40;‘pg r’&#41;&#125;” 計測スクリプトなどの 配信元 悪意あるスクリプトに置き換え (または混入)
  6. • CORS 関連 (Access-Control-*) …指定したオリジンからのリクエストのみを許可する • Cross-Origin-Opener-Policy (COOP) …ポップアップで開くリンクのドメインを許可する •

    Strict-Transport-Security (HSTS) …HTTPのかわりにHTTPS通信を強制する • X-Frame-Options …<iframe>の可否や指定したオリジンのみ許可する • Permissions-Policy …ブラウザの機能の可否を制御する • Content-Security-Policy (CSP) …読み込み・実行するデータの可否・オリジンを制御する Header に限らず、一般的な脅威に対する対策はMdNがまとめてくれてます! https://developer.mozilla.org/ja/docs/Web/Security セキュリティに関するいろいろな HTTP Header の例
  7. • CORS 関連 (Access-Control-*) …指定したオリジンからのリクエストのみを許可する • Cross-Origin-Opener-Policy (COOP) …ポップアップで開くリンクのドメインを許可する •

    Strict-Transport-Security (HSTS) …HTTPのかわりにHTTPS通信を強制する • X-Frame-Options …<iframe>の可否や指定したオリジンのみ許可する • Permissions-Policy …ブラウザの機能の可否を制御する • Content-Security-Policy (CSP) …読み込み・実行するデータの可否・オリジンを制御する Header に限らず、一般的な脅威に対する対策はMdNがまとめてくれてます! https://developer.mozilla.org/ja/docs/Web/Security セキュリティに関するいろいろな HTTP Header の例 ここを深ぼる
  8. 設定できるCSPポリシーがいくつかある。 • default-src …ほかのポリシーが未指定だった場合に参照される設定 • connect-src …スクリプト内で読み込み可能なオリジン設定 • img-src …読み込み可能な画像のオリジン設定

    • script-src …実行可能なスクリプトのオリジン等の設定 • style-src …適用可能なCSSのオリジン等の設定 • report-uri …CSPポリシー違反が起きた場合の通報先URL • etc… 詳細は MdN をチェックしてください CSP のポリシー
  9. ところで CSP は inline script / style に厳しい 例3:Script は自己ドメインからの読み込みのみ許可した場合...

    script-src: ‘self’ <script src=”/path/to/script.js”></script> → 実行される <script>console.log(‘hoge’);</script> → 実行が拒否される
  10. nonce とは1回限り有効なランダムなデータのことです。 CSP が Content-Security-Policy: script-src 'nonce-2726c7f26c’ だったとして、 <body> <!--

    ↓これは実行されない --> <script>window.alert(‘hello’);</script> <!-- ↓これは実行される --> <script nonce=”2726c7f26c”>window.alert(‘world!’);</script> </body> →簡単だが、リクエストのたびに nonce が生成できる環境... MPA、SSR・ISRでないと採用できない。 ① nonce 方式
  11. unsafe-inline と hash を同時に指定したらどうなる? →強力な指定が優先されるので、 unsafe-inline は無視されます なので、開発中に HMR 由来の

    inline-script が挿入される場合では process.env.NODE_ENV を見て header を出し分ける必要あり。 unsafe-inline と nonce/hash を併用した場合の優先度
  12. SSG の場合は hash 方式を使うことになるが... ① デザインF/W使ってる場合、 インラインに埋め込まれる CSS / JavaScript

    が どうなるかわからないので、どんな hash を 生成すればいいのかわからない。 ② inline style/script を用意するたびに hash を手で生成してたら気が遠くなる →せやな 最悪、手作業でできる が、アセットをビルドして生成する環境であれば Bundler のビルドプロセスに介入して hash を作るしかない。 inline-script / style の許可が SSG/SPA でつらい問題
  13. SSRしたくない!SSGで使える便利なライブラリはないの? → Next.js であれば @next-safe/middleware というライブラリがあります が、Next.js の v13.3 系リリース以降、長期間メンテされていない上に、

    クライアントの環境によっては Next.js の初期化を阻害してしまうため、 私のプロジェクトでは利用を見合わせました。 https://github.com/nibtime/next-safe-middleware/issues/83 ダメ元で、 Next.js 側で初期化の挙動を調整する PR を本家に出したが、再現性がないため放置されてる (だれからもコメントすらつかない...) https://github.com/vercel/next.js/pull/53423 Auth0 もSPA x CSP は 「SSR 方式以外は難しい」としている https://auth0.com/blog/defending-against-xss-with-csp/#Using-CSP-with-SPAs inline-script / style の許可が SSG/SPA でつらい問題
  14. • フロントエンドでちゃんとセキュリティ対策しようとすると JavaScript だけでなく、ブラウザの動作に関する知識が必要 (MdNのドキュメント、caniuse とにらめっこ) • 何も考えずに CSP を厳し目に導入するのはオススメしない

    ◦ UGC がメインコンテンツではないアプリの場合は 得られるメリットが限定的 ◦ ただし導入しない場合は依存するライブラリの選定を慎重にする (悪意あるコードが意図せずに混入したら大変) • 利用するライブラリが CSP に対応していない場合があるので、 後からCSP導入するのは大変(ある程度の妥協が必要) ◦ 私は notistack が CSP 未対応だったので泣きました https://github.com/iamhosseindhv/notistack/issues/552 • CSP に頼らずセキュアな実装にすることを忘れない おまけ: 個人的な感想①
  15. • 最低限やっておきたい設定 ◦ CSPだけでなんでも対策しようとしない おまけ: 個人的な感想② Content-Security-Policy default-src self script-src

    style-src - self - unsafe-inline - その他ライブラリが依存する origin connect-src - self - API 接続先の origin Cross-Origin-Opener-Policy same-origin Cross-Origin-Resource-Policy same-origin X-Frame-Options ‘DENY’
  16. • これ以上強化したい場合は、提供サービスの性質や依存ライブラリの 振る舞いを見て、適宜設定を強化していけば良いかな...? • 異常検知したい場合は report-uri も指定 ※ report-uri は

    非推奨になったので、 Content-Security-Policy-Report-Only ヘッダーを使うことを推奨 • まともなホスティングサービスを使いましょう ◦ SSRしないからという理由で GCS を使うと CSP が設定できません https://issuetracker.google.com/issues/36427250 おまけ: 個人的な感想②
  17. • ① next.config.json の headers を使う ◦ 簡単だが inline-script/style 向け設定は厳しい

    • ② _document.tsx で nonce を生成する (要 SSR 化) ◦ SSR の利用が許容できるなら間違いなく有効 • ② middleware.ts を使う ◦ SSR せずに inline script を hash や nonce で ケアできるかも(検討中...) おまけ: Next.js における具体的な実装アイデア