关于 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 — 欧盟《通用数据保护条例》(第 5、6、7、12-22、25、32 条)
- CCPA/CPRA —《加利福尼亚州消费者隐私法》
- OWASP 隐私风险十大项
- NIST 隐私框架
- ISO 27701 — 隐私信息管理
- 《ePrivacy 指令》 — 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 赋予消费者因数据泄露提起诉讼的权利(每位消费者每起事件可获 100 至 750 美元赔偿)。除了合规要求之外,侵犯隐私还会削弱用户信任——79% 的消费者表示,品牌发生隐私泄露后,他们会停止与该品牌互动。许多隐私问题在代码审查中难以察觉,却会在运行时行为中显而易见。
本审查侧重于可观察到的运行时隐私行为——用户与应用互动时,浏览器中实际发生的情况。
阶段 2:确定范围
收集背景信息
-
从代码库自动检测:
- 收集用户输入的表单(注册、个人资料、付款、联系)
- 分析/追踪脚本(Google Analytics、Mixpanel、Segment、Hotjar 等)
- 设置 Cookie 的代码和 Cookie 同意机制
- 可能包含 PII 的日志语句
- 传输用户数据的 API 调用
- 第三方 SDK 及其数据共享行为
- 隐私政策和服务条款页面
-
逐项询问用户:
- 目标 URL:应用运行在哪里?
- 数据类型:应用会收集哪些个人数据?(根据自动检测结果确认)
- 适用地区:用户身处哪些地区?(用于确定 GDPR/CCPA 或其他法规是否适用)
- 第三方服务:使用了哪些分析/追踪/营销工具?(根据自动检测结果确认)
- 已知疑虑:是否担心任何特定的隐私问题?(可选)
-
构建数据流图:
- PII 输入点(表单、URL 参数、导入)
- PII 处理方式(客户端或服务器端)
- PII 存储位置(Cookie、localStorage、服务器数据库)
- PII 传输方式(API 调用、第三方脚本)
- PII 展示位置(个人资料页面、管理面板、日志)
阶段 3:分析
使用 new_session 打开浏览器会话,并设置 record_evidence: true。运行所有适用的检查类别。
类别 A:数据收集与同意(CON)
| 检查 ID | 检查项 | 标准 | 方法 |
|---|---|---|---|
| CON-01 | 设置非必要 Cookie 前显示 Cookie 同意横幅 | ePrivacy / GDPR Art.7 | 加载页面,检查是否在获得同意前就存在跟踪 Cookie |
| CON-02 | 获得同意前不触发跟踪脚本 | ePrivacy / GDPR | 在全新页面加载时(尚未给予同意)监控网络请求 |
| CON-03 | 同意选项细化(不只是“全部接受”) | GDPR Art.7 | 检查同意界面是否提供类别级选项 |
| 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 | meta 标签或 Open Graph 中不包含个人身份信息 | 信息泄漏 | 检查共享页面上的 <meta> 是否包含特定用户的数据 |
| LEAK-08 | 缓存响应(浏览器缓存)中不包含个人身份信息 | 数据最小化 | 检查包含个人身份信息的页面上的 Cache-Control 标头 |
| LEAK-09 | 不向第三方脚本泄漏个人身份信息 | GDPR Art.28 | 监控发送到分析/跟踪端点的数据 |
| LEAK-10 | 敏感字段的自动填充设置恰当 | 易用性/隐私 | 检查密码、信用卡字段上的 autocomplete 属性 |
浏览器验证: 按照用户流程逐步操作。每次操作后,检查 URL、控制台日志、存储和网络请求中是否存在个人身份信息模式(电子邮件正则表达式、电话号码模式、SSN 模式等)。使用 JavaScript 检查 performance.getEntries() 中的请求 URL。
类别 C:第三方跟踪清单(TRACK)
| 检查 ID | 检查项 | 标准 | 方法 |
|---|---|---|---|
| TRACK-01 | 清点所有第三方脚本 | GDPR Art.30 | 列出所有外部脚本来源及其域名 |
| TRACK-02 | 记录所有第三方脚本 | 透明度 | 与隐私政策交叉核对 |
| TRACK-03 | 不存在未知或意外的跟踪像素 | 隐私 | 检查 1x1 图片和信标请求 |
| TRACK-04 | 第三方 Cookie 清单 | ePrivacy | 按域名列出所有 Cookie |
| TRACK-05 | 不存在指纹识别脚本 | 隐私 | 检查 Canvas 指纹识别、WebGL、AudioContext 探测 |
| TRACK-06 | 发送给第三方的数据符合比例原则 | GDPR Art.5(1)(c) | 检查发送到分析端点的数据载荷 |
| TRACK-07 | 跟踪遵循 Do-Not-Track 标头 | 最佳实践 | 设置 DNT 标头,检查跟踪是否仍会触发 |
浏览器验证: 使用全新会话加载页面。使用 JavaScript 枚举所有 <script> 来源、所有 Cookie 域名,以及所有发往外部域名的网络请求。检查是否使用指纹识别 API(Canvas、WebGL、AudioContext)。
类别 D:数据存储与保留(STOR)
| 检查 ID | 检查项 | 标准 | 方法 |
|---|---|---|---|
| STOR-01 | 敏感数据在传输过程中经过加密(HTTPS) | GDPR Art.32 | 检查所有资源 URL 是否使用 HTTPS |
| STOR-02 | 会话数据的过期时间恰当 | 数据最小化 | 检查 Cookie/令牌的过期时间 |
| STOR-03 | Cookie 中没有过量数据 | 数据最小化 | 检查 Cookie 的大小和内容 |
| STOR-04 | 客户端存储的数据量最少 | 数据最小化 | 审核 localStorage/sessionStorage 内容 |
| STOR-05 | 敏感表单数据不会保留在历史记录中 | 隐私 | 检查敏感表单是否使用 POST,而非 GET |
| STOR-06 | 注销后,浏览器后退按钮不会显示敏感数据 | 会话管理 | 注销后按后退按钮,检查是否有缓存的敏感内容 |
浏览器验证: 检查所有 Cookie(名称、值、域名、过期时间、标志)。检查 localStorage/sessionStorage。测试注销后按后退按钮的行为。
类别 E:用户权利落实(RIGHTS)
| 检查 ID | 检查项 | 标准 | 方法 |
|---|---|---|---|
| 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) |
浏览器验证: 前往账户设置,测试数据导出、个人资料编辑和账户删除流程。确认每项权利都可以访问且功能正常。
阶段 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%:不要报告
阶段 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生成证据