privacy-review について
privacy-reviewは、アプリの個人データの取り扱いを評価するワークフロー型スキルです。コードレビューでは見落としやすい実行時の挙動をブラウザーで検証し、根拠付きの報告、修正案、回帰テストにつなげます。
主な機能
- 01個人データの流れと第三者の整理
- 02ブラウザーでの同意と追跡の検証
- 03個人データ漏えいの確認
- 04保存期間とユーザー権利の点検
- 05根拠と確信度を含む所見の作成
- 06修正案と YAML 回帰テストの提示
活用シーン
- 01製品公開前の同意フロー確認
- 02個人データ漏えいの可能性の調査
- 03サードパーティ分析と追跡の評価
- 04アカウントデータの取得・削除フローのテスト
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ shiplightai/ agent-skills --skill privacy-reviewインストール後、Claude Code で/privacy-reviewを入力して読み込まれたか確認します。
詳細
プライバシーレビュー
アプリケーションが個人データをどのように扱うかを評価します。データがどこで収集、処理、保存、送信され、漏えいする可能性があるかを確認します。このレビューでは、コードレビューだけでは見つからないプライバシー上の問題、つまり実行時のデータフロー、サードパーティによるトラッキング、コンソールやネットワークへの漏えい、同意の実装における不備を検出します。
使用するタイミング
次のような場合に /privacy-review を使用してください。
- アプリが個人情報(氏名、メールアドレス、住所など)を収集する場合
- GDPR/CCPA の対象地域で公開する前
- サードパーティの分析、トラッキング、マーケティングツールを追加する場合
- データインシデントやプライバシーに関する苦情の発生後
- 機微データ(健康、金融、生体情報)を扱う機能を構築する場合
- ユーザーデータを受け取るサードパーティ API と統合する場合
参照する標準
- GDPR — EU 一般データ保護規則(第 5、6、7、12~22、25、32 条)
- CCPA/CPRA — カリフォルニア州消費者プライバシー法
- OWASP Privacy Risks Top 10
- NIST Privacy Framework
- ISO 27701 — プライバシー情報マネジメント
- ePrivacy Directive — Cookie の同意要件
フェーズの概要
Phase 1: EDUCATE → Privacy principles and what we check
Phase 2: SCOPE → Map data flows, PII types, third parties
Phase 3: ANALYZE → Browser-based validation of privacy practices
Phase 4: REPORT → Findings with evidence and confidence scores
Phase 5: REMEDIATE → Fix guidance + YAML regression tests
フェーズ 1:理解を深める
重要な理由: GDPR の制裁金は 2023 年に 21 億ユーロに達しました。CCPA では、消費者はデータ侵害に対して訴訟を起こす権利を有し、消費者 1 人あたり、インシデント 1 件につき 100~750 ドルを請求できます。法令遵守にとどまらず、プライバシー侵害はユーザーの信頼を損ないます。消費者の 79%は、プライバシー侵害の後、そのブランドとの関わりをやめると回答しています。コードレビューでは見えないプライバシー上の問題も、実行時の挙動では明らかになることが多くあります。
このレビューでは、実行時に観察できるプライバシーの挙動、つまりユーザーがアプリを操作したときにブラウザー内で実際に何が起きるかに焦点を当てます。
フェーズ 2:範囲を定める
コンテキストを収集する
-
コードベースから自動検出する項目:
- ユーザー入力を収集するフォーム(登録、プロフィール、支払い、問い合わせ)
- 分析/トラッキング用スクリプト(Google Analytics、Mixpanel、Segment、Hotjar など)
- Cookie を設定するコードと Cookie 同意の仕組み
- PII を含む可能性のあるログ出力
- ユーザーデータを送信する API 呼び出し
- サードパーティ SDK と、データ共有の挙動
- プライバシーポリシーと利用規約のページ
-
ユーザーに質問する(一度に 1 つずつ):
- 対象 URL:アプリはどこで実行されていますか?
- データの種類:アプリはどのような個人データを収集しますか?(自動検出した内容を確認)
- 対象地域:ユーザーはどの地域にいますか?(GDPR/CCPA などが適用されるかどうかを判断します)
- サードパーティ:どの分析/トラッキング/マーケティングツールを使用していますか?(自動検出した内容を確認)
- 懸念事項:特に懸念しているプライバシー領域はありますか?(任意)
-
データフローマップを作成する:
- PII の入力ポイント(フォーム、URL パラメーター、インポート)
- PII の処理(クライアント側またはサーバー側)
- PII の保存先(Cookie、localStorage、サーバー DB)
- PII の送信先(API 呼び出し、サードパーティスクリプト)
- PII の表示先(プロフィールページ、管理パネル、ログ)
フェーズ 3:分析する
record_evidence: true を使用して new_session でブラウザーセッションを開き、該当するすべてのチェックカテゴリを実行します。
カテゴリー A:データ収集と同意(CON)
| チェック ID | チェック項目 | 標準 | 方法 |
|---|---|---|---|
| CON-01 | 必須ではない Cookie を設定する前に Cookie 同意バナーが表示される | ePrivacy / GDPR Art.7 | ページを読み込み、同意前にトラッキング Cookie が存在するか確認する |
| CON-02 | 同意前にトラッキングスクリプトが実行されない | ePrivacy / GDPR | ページを新規読み込み(同意なし)した際のネットワークリクエストを監視する |
| CON-03 | 同意を細かく設定できる(「すべて承認」だけではない) | GDPR Art.7 | 同意 UI にカテゴリー単位の選択肢があるか確認する |
| CON-04 | 同意を拒否すると、実際にトラッキングが防止される | GDPR Art.7 | すべて拒否し、トラッキング Cookie/リクエストがないことを確認する |
| CON-05 | 同意設定が保存され、反映される | GDPR Art.7 | 設定を選択し、ページを再読み込みして記憶されていることを確認する |
| CON-06 | 同意を撤回できる(変更/取り消し) | GDPR Art.7(3) | 最初に選択した後で同意を変更する方法を確認する |
| CON-07 | プライバシーポリシーにアクセスでき、リンクがある | GDPR Art.12-14 | フッター/同意バナーにプライバシーポリシーへのリンクがあるか確認する |
| CON-08 | データ収集が適切な範囲に限られている(不要な項目がない) | GDPR Art.5(1)(c) | フォームに、明示された目的に不要な項目がないか確認する |
ブラウザーでの検証: 新しいセッション(Cookie なし)でページを読み込みます。get_browser_console_logs を使用し、JavaScript でネットワークを監視します。同意操作の前後で Cookie を確認します。act を使用して同意バナーを操作します。
カテゴリー B:個人を特定できる情報の漏えい検出(LEAK)
| チェック ID | チェック項目 | 標準 | 方法 |
|---|---|---|---|
| LEAK-01 | URL パラメーターに個人を特定できる情報が含まれない | OWASP Privacy #1 | フォーム送信後やページ移動後の URL を確認する |
| LEAK-02 | ブラウザーのコンソールログに個人を特定できる情報が含まれない | OWASP Privacy #4 | get_browser_console_logs でメールアドレス、氏名、ID を確認する |
| LEAK-03 | localStorage/sessionStorage に個人を特定できる情報が含まれない | データ最小化 | クライアントストレージを調べ、個人データがないか確認する |
| LEAK-04 | ページのソース/コメントに個人を特定できる情報が含まれない | 情報漏えい | HTML コメントや非表示フィールドを確認する |
| LEAK-05 | エラーメッセージに個人を特定できる情報が含まれない | OWASP Privacy #7 | エラーを発生させ、メッセージにユーザーデータが含まれていないか確認する |
| LEAK-06 | Referer ヘッダーに個人を特定できる情報が含まれない | OWASP Privacy | Referrer-Policy を確認し、送信リクエストを調べる |
| LEAK-07 | メタタグや Open Graph に個人を特定できる情報が含まれない | 情報漏えい | 共有ページの <meta> にユーザー固有のデータがないか確認する |
| LEAK-08 | キャッシュされたレスポンス(ブラウザーキャッシュ)に個人を特定できる情報が含まれない | データ最小化 | 個人を特定できる情報を含むページの Cache-Control ヘッダーを確認する |
| LEAK-09 | 個人を特定できる情報がサードパーティのスクリプトに漏えいしない | GDPR Art.28 | アナリティクス/トラッキングのエンドポイントに送信されるデータを監視する |
| LEAK-10 | 機密フィールドで適切なオートコンプリートが設定されている | ユーザビリティ/プライバシー | パスワードやクレジットカードのフィールドにある autocomplete 属性を確認する |
ブラウザーでの検証: ユーザーの操作フローを順に進めます。各操作の後に、URL、コンソールログ、ストレージ、ネットワークリクエストを調べ、個人を特定できる情報のパターン(メールアドレスの正規表現、電話番号のパターン、SSN のパターンなど)がないか確認します。JavaScript を使用して performance.getEntries() を調べ、リクエスト URL を確認します。
Category C:サードパーティトラッキングのインベントリ(TRACK)
| Check ID | Check | Standard | Method |
|---|---|---|---|
| TRACK-01 | すべてのサードパーティスクリプトを一覧化する | GDPR Art.30 | すべての外部スクリプトのソースとドメインを列挙する |
| TRACK-02 | すべてのサードパーティスクリプトが文書化されている | Transparency | プライバシーポリシーと照合する |
| TRACK-03 | 不明または想定外のトラッキングピクセルがない | Privacy | 1x1 画像とビーコンリクエストを確認する |
| TRACK-04 | サードパーティ Cookie のインベントリ | ePrivacy | ドメインごとにすべての Cookie を列挙する |
| TRACK-05 | フィンガープリントスクリプトがない | Privacy | Canvas フィンガープリント、WebGL、AudioContext のプローブを確認する |
| TRACK-06 | サードパーティに送信するデータが適切な範囲内である | GDPR Art.5(1)(c) | アナリティクスのエンドポイントに送信されるペイロードを調べる |
| TRACK-07 | トラッキングが Do-Not-Track ヘッダーを尊重する | Best practice | DNT ヘッダーを設定し、トラッキングが引き続き実行されるか確認する |
ブラウザーでの検証: 新しいセッションでページを読み込みます。JavaScript を使用して、すべての <script> のソース、すべての Cookie ドメイン、外部ドメインへのすべてのネットワークリクエストを列挙します。フィンガープリント API(Canvas、WebGL、AudioContext)の使用を確認します。
Category D:データの保存と保持(STOR)
| Check ID | Check | Standard | Method |
|---|---|---|---|
| STOR-01 | 機密データが転送中に暗号化されている(HTTPS) | GDPR Art.32 | すべてのリソース URL が HTTPS を使用しているか確認する |
| STOR-02 | セッションデータに適切な有効期限が設定されている | Data minimization | Cookie/トークンの有効期限を確認する |
| STOR-03 | Cookie に過剰なデータが含まれていない | Data minimization | Cookie のサイズと内容を確認する |
| STOR-04 | クライアント側のストレージが最小限である | Data minimization | localStorage/sessionStorage の内容を監査する |
| STOR-05 | 機密性の高いフォームデータが履歴に保存されない | Privacy | 機密性の高いフォームが GET ではなく POST を使用しているか確認する |
| STOR-06 | ログアウト後にブラウザーの戻るボタンで機密データが表示されない | Session management | ログアウトして戻るボタンを押し、キャッシュされた機密コンテンツがないか確認する |
ブラウザーでの検証: すべての Cookie(名前、値、ドメイン、有効期限、フラグ)を調べます。localStorage/sessionStorage を確認します。ログアウト後の戻るボタンの動作をテストします。
Category E:ユーザーの権利の実装(RIGHTS)
| Check ID | Check | Standard | Method |
|---|---|---|---|
| RIGHTS-01 | ユーザーが自身のデータにアクセスできる(データエクスポート) | GDPR Art.15 / CCPA | データエクスポート機能を見つけてテストする |
| RIGHTS-02 | ユーザーがアカウント/データを削除できる | GDPR Art.17 | アカウント削除の手順を見つけて確認する |
| RIGHTS-03 | ユーザーが個人情報を更新できる | GDPR Art.16 | プロフィール編集機能をテストする |
| RIGHTS-04 | データ販売のオプトアウト手段(CCPA) | CCPA §1798.120 | 「Do Not Sell」リンクがあるか確認する |
| RIGHTS-05 | アカウントが完全に削除される(単なる無効化ではない) | GDPR Art.17 | アカウントを削除し、データが削除されたことを確認する(プロフィール URL を確認) |
ブラウザーでの検証: アカウント設定に移動し、データエクスポート、プロフィール編集、アカウント削除の各手順をテストします。それぞれの権利を利用でき、機能することを確認します。
Phase 4:レポート
shiplight/reports/privacy-review-{date}.md に保存する構造化レポートを生成します:
# Privacy Review Report
**Date:** {date}
**URL:** {url}
**PII types handled:** {list}
**Jurisdictions:** {GDPR, CCPA, etc.}
**Third parties detected:** {count and list}
## Overall Score: {X}/10 | Confidence: {X}%
## Score Breakdown
| Category | Score | Findings |
|----------|-------|----------|
| Consent (CON) | 5/10 | 1 critical, 2 high |
| PII Leakage (LEAK) | 7/10 | 1 high, 1 medium |
| Tracking Inventory (TRACK) | 4/10 | 2 high, 1 medium |
| Data Storage (STOR) | 8/10 | 1 medium |
| User Rights (RIGHTS) | 6/10 | 1 high, 1 medium |
## Data Flow Map
(visual representation of PII flows through the application)
## Third-Party Tracking Inventory
| Domain | Type | Cookies Set | Data Sent | Consent Required |
|--------|------|-------------|-----------|-----------------|
| google-analytics.com | Analytics | _ga, _gid | Page URL, user agent | Yes |
| ... | | | | |
## Findings
(structured findings with evidence, severity, confidence)
信頼度スコア
- 90-100%:ブラウザーで検証済み — コンソール、URL、またはネットワークリクエストで PII を確認
- 70-89%:ストレージ/ヘッダーの調査による強い証拠
- 50-69%:コードレベルのパターン一致。実行時に現れない場合があります
- 50% 未満:報告しないでください
Phase 5:修正
1. 修正のガイダンス(例)
#### LEAK-01: Email address in URL parameter after form submit
**Risk:** PII in URL is logged by servers, proxies, browser history, and analytics
**File:** src/pages/search.tsx:34
**Current:** `router.push(`/results?email=${email}`)`
**Fix:** Use POST request or session state
- `router.push('/results')` with email in request body or session
- Add `Referrer-Policy: no-referrer` header as defense-in-depth
2. YAML 回帰テスト
- name: leak-01-no-pii-in-urls
description: Verify email addresses are not exposed in URL parameters
severity: high
standard: OWASP-Privacy-1
steps:
- URL: /search
- intent: Enter email in search form
action: fill
locator: "getByLabel('Email')"
value: "[email protected]"
- intent: Submit the search form
action: click
locator: "getByRole('button', { name: 'Search' })"
- WAIT_UNTIL: Search results are displayed
timeout_seconds: 15
- description: Assert no email address appears in the URL
js: |
const url = page.url();
if (/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/.test(url)) {
throw new Error(`PII found in URL: ${url}`);
}
- VERIFY: No email addresses appear in the browser URL
すべての YAML テストを shiplight/tests/privacy-review.test.yaml に保存します。
ヒント
- 同意動作を正確にテストするには、新しいブラウザーセッション(Cookie が保存されていない状態)を使用します
- 検索する PII パターン:メールアドレス(
@)、電話番号(\d{3}[-.]?\d{3}[-.]?\d{4})、SSN、クレジットカード番号、テストアカウントの名前 - サードパーティ製スクリプトはほかのスクリプトを読み込むことが多いため、連鎖的な読み込みを確認します
get_browser_console_logsで、開発者がデバッグログに残した PII が見つかることがよくあります- 同意を拒否した場合と受け入れた場合の両方をテストします。どちらの経路も重要です
close_sessionでセッションを閉じ、証拠としてgenerate_html_reportを使用します