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

機密情報の漏洩を防げ! Webフロントエンド開発で意識すべき漏洩パターンとその対策

Sponsored · SiteGround - Reliable hosting with speed, security, and support you can count on.
Avatar for mizdra mizdra PRO
November 15, 2025

機密情報の漏洩を防げ! Webフロントエンド開発で意識すべき漏洩パターンとその対策

Avatar for mizdra

mizdra PRO

November 15, 2025
Tweet

More Decks by mizdra

Other Decks in Technology

Transcript

  1. 4 機密情報 • 機密情報と言っても色々ある ◦ 個人情報 (メールアドレス, 住所) ◦ 業務上の情報

    (開発環境のドメイン, 未公開のキャンペーン情報) ◦ 認証情報 (API トークン, Cookie) ◦ ログ (アクセスログ、アプリケーションログ) ◦ ソースコード • 要は漏れるとマズいもの
  2. 5 Web フロントエンドにおいては • 漏れないように注意して開発しようという話ではある • ただし Web フロントエンドフロントエンドでは... ◦

    機密情報の漏洩が起きやすい • 何故か ◦ ユーザに面してる ◦ HTML や JavaScript がブラウザから読める • 見える情報が多いゆえに脆弱
  3. 6 最近の Web フロントエンドは 落とし穴が結構ある • モダンなフロントエンドフレームワークでは... ◦ 機密情報を漏洩させやすいポイントがある •

    フレームワークの裏側の挙動を知ってれば回避可能だが... ◦ 知らないとハマる ◦ テンプレートエンジン (Xslate, erb) に慣れてる人ほどハマりやすい
  4. 7 このセッションの目的 モダンな Web フロントエンド開発で漏洩を防ぐための知識 と術を伝えます。 • 従来技術 (Xslate, erb)

    との違い ◦ なぜモダンなフロントエンド FW は漏洩させやすいのか ◦ 漏洩を防ぐにはどうしたら良いのか • 漏洩の有無を調べる方法 • うっかり漏洩するのを防ぐテクニック
  5. 8 おことわり • React, Next.js の話が割と多め • とはいえ他の View ライブラリ/FW

    に適用可能な話もある • 最もメジャーな流派の事情を知るのは良いこと
  6. 10 従来技術とは • ここでいう従来技術というのは... ◦ Xslate (Perl), erb (Ruby), PHP

    ◦ いわゆるテンプレートエンジン • リクエストが来たら、サーバでテンプレートをレンダー ◦ HTML を返す
  7. 12 最近の Web フロントエンド開発 • JS の View ライブラリを使って UI

    を組むのが主流 ◦ React, Vue.js, Angular, … • ブラウザ上でコンポーネントをレンダーするだけでなく ◦ SSR (サーバー上でレンダー) するのが当たり前 ◦ SSR をサポートする FW (Next.js, Nuxt.js など) を使う • 1つの View ライブラリ、1つの言語で UI を実装
  8. 19 Next.js (Pages Router) の挙動 • 全コンポーネントはブラウザ向けの bundle に含まれる ◦

    コンポーネントに書いてあることは、全部漏洩する • コンポーネントに機密情報を書いてはならない
  9. 20 何故コンポーネントがブラウザ向けの bundle に含まれるのか • もしかしたら疑問に思うかも ◦ erb はそうじゃないのに、なんで Next.js

    はそうなるの • コンポーネントはレンダーが1回限りじゃない ◦ サーバー上で1度レンダーされる (SSR) ◦ state が変わったら、ブラウザでもレンダーされる (CSR)
  10. 25 モダンなフロントエンド FW での漏洩対策 • サーバーに機密情報を追いやる • いくつかの実装パターンがある ◦ 1.

    サーバーから機密情報を fetch する ◦ 2. getServerSideProps を使う (Next.js Pages Router 限定) ◦ 3. Server Component を使う (React 限定)
  11. 27 2. getServerSideProps を使う • Next.js Pages Router 限定のテク ◦

    面白いので紹介 • getServerSideProps とは ◦ ページコンポーネント (例: TopPage) に渡す props を生成する関数 • これを使っても漏洩を回避できる
  12. 29 なぜこれで漏洩を回避できるのか • 実は getServerSideProps は... ◦ サーバーサイドで実行される • 関数自体のコードも、サーバーの

    bundle にのみ含まれる ◦ ブラウザの bundle に含まれない • 機密情報を書いても漏洩しない!
  13. 31 3. Server Component (SC) を使う • React 限定のテク •

    React 19 で安定化された、新しい種類のコンポーネント ◦ サーバーで"のみ"レンダーされるコンポーネント ◦ Xslate や erb みたいなやつ • ブラウザの bundle に含まれない ◦ 漏洩を回避できる!
  14. 補足: Client Component (CC) • Server Component の対になるもの • その正体は...

    ◦ SC 登場以前にあったコンポーネントのこと • Server Component 登場によって... ◦ 名前の整理が行われただけ ◦ 今まで書いてたやつが、Client Component と呼ばれるように 32
  15. 補足: 'use client' ディレクティブ • RSC の世界では、デフォルトで SCになる (※1) •

    CC にするには、 ‘use client’ を付ける 33 ※1: 厳密には何もつけないと SC / CC のどちらでもない、未確定の状態になる。 コンポーネント利用側に応じて SC / CC どちらになるか、後から決まる。
  16. 補足: SC と CC の違い 34 Server Components Client Components

    ブラウザの bundle 含まれない 含まれる イベントリスナ ❌ 登録できない ✅ 登録できる サーバ専用 API ✅ 使える ❌ 使えない ブラウザ専用 API ❌ 使えない ✅ 使える React Hooks ❌ 使えない ✅ 使える
  17. 補足: サポート状況 35 • Server Component をサポートしている FW が必要 ◦

    Next.js, Waku, React Router, … ◦ production ready なものは Next.js のみ • Next.js はサポートしているものの... ◦ App Router (新しい Router 実装) でのみサポート ◦ Pages Router (古い Router 実装) では未サポート ▪ コンポーネントはすべて Client Component という扱い
  18. 補足: 他にも色々 36 • SC/CC は入れ子にできる • … • 後は資料見て!!!

    https://speakerdeck.com/mizdra/react-server-components-noyi-wen-wojie-kim ing-kasu
  19. 38 Server Component の落とし穴 • SC => CC に props

    を渡すとき... ◦ 実はその props の中身がユーザから見える
  20. CC に渡す props からの漏洩 • SC から CC に渡した props

    はユーザから丸見え!!! ◦ props が丸ごとシリアライズされ、HTML に埋め込まれてる コードは以下の記事を参考にしつつ、改変してます。 https://zenn.dev/cybozu_frontend/articles/react-taint-apis
  21. 40 CC の props はなぜ HTML に 埋め込まれる? • erb

    で data-initial="<%= count %>" してたのと同じ • サーバーからクライアントにデータを渡すには... ◦ HTML にシリアライズして埋め込まないといけない
  22. 44 調査方法①: grep する • ブラウザ向けのビルド成果物を grep する ◦ 例:

    grep --color -i -r -o -E '機密情報' ./dist • Next.js の場合 ◦ .next/static にブラウザ向けの成果物があるので、そこを grep する
  23. 45 調査方法②: Chrome DevTools の Network パネルを使う • Network パネル

    ◦ ページ閲覧中に発生したリクエストを覗き見れる
  24. 46 調査方法②: Chrome DevTools の Network パネルを使う • 実は検索機能が付いてる ◦

    ページ閲覧中にリクエストされたリソースに対し、平文検索する • これを使えば、機密情報の漏洩を調べられる
  25. 53 ② CC に機密情報が渡るのを Taint API で防ぐ • React に

    Taint API という機能がある ◦ 任意の値を汚染 (taint) できる • 汚染された値を CC に渡すと... ◦ 実行時エラーが発生する • 誤って CC に機密情報を渡してしまうのを防げる
  26. 55 ③ GraphQL で data fetch • 一般的にはレンダーに必要な data を

    fetch するのに... ◦ `prisma.users.findUnique(...)` や `fetch(...)` を使いがち • その代わりに、GraphQL を使う
  27. 56

  28. 57 何が良いの • GraphQL スキーマに書かれた field しか、コンポーネント から触れなくなる ◦ スキーマに書いてない余計なもの

    (User.pass など) は、resolver か ら返される段階で削ぎ落とされる • コンポーネントから余計なものを参照できない ◦ 漏洩もしない
  29. 58 とはいえ • このためだけに GraphQL を利用するのはオーバーキル ◦ resolver の実装コストは無視できない •

    一般にはオススメできないが... ◦ すごく漏洩に気を遣うプロジェクトではアリ
  30. 59 まとめ • モダンなフロントエンド FW では... ◦ (通常) コンポーネントがブラウザから丸見え ◦

    fetch, getServerSideProps, Server Component で漏洩を防ぐ • 漏洩の有無を調べることも大事 ◦ grep, Chrome Devtools • うっかりミスを防ぐのも重要 ◦ CI で grep, Taint API, GraphQL で多層防御
  31. 62 Source Map とは • ビルド前後のコードの対応関係が記録されたファイル ◦ 拡張子は *.map •

    Source Map があることで ◦ スタックトレースがオリジナルのコードのものになる ◦ オリジナルのコードに breakpoint を仕掛けてステップ実行できる
  32. 67 対策 • 本番ビルドでは Source Map を生成しない • とはいえ...どうしても生成したい時はある ◦

    エラー監視サービス (Sentry など) に Source Map を送りたいとか • 以下のようなビルドフローを組むと良い ◦ 1. Source Map 生成ありで本番ビルド ◦ 2. エラー監視サービスに Source Map をアップロード ◦ 3. Source Map を削除 (`rm -rf dist/**/*.map`)
  33. 68 余談 • @sentry/nextjs ◦ ビルド時に Source Map を Sentry

    にアップロードしてくれる ◦ アップロード後、自動で削除もしてくれる • しかし... ◦ 最近まで CSS の Source Map が削除されないバグがあった ◦ https://github.com/getsentry/sentry-javascript/issues/18125 ◦ 5日前に報告して、修正リリース済み
  34. 70 コンポーネントの関連リソースからの漏洩 • 関連リソースとは ◦ コンポーネントファイルから import したり、参照しているもの ◦ CSS,

    画像, JavaScript モジュール • 全部 .next/static 配下に出力される (ブラウザから見える) • 開発環境用の隠し画像ファイルが漏れるとかはありがち... ◦ 気をつけよう
  35. 71 対策 • 可能な限り、開発環境用のリソースの置き場を限定する ◦ `app/internal/…`: ページコンポーネント ◦ `components/internal/…`: 汎用コンポーネント

    ◦ `assets/internal/…`: 画像や json ファイルなど • 本番環境向けのビルドをする直前に、それらを削除する ◦ rm -rf {app,components,assets}/internal
  36. 72 app/internal を削除するだけでは駄目? • 理論上はそれで良い • ただし本番環境用のページから components/internal を うっかり参照してしまうと...

    ◦ ブラウザ向けのビルド成果物にそれが含まれてしまう • rm -rf components/internal しておくと... ◦ 本番環境向けにビルドした時に、ビルドエラーになる • ミスを防ぐために app/internal 以外も削除すべき