security-review
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chinese<!--
Reference material based on OWASP Cheat Sheet Series (CC BY-SA 4.0)
https://cheatsheetseries.owasp.org/
-->
<!--
参考资料基于OWASP cheat Sheet Series (CC BY-SA 4.0)
https://cheatsheetseries.owasp.org/
-->
Security Review Skill
安全审查技能
Identify exploitable security vulnerabilities in code. Report only HIGH CONFIDENCE findings—clear vulnerable patterns with attacker-controlled input.
识别代码中可被利用的安全漏洞。仅报告高可信度的发现——即存在攻击者可控输入的明确漏洞模式。
Scope: Research vs. Reporting
范围:研究与报告的区别
CRITICAL DISTINCTION:
- Report on: Only the specific file, diff, or code provided by the user
- Research: The ENTIRE codebase to build confidence before reporting
Before flagging any issue, you MUST research the codebase to understand:
- Where does this input actually come from? (Trace data flow)
- Is there validation/sanitization elsewhere?
- How is this configured? (Check settings, config files, middleware)
- What framework protections exist?
Do NOT report issues based solely on pattern matching. Investigate first, then report only what you're confident is exploitable.
关键区分:
- 报告对象:仅针对用户提供的特定文件、差异或代码
- 研究范围:整个代码库,以便在报告前建立足够的可信度
在标记任何问题之前,你必须研究代码库以了解:
- 该输入实际来自哪里?(追踪数据流)
- 其他地方是否存在验证/清理机制?
- 配置情况如何?(检查设置、配置文件、中间件)
- 框架有哪些防护措施?
请勿仅基于模式匹配报告问题。 先进行调查,仅报告你确信可被利用的问题。
Confidence Levels
可信度等级
| Level | Criteria | Action |
|---|---|---|
| HIGH | Vulnerable pattern + attacker-controlled input confirmed | Report with severity |
| MEDIUM | Vulnerable pattern, input source unclear | Note as "Needs verification" |
| LOW | Theoretical, best practice, defense-in-depth | Do not report |
| 等级 | 判断标准 | 操作 |
|---|---|---|
| 高 | 确认存在漏洞模式 + 攻击者可控输入 | 报告并标注严重性 |
| 中 | 存在漏洞模式,但输入来源不明确 | 记录为「需验证」 |
| 低 | 理论性问题、最佳实践、纵深防御建议 | 不报告 |
Do Not Flag
无需标记的情况
General Rules
通用规则
- Test files (unless explicitly reviewing test security)
- Dead code, commented code, documentation strings
- Patterns using constants or server-controlled configuration
- Code paths that require prior authentication to reach (note the auth requirement instead)
- 测试文件(除非明确要求审查测试代码的安全性)
- 死代码、注释代码、文档字符串
- 使用常量或服务器可控配置的模式
- 需要先通过身份验证才能访问的代码路径(需记录身份验证要求)
Server-Controlled Values (NOT Attacker-Controlled)
服务器可控值(非攻击者可控)
These are configured by operators, not controlled by attackers:
| Source | Example | Why It's Safe |
|---|---|---|
| Django settings | | Set via config/env at deployment |
| Environment variables | | Deployment configuration |
| Config files | | Server-side files |
| Framework constants | | Not user-modifiable |
| Hardcoded values | | Compile-time constants |
SSRF Example - NOT a vulnerability:
python
undefined这些值由运维人员配置,不受攻击者控制:
| 来源 | 示例 | 安全原因 |
|---|---|---|
| Django设置 | | 部署时通过配置/环境变量设置 |
| 环境变量 | | 部署配置项 |
| 配置文件 | | 服务器端文件 |
| 框架常量 | | 用户无法修改 |
| 硬编码值 | | 编译时常量 |
SSRF示例 - 非漏洞:
python
undefinedSAFE: URL comes from Django settings (server-controlled)
安全:URL来自Django设置(服务器可控)
response = requests.get(f"{settings.SEER_AUTOFIX_URL}{path}")
**SSRF Example - IS a vulnerability:**
```pythonresponse = requests.get(f"{settings.SEER_AUTOFIX_URL}{path}")
**SSRF示例 - 属于漏洞:**
```pythonVULNERABLE: URL comes from request (attacker-controlled)
存在漏洞:URL来自请求(攻击者可控)
response = requests.get(request.GET.get('url'))
undefinedresponse = requests.get(request.GET.get('url'))
undefinedFramework-Mitigated Patterns
框架已缓解的模式
Check language guides before flagging. Common false positives:
| Pattern | Why It's Usually Safe |
|---|---|
Django | Auto-escaped by default |
React | Auto-escaped by default |
Vue | Auto-escaped by default |
| ORM parameterizes queries |
| Parameterized query |
| Constant string, no user input |
Only flag these when:
- Django: ,
{{ var|safe }},{% autoescape off %}mark_safe(user_input) - React:
dangerouslySetInnerHTML={{__html: userInput}} - Vue:
v-html="userInput" - ORM: ,
.raw(),.extra()with string interpolationRawSQL()
标记前请查阅语言指南。常见误报:
| 模式 | 通常安全的原因 |
|---|---|
Django | 默认自动转义 |
React | 默认自动转义 |
Vue | 默认自动转义 |
| ORM自动参数化查询 |
| 参数化查询 |
| 常量字符串,无用户输入 |
仅在以下情况标记:
- Django: ,
{{ var|safe }},{% autoescape off %}mark_safe(user_input) - React:
dangerouslySetInnerHTML={{__html: userInput}} - Vue:
v-html="userInput" - ORM: 使用字符串插值的,
.raw(),.extra()RawSQL()
Review Process
审查流程
1. Detect Context
1. 识别上下文
What type of code am I reviewing?
| Code Type | Load These References |
|---|---|
| API endpoints, routes | |
| Frontend, templates | |
| File handling, uploads | |
| Crypto, secrets, tokens | |
| Data serialization | |
| External requests | |
| Business workflows | |
| GraphQL, REST design | |
| Config, headers, CORS | |
| CI/CD, dependencies | |
| Error handling | |
| Audit, logging | |
我正在审查的代码类型是什么?
| 代码类型 | 加载对应参考资料 |
|---|---|
| API端点、路由 | |
| 前端、模板 | |
| 文件处理、上传 | |
| 加密、密钥、令牌 | |
| 数据序列化 | |
| 外部请求 | |
| 业务流程 | |
| GraphQL、REST设计 | |
| 配置、请求头、CORS | |
| CI/CD、依赖 | |
| 错误处理 | |
| 审计、日志 | |
2. Load Language Guide
2. 加载语言指南
Based on file extension or imports:
| Indicators | Guide |
|---|---|
| |
| |
| |
| |
| |
根据文件扩展名或导入内容选择:
| 识别标识 | 指南 |
|---|---|
| |
| |
| |
| |
| |
3. Load Infrastructure Guide (if applicable)
3. 加载基础设施指南(如适用)
| File Type | Guide |
|---|---|
| |
| K8s manifests, Helm charts | |
| |
GitHub Actions, | |
| AWS/GCP/Azure configs, IAM | |
| 文件类型 | 指南 |
|---|---|
| |
| K8s清单、Helm图表 | |
| |
GitHub Actions, | |
| AWS/GCP/Azure配置、IAM | |
4. Research Before Flagging
4. 标记前先研究
For each potential issue, research the codebase to build confidence:
- Where does this value actually come from? Trace the data flow.
- Is it configured at deployment (settings, env vars) or from user input?
- Is there validation, sanitization, or allowlisting elsewhere?
- What framework protections apply?
Only report issues where you have HIGH confidence after understanding the broader context.
对于每个潜在问题,研究代码库以建立可信度:
- 该值实际来自哪里?追踪数据流。
- 它是部署时配置的(设置、环境变量)还是来自用户输入?
- 其他地方是否存在验证、清理或白名单机制?
- 适用哪些框架防护措施?
只有在了解更广泛的上下文后,确认具有高可信度的问题才可以报告。
5. Verify Exploitability
5. 验证可利用性
For each potential finding, confirm:
Is the input attacker-controlled?
| Attacker-Controlled (Investigate) | Server-Controlled (Usually Safe) |
|---|---|
| |
| |
| Hardcoded constants |
| Internal service URLs from config |
URL path segments: | Database content from admin/system |
| File uploads (content and names) | Signed session data |
| Database content from other users | Framework settings |
| WebSocket messages |
Does the framework mitigate this?
- Check language guide for auto-escaping, parameterization
- Check for middleware/decorators that sanitize
Is there validation upstream?
- Input validation before this code
- Sanitization libraries (DOMPurify, bleach, etc.)
对于每个潜在发现,确认:
输入是否由攻击者控制?
| 攻击者可控(需调查) | 服务器可控(通常安全) |
|---|---|
| |
| |
| 硬编码常量 |
| 配置中的内部服务URL |
URL路径段: | 管理员/系统写入的数据库内容 |
| 文件上传(内容和文件名) | 签名的会话数据 |
| 来自其他用户的数据库内容 | 框架设置 |
| WebSocket消息 |
框架是否已缓解该问题?
- 查阅语言指南了解自动转义、参数化查询机制
- 检查是否存在清理数据的中间件/装饰器
上游是否存在验证?
- 此代码之前是否有输入验证
- 是否使用清理库(DOMPurify、bleach等)
6. Report HIGH Confidence Only
6. 仅报告高可信度问题
Skip theoretical issues. Report only what you've confirmed is exploitable after research.
跳过理论性问题。仅报告经过研究后确认可被利用的问题。
Severity Classification
严重性分类
| Severity | Impact | Examples |
|---|---|---|
| Critical | Direct exploit, severe impact, no auth required | RCE, SQL injection to data, auth bypass, hardcoded secrets |
| High | Exploitable with conditions, significant impact | Stored XSS, SSRF to metadata, IDOR to sensitive data |
| Medium | Specific conditions required, moderate impact | Reflected XSS, CSRF on state-changing actions, path traversal |
| Low | Defense-in-depth, minimal direct impact | Missing headers, verbose errors, weak algorithms in non-critical context |
| 严重性 | 影响 | 示例 |
|---|---|---|
| Critical(严重) | 可直接利用,影响重大,无需身份验证 | RCE、可获取数据的SQL注入、身份验证绕过、硬编码密钥 |
| High(高) | 需满足特定条件才可利用,影响显著 | 存储型XSS、可访问元数据的SSRF、可访问敏感数据的IDOR |
| Medium(中) | 需满足特定条件,影响中等 | 反射型XSS、针对状态变更操作的CSRF、路径遍历 |
| Low(低) | 纵深防御问题,直接影响极小 | 缺失安全请求头、详细错误信息、非关键场景下的弱算法 |
Quick Patterns Reference
快速模式参考
Always Flag (Critical)
必须标记(Critical)
eval(user_input) # Any language
exec(user_input) # Any language
pickle.loads(user_data) # Python
yaml.load(user_data) # Python (not safe_load)
unserialize($user_data) # PHP
deserialize(user_data) # Java ObjectInputStream
shell=True + user_input # Python subprocess
child_process.exec(user) # Node.jseval(user_input) # 任意语言
exec(user_input) # 任意语言
pickle.loads(user_data) # Python
yaml.load(user_data) # Python(非safe_load)
unserialize($user_data) # PHP
deserialize(user_data) # Java ObjectInputStream
shell=True + user_input # Python subprocess
child_process.exec(user) # Node.jsAlways Flag (High)
必须标记(High)
innerHTML = userInput # DOM XSS
dangerouslySetInnerHTML={user} # React XSS
v-html="userInput" # Vue XSS
f"SELECT * FROM x WHERE {user}" # SQL injection
`SELECT * FROM x WHERE ${user}` # SQL injection
os.system(f"cmd {user_input}") # Command injectioninnerHTML = userInput # DOM XSS
dangerouslySetInnerHTML={user} # React XSS
v-html="userInput" # Vue XSS
f"SELECT * FROM x WHERE {user}" # SQL注入
`SELECT * FROM x WHERE ${user}` # SQL注入
os.system(f"cmd {user_input}") # 命令注入Always Flag (Secrets)
必须标记(密钥泄露)
password = "hardcoded"
api_key = "sk-..."
AWS_SECRET_ACCESS_KEY = "..."
private_key = "-----BEGIN"password = "hardcoded"
api_key = "sk-..."
AWS_SECRET_ACCESS_KEY = "..."
private_key = "-----BEGIN"Check Context First (MUST Investigate Before Flagging)
需先检查上下文(标记前必须调查)
undefinedundefinedSSRF - ONLY if URL is from user input, NOT from settings/config
SSRF - 仅当URL来自用户输入时标记,来自设置/配置的不标记
requests.get(request.GET['url']) # FLAG: User-controlled URL
requests.get(settings.API_URL) # SAFE: Server-controlled config
requests.get(f"{settings.BASE}/{x}") # CHECK: Is 'x' user input?
requests.get(request.GET['url']) # 标记:用户可控URL
requests.get(settings.API_URL) # 安全:服务器可控配置
requests.get(f"{settings.BASE}/{x}") # 检查:'x'是否为用户输入?
Path traversal - ONLY if path is from user input
路径遍历 - 仅当路径来自用户输入时标记
open(request.GET['file']) # FLAG: User-controlled path
open(settings.LOG_PATH) # SAFE: Server-controlled config
open(f"{BASE_DIR}/{filename}") # CHECK: Is 'filename' user input?
open(request.GET['file']) # 标记:用户可控路径
open(settings.LOG_PATH) # 安全:服务器可控配置
open(f"{BASE_DIR}/{filename}") # 检查:'filename'是否为用户输入?
Open redirect - ONLY if URL is from user input
开放重定向 - 仅当URL来自用户输入时标记
redirect(request.GET['next']) # FLAG: User-controlled redirect
redirect(settings.LOGIN_URL) # SAFE: Server-controlled config
redirect(request.GET['next']) # 标记:用户可控重定向
redirect(settings.LOGIN_URL) # 安全:服务器可控配置
Weak crypto - ONLY if used for security purposes
弱加密 - 仅当用于安全场景时标记
hashlib.md5(file_content) # SAFE: File checksums, caching
hashlib.md5(password) # FLAG: Password hashing
random.random() # SAFE: Non-security uses (UI, sampling)
random.random() for token # FLAG: Security tokens need secrets module
---hashlib.md5(file_content) # 安全:文件校验、缓存
hashlib.md5(password) # 标记:密码哈希
random.random() # 安全:非安全场景使用(UI、采样)
random.random() 生成令牌 # 标记:安全令牌需使用secrets模块
---Output Format
输出格式
markdown
undefinedmarkdown
undefinedSecurity Review: [File/Component Name]
安全审查:[文件/组件名称]
Summary
摘要
- Findings: X (Y Critical, Z High, ...)
- Risk Level: Critical/High/Medium/Low
- Confidence: High/Mixed
- 发现数量:X(Y个Critical,Z个High,...)
- 风险等级:Critical/High/Medium/Low
- 可信度:高/混合
Findings
发现结果
[VULN-001] [Vulnerability Type] (Severity)
[VULN-001] [漏洞类型](严重性)
- Location:
file.py:123 - Confidence: High
- Issue: [What the vulnerability is]
- Impact: [What an attacker could do]
- Evidence:
python
[Vulnerable code snippet] - Fix: [How to remediate]
- 位置:
file.py:123 - 可信度:高
- 问题描述:[漏洞具体内容]
- 影响:[攻击者可执行的操作]
- 证据:
python
[漏洞代码片段] - 修复建议:[修复方案]
Needs Verification
需验证项
[VERIFY-001] [Potential Issue]
[VERIFY-001] [潜在问题]
- Location:
file.py:456 - Question: [What needs to be verified]
If no vulnerabilities found, state: "No high-confidence vulnerabilities identified."
---- 位置:
file.py:456 - 疑问:[需要验证的内容]
如果未发现漏洞,请说明:"未识别到高可信度漏洞。"
---Reference Files
参考文件
Core Vulnerabilities (references/
)
references/核心漏洞(references/
)
references/| File | Covers |
|---|---|
| SQL, NoSQL, OS command, LDAP, template injection |
| Reflected, stored, DOM-based XSS |
| Authorization, IDOR, privilege escalation |
| Sessions, credentials, password storage |
| Algorithms, key management, randomness |
| Pickle, YAML, Java, PHP deserialization |
| Path traversal, uploads, XXE |
| Server-side request forgery |
| Cross-site request forgery |
| Secrets exposure, PII, logging |
| REST, GraphQL, mass assignment |
| Race conditions, workflow bypass |
| Prototype pollution, LLM injection, WebSocket |
| Headers, CORS, debug mode, defaults |
| Fail-open, information disclosure |
| Dependencies, build security |
| Audit failures, log injection |
| 文件 | 覆盖范围 |
|---|---|
| SQL、NoSQL、OS命令、LDAP、模板注入 |
| 反射型、存储型、DOM型XSS |
| 授权、IDOR、权限提升 |
| 会话、凭证、密码存储 |
| 算法、密钥管理、随机性 |
| Pickle、YAML、Java、PHP反序列化 |
| 路径遍历、文件上传、XXE |
| 服务器端请求伪造 |
| 跨站请求伪造 |
| 密钥泄露、PII、日志 |
| REST、GraphQL、批量赋值 |
| 竞争条件、流程绕过 |
| 原型污染、LLM注入、WebSocket |
| 请求头、CORS、调试模式、默认配置 |
| 故障开放、信息泄露 |
| 依赖、构建安全 |
| 审计失效、日志注入 |
Language Guides (languages/
)
languages/语言指南(languages/
)
languages/- - Django, Flask, FastAPI patterns
python.md - - Node, Express, React, Vue, Next.js
javascript.md - - Go-specific security patterns
go.md - - Rust unsafe blocks, FFI security
rust.md - - Spring, Java EE patterns
java.md
- - Django、Flask、FastAPI相关模式
python.md - - Node、Express、React、Vue、Next.js相关模式
javascript.md - - Go语言特定安全模式
go.md - - Rust不安全代码块、FFI安全
rust.md - - Spring、Java EE相关模式
java.md
Infrastructure (infrastructure/
)
infrastructure/基础设施指南(infrastructure/
)
infrastructure/- - Container security
docker.md - - K8s RBAC, secrets, policies
kubernetes.md - - IaC security
terraform.md - - Pipeline security
ci-cd.md - - AWS/GCP/Azure security
cloud.md
- - 容器安全
docker.md - - K8s RBAC、密钥、策略
kubernetes.md - - IaC安全
terraform.md - - 流水线安全
ci-cd.md - - AWS/GCP/Azure安全
cloud.md