Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Secure な UX のために Content Security Policy について知っ...
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
Takuya Eguchi (egch)
December 10, 2023
59
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Secure な UX のために Content Security Policy について知っておこう
https://uxdig.connpass.com/event/303907/
Takuya Eguchi (egch)
December 10, 2023
More Decks by Takuya Eguchi (egch)
See All by Takuya Eguchi (egch)
TypeScript の class を使い倒す
egch
1
56
Next.js に疲れた私は Vue3 に癒やされた
egch
0
330
package.json がすごい
egch
0
150
Nuxt.js のインスタンスライフサイクル総点検
egch
0
420
Webエンジニアのデザイン実装との付き合い方
egch
0
320
20200528 - GCPでもサーバーレスでRubyりたい!
egch
0
140
VeeValidate の"穴"を踏み抜いてしまった
egch
1
920
継続的に楽しくプログラミングするには - 2018/11/3 Rails Girls Sendai
egch
0
120
Featured
See All Featured
Taking LLMs out of the black box: A practical guide to human-in-the-loop distillation
inesmontani
PRO
3
2.3k
The Mindset for Success: Future Career Progression
greggifford
PRO
0
360
New Earth Scene 8
popppiees
3
2.3k
Lessons Learnt from Crawling 1000+ Websites
charlesmeaden
PRO
1
1.3k
The SEO Collaboration Effect
kristinabergwall1
1
480
Why Our Code Smells
bkeepers
PRO
340
58k
Tips & Tricks on How to Get Your First Job In Tech
honzajavorek
1
540
Balancing Empowerment & Direction
lara
6
1.1k
The untapped power of vector embeddings
frankvandijk
2
1.7k
The Hidden Cost of Media on the Web [PixelPalooza 2025]
tammyeverts
2
330
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
333
22k
Public Speaking Without Barfing On Your Shoes - THAT 2023
reverentgeek
1
420
Transcript
Secure な UX のために Content Security Policy について 2023/12/11 UXDIG
11
自己紹介 江口 拓弥 インフラ知識が壊滅的な Web 開発者 フロントエンド領域(特に表層の実装)が大好き。 2018 年に東京から仙台へお引越し 2019
年から新規事業を作るお仕事やってます
技術的な話が多いです おことわり
・Web アプリのセキュリティ対策 ・XSSとクリックジャッキング について ・CSP について アジェンダ
・Web アプリのセキュリティ対策 ・XSSとクリックジャッキング について ・CSP について アジェンダ
Web アプリケーションが「取れうる」セキュリティ対策いろいろ
Web アプリケーションが「取れうる」セキュリティ対策いろいろ 一般的に知られている脅威 • DDoS • バッファオーバーフロー • ディレクトリ・トラバーサル •
OSコマンドインジェクション • SQLインジェクション • アクセス制御不備 • セッション管理不備 • CSRF • クロスサイトスクリプティング • クリックジャッキング • etc…
Web アプリケーションが「取れうる」セキュリティ対策いろいろ 一般的に知られている脅威 • DDoS • バッファオーバーフロー • ディレクトリ・トラバーサル •
OSコマンドインジェクション • SQLインジェクション • アクセス制御不備 • セッション管理不備 • CSRF • クロスサイトスクリプティング • クリックジャッキング • etc… サーバー アプリケーション ブラウザ
Web アプリケーションが「取れうる」セキュリティ対策いろいろ 一般的に知られている脅威 • DDoS • バッファオーバーフロー • ディレクトリ・トラバーサル •
OSコマンドインジェクション • SQLインジェクション • アクセス制御不備 • セッション管理不備 • CSRF • クロスサイトスクリプティング • クリックジャッキング • etc… CDN、LB 要件(ユーザーがOSコマンド・パスを指定できるような要件を排除) 実装(エスケープ、プレースホルダー) 適切な権限設定(実行ユーザーに用途以外のbinをさわれなくしておく等) 要件(入力値を <script> や <style> で実行したいような要件を排除) 実装(token、パスワード再入力、メール案内、サニタイズ等) HTTP header 設定(X-Frame-Options、Content-Security-Policy等)
Web アプリケーションが「取れうる」セキュリティ対策いろいろ 一般的に知られている脅威 • DDoS • バッファオーバーフロー • ディレクトリ・トラバーサル •
OSコマンドインジェクション • SQLインジェクション • アクセス制御不備 • セッション管理不備 • CSRF • クロスサイトスクリプティング • クリックジャッキング • etc… CDN、LB 要件(ユーザーがOSコマンド・パスを指定できるような要件を排除) 実装(エスケープ、プレースホルダー) 適切な権限設定(実行ユーザーに用途以外のbinをさわれなくしておく等) 要件(入力値を <script> や <style> で実行したいような要件を排除) 実装(token、パスワード再入力、メール案内、サニタイズ等) HTTP header 設定(X-Frame-Options、Content-Security-Policy等) ここの話をします
・Web アプリのセキュリティ対策 ・XSSとクリックジャッキング について ・CSP について アジェンダ
XSSやクリックジャッキングが起こってしまう理由(説明でよくある例) なんの対策もしてない 掲示板サービス “2get” “2get” “while (true) { window.alert(‘pgr’) }”
XSSやクリックジャッキングが起こってしまう理由(近年の実例) サニタイズで対策を している掲示板サービス “while (true) { window.alert(‘pgr’) }” “while (true){
;window.alert(‘pg r’)}” 計測スクリプトなどの 配信元 悪意あるスクリプトに置き換え (または混入)
クライアントサイドへの攻撃に対して、アプリケーションが取れうる対策は限られる。 が、ブラウザはどんどんモダンでセキュアに使えるようになっている。 ↓ HTTP Header でブラウザの挙動を指定して 意図しないスクリプトの読み込みや実行を ブロックすることで対策できる 依存系が原因でXSS・クリックジャッキングが発生することも
• 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 の例
• 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 の例 ここを深ぼる
・Web アプリのセキュリティ対策 ・XSSとクリックジャッキング について ・CSP について アジェンダ
設定できるCSPポリシーがいくつかある。 • default-src …ほかのポリシーが未指定だった場合に参照される設定 • connect-src …スクリプト内で読み込み可能なオリジン設定 • img-src …読み込み可能な画像のオリジン設定
• script-src …実行可能なスクリプトのオリジン等の設定 • style-src …適用可能なCSSのオリジン等の設定 • report-uri …CSPポリシー違反が起きた場合の通報先URL • etc… 詳細は MdN をチェックしてください CSP のポリシー
CSPのポリシーに指定する値はソースと呼ばれます。 例1:自己ドメインと cdn.jsdelivr.net からの 画像読み込みのみ許可したい場合... img-src: ‘self’ https://cdn.jsdelivr.net/ 指定できるポリシーの内容 ポリシー
ソース ソース
例2:CSSは自己ドメインからの読み込みと、inline-style を許可したい場合... style-src: ‘self’ ‘unsafe-inline’ 指定できるポリシーの内容 ポリシー ソース ソース
複数のルールを指定するときは「 ; 」で区切る 例)画像はホスティングしてるオリジンまたはjsDelivrから、 CSSはホスティングしてるオリジンとinlineスタイルのみ適用し、 それ以外は読み込みをしない設定 default-src: ‘none’; img-src: ‘self’
https://cdn.jsdelivr.net/; style-src: ‘self’ ‘unsafe-inline’ 指定できるポリシーの内容
ほかにも、eval の利用を許可 (‘unsafe-eval’)したり データソースとして file (‘filesystem:’)を許容するなど 色々な設定があります。 詳細はMdNの CSP ソース値を参照してください
https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/Content-Security-Policy/So urces 指定できるポリシーの内容
ところで CSP は inline script / style に厳しい 例3:Script は自己ドメインからの読み込みのみ許可した場合...
script-src: ‘self’ <script src=”/path/to/script.js”></script> → 実行される <script>console.log(‘hoge’);</script> → 実行が拒否される
① nonce方式 ② hash 方式 unsafe-inline を利用せずに inline script /
style を許可する方法
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 方式
hash とは、あるデータを特定の関数に入れたときに生成されるデータのことです。 インラインコードから sha256/384/512 のいずれかのアルゴリズムで hash を生成し、許可リストにすることも可能。 例:<script>window.alert(‘hello’);</script> を許可する場合... ②
hash 方式 となったので、以下のポリシーを設定すれば alert が実行される。 script-src: sha256-vkOgq6/Q3V+sbQmNOKbqLVBnxivEH+pSOxfOF2VywDA=
unsafe-inline と hash を同時に指定したらどうなる? →強力な指定が優先されるので、 unsafe-inline は無視されます なので、開発中に HMR 由来の
inline-script が挿入される場合では process.env.NODE_ENV を見て header を出し分ける必要あり。 unsafe-inline と nonce/hash を併用した場合の優先度
設定項目も多いので確認がつらい... → CSP Evaluator っていう便利なサービスがあります https://csp-evaluator.withgoogle.com/ CSP 設定内容のデバッグ
SSG の場合は hash 方式を使うことになるが... ① デザインF/W使ってる場合、 インラインに埋め込まれる CSS / JavaScript
が どうなるかわからないので、どんな hash を 生成すればいいのかわからない。 ② inline style/script を用意するたびに hash を手で生成してたら気が遠くなる →せやな 最悪、手作業でできる が、アセットをビルドして生成する環境であれば Bundler のビルドプロセスに介入して hash を作るしかない。 inline-script / style の許可が SSG/SPA でつらい問題
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 でつらい問題
• クライアントサイドのセキュリティ対策は HTTP Header で行う • 適切に設定すればインジェクションはほぼ防げる • 特に CSP
は万が一インジェクションされた場合も対策可能 まとめ
• フロントエンドでちゃんとセキュリティ対策しようとすると JavaScript だけでなく、ブラウザの動作に関する知識が必要 (MdNのドキュメント、caniuse とにらめっこ) • 何も考えずに CSP を厳し目に導入するのはオススメしない
◦ UGC がメインコンテンツではないアプリの場合は 得られるメリットが限定的 ◦ ただし導入しない場合は依存するライブラリの選定を慎重にする (悪意あるコードが意図せずに混入したら大変) • 利用するライブラリが CSP に対応していない場合があるので、 後からCSP導入するのは大変(ある程度の妥協が必要) ◦ 私は notistack が CSP 未対応だったので泣きました https://github.com/iamhosseindhv/notistack/issues/552 • CSP に頼らずセキュアな実装にすることを忘れない おまけ: 個人的な感想①
• 最低限やっておきたい設定 ◦ 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’
• これ以上強化したい場合は、提供サービスの性質や依存ライブラリの 振る舞いを見て、適宜設定を強化していけば良いかな...? • 異常検知したい場合は report-uri も指定 ※ report-uri は
非推奨になったので、 Content-Security-Policy-Report-Only ヘッダーを使うことを推奨 • まともなホスティングサービスを使いましょう ◦ SSRしないからという理由で GCS を使うと CSP が設定できません https://issuetracker.google.com/issues/36427250 おまけ: 個人的な感想②
• ① next.config.json の headers を使う ◦ 簡単だが inline-script/style 向け設定は厳しい
• ② _document.tsx で nonce を生成する (要 SSR 化) ◦ SSR の利用が許容できるなら間違いなく有効 • ② middleware.ts を使う ◦ SSR せずに inline script を hash や nonce で ケアできるかも(検討中...) おまけ: Next.js における具体的な実装アイデア
おわり