Loading...
Loading...
Compare original and translation side by side
/privacy-review/privacy-reviewPhase 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 testsPhase 1: EDUCATE → 隐私原则及审查内容说明
Phase 2: SCOPE → 梳理数据流、PII类型、第三方服务
Phase 3: ANALYZE → 基于浏览器验证隐私实践
Phase 4: REPORT → 包含证据和置信度评分的审查结果
Phase 5: REMEDIATE → 修复指南 + YAML回归测试Why this matters: GDPR fines reached €2.1B in 2023. CCPA gives consumers the right to sue for data breaches ($100-$750 per consumer per incident). Beyond compliance, privacy violations erode user trust — 79% of consumers say they'd stop engaging with a brand after a privacy breach. Many privacy issues are invisible in code review but obvious in runtime behavior.
重要性说明: 2023年GDPR罚款总额达21亿欧元。CCPA赋予消费者针对数据泄露提起诉讼的权利(每起事件每位消费者可获100-750美元赔偿)。除合规要求外,隐私违规会损害用户信任——79%的消费者表示在遭遇隐私泄露后会停止与品牌互动。许多隐私问题在代码审查中不可见,但在运行时行为中会暴露无遗。
new_sessionrecord_evidence: truenew_sessionrecord_evidence: true| Check ID | Check | Standard | Method |
|---|---|---|---|
| CON-01 | Cookie consent banner shown before setting non-essential cookies | ePrivacy / GDPR Art.7 | Load page, check if tracking cookies exist before consent |
| CON-02 | No tracking scripts fire before consent | ePrivacy / GDPR | Monitor network requests on fresh page load (no consent given) |
| CON-03 | Consent is granular (not just "accept all") | GDPR Art.7 | Check consent UI for category-level options |
| CON-04 | Rejecting consent actually prevents tracking | GDPR Art.7 | Reject all, verify no tracking cookies/requests |
| CON-05 | Consent preference is persisted and respected | GDPR Art.7 | Set preference, reload page, verify it's remembered |
| CON-06 | Consent can be withdrawn (modify/revoke) | GDPR Art.7(3) | Find mechanism to change consent after initial choice |
| CON-07 | Privacy policy is accessible and linked | GDPR Art.12-14 | Check for privacy policy link in footer/consent banner |
| CON-08 | Data collection is proportionate (no unnecessary fields) | GDPR Art.5(1)(c) | Review forms for fields not needed for stated purpose |
get_browser_console_logsact| 检查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) | 检查表单是否包含非必要字段 |
get_browser_console_logsact| Check ID | Check | Standard | Method |
|---|---|---|---|
| LEAK-01 | No PII in URL parameters | OWASP Privacy #1 | Check URLs after form submissions, navigation |
| LEAK-02 | No PII in browser console logs | OWASP Privacy #4 | Check |
| LEAK-03 | No PII in localStorage/sessionStorage | Data minimization | Inspect client storage for personal data |
| LEAK-04 | No PII in page source/comments | Information leak | Check HTML comments, hidden fields |
| LEAK-05 | No PII in error messages | OWASP Privacy #7 | Trigger errors, check for user data in messages |
| LEAK-06 | No PII in Referer headers | OWASP Privacy | Check Referrer-Policy, inspect outbound requests |
| LEAK-07 | No PII in meta tags or Open Graph | Information leak | Check |
| LEAK-08 | No PII in cached responses (browser cache) | Data minimization | Check Cache-Control headers on pages with PII |
| LEAK-09 | No PII leaked to third-party scripts | GDPR Art.28 | Monitor data sent to analytics/tracking endpoints |
| LEAK-10 | Autocomplete appropriate on sensitive fields | Usability/Privacy | Check |
performance.getEntries()| 检查ID | 检查内容 | 参考标准 | 验证方法 |
|---|---|---|---|
| LEAK-01 | URL参数中无PII | OWASP Privacy #1 | 检查表单提交、导航后的URL |
| LEAK-02 | 浏览器控制台日志中无PII | OWASP Privacy #4 | 检查 |
| LEAK-03 | localStorage/sessionStorage中无PII | 数据最小化原则 | 检查客户端存储中的个人数据 |
| LEAK-04 | 页面源码/注释中无PII | 信息泄露防护 | 检查HTML注释、隐藏字段 |
| LEAK-05 | 错误信息中无PII | OWASP Privacy #7 | 触发错误,检查信息中是否包含用户数据 |
| LEAK-06 | Referer请求头中无PII | OWASP Privacy | 检查Referrer-Policy,查看出站请求 |
| LEAK-07 | 元标签或Open Graph中无PII | 信息泄露防护 | 检查共享页面的 |
| LEAK-08 | 缓存响应(浏览器缓存)中无PII | 数据最小化原则 | 检查含PII页面的Cache-Control请求头 |
| LEAK-09 | 无PII泄露至第三方脚本 | GDPR Art.28 | 监控发送至分析/追踪端点的数据 |
| LEAK-10 | 敏感字段自动补全设置合理 | 可用性/隐私性 | 检查密码、信用卡字段的 |
performance.getEntries()| Check ID | Check | Standard | Method |
|---|---|---|---|
| TRACK-01 | Inventory all third-party scripts | GDPR Art.30 | List all external script sources and their domains |
| TRACK-02 | All third-party scripts are documented | Transparency | Cross-reference with privacy policy |
| TRACK-03 | No unknown/unexpected tracking pixels | Privacy | Check for 1x1 images, beacon requests |
| TRACK-04 | Third-party cookies inventory | ePrivacy | List all cookies by domain |
| TRACK-05 | No fingerprinting scripts | Privacy | Check for canvas fingerprint, WebGL, AudioContext probing |
| TRACK-06 | Data sent to third parties is proportionate | GDPR Art.5(1)(c) | Inspect payloads to analytics endpoints |
| TRACK-07 | Tracking respects Do-Not-Track header | Best practice | Set DNT header, check if tracking still fires |
<script>| 检查ID | 检查内容 | 参考标准 | 验证方法 |
|---|---|---|---|
| TRACK-01 | 梳理所有第三方脚本清单 | GDPR Art.30 | 列出所有外部脚本来源及其域名 |
| TRACK-02 | 所有第三方脚本均已记录 | 透明度要求 | 与隐私政策交叉核对 |
| TRACK-03 | 无未知/意外追踪像素 | 隐私防护 | 检查1x1图片、信标请求 |
| TRACK-04 | 第三方Cookie清单 | ePrivacy | 按域名列出所有Cookie |
| TRACK-05 | 无指纹识别脚本 | 隐私防护 | 检查是否存在画布指纹、WebGL、AudioContext探测 |
| TRACK-06 | 发送至第三方的数据符合比例原则 | GDPR Art.5(1)(c) | 检查分析端点的负载内容 |
| TRACK-07 | 追踪行为尊重Do-Not-Track请求头 | 最佳实践 | 设置DNT请求头,检查追踪是否仍触发 |
<script>| Check ID | Check | Standard | Method |
|---|---|---|---|
| STOR-01 | Sensitive data encrypted in transit (HTTPS) | GDPR Art.32 | Check all resource URLs use HTTPS |
| STOR-02 | Session data has appropriate expiry | Data minimization | Check cookie/token expiration times |
| STOR-03 | No excessive data in cookies | Data minimization | Check cookie sizes and contents |
| STOR-04 | Client-side storage is minimal | Data minimization | Audit localStorage/sessionStorage contents |
| STOR-05 | Sensitive form data not persisted in history | Privacy | Check if sensitive forms use POST, not GET |
| STOR-06 | Browser back button doesn't show sensitive data after logout | Session management | Logout, press back, check for cached sensitive content |
| 检查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 | 登出后浏览器返回按钮不显示敏感数据 | 会话管理 | 登出后点击返回按钮,检查是否缓存敏感内容 |
| Check ID | Check | Standard | Method |
|---|---|---|---|
| RIGHTS-01 | Users can access their data (data export) | GDPR Art.15 / CCPA | Find and test data export feature |
| RIGHTS-02 | Users can delete their account/data | GDPR Art.17 | Find and verify account deletion flow |
| RIGHTS-03 | Users can update their personal information | GDPR Art.16 | Test profile edit functionality |
| RIGHTS-04 | Opt-out mechanism for data selling (CCPA) | CCPA §1798.120 | Check for "Do Not Sell" link |
| RIGHTS-05 | Account deletion is complete (not just deactivation) | GDPR Art.17 | Delete account, verify data is removed (check profile URL) |
| 检查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) |
shiplight/reports/privacy-review-{date}.mdundefinedshiplight/reports/privacy-review-{date}.mdundefined| 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 |
| 类别 | 评分 | 发现问题 |
|---|---|---|
| 授权(CON) | 5/10 | 1个严重问题,2个高风险问题 |
| PII泄露(LEAK) | 7/10 | 1个高风险问题,1个中风险问题 |
| 追踪清单(TRACK) | 4/10 | 2个高风险问题,1个中风险问题 |
| 数据存储(STOR) | 8/10 | 1个中风险问题 |
| 用户权利(RIGHTS) | 6/10 | 1个高风险问题,1个中风险问题 |
| Domain | Type | Cookies Set | Data Sent | Consent Required |
|---|---|---|---|---|
| google-analytics.com | Analytics | _ga, _gid | Page URL, user agent | Yes |
| ... |
| 域名 | 类型 | 设置的Cookie | 发送的数据 | 是否需要授权 |
|---|---|---|---|---|
| google-analytics.com | 分析工具 | _ga, _gid | 页面URL、用户代理 | 是 |
| ... |
undefinedundefinedundefinedundefinedrouter.push()router.push('/results')Referrer-Policy: no-referrerundefinedrouter.push()router.push('/results')Referrer-Policy: no-referrerundefined- 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: "test@example.com"
- 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 URLshiplight/tests/privacy-review.test.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: "test@example.com"
- 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 URLshiplight/tests/privacy-review.test.yaml@\d{3}[-.]?\d{3}[-.]?\d{4}get_browser_console_logsclose_sessiongenerate_html_report@\d{3}[-.]?\d{3}[-.]?\d{4}get_browser_console_logsclose_sessiongenerate_html_report