「代码审查」这四个字很容易写虚。所以这篇不谈方法论,直接把我们扫描器里真跑着的 15 条判据摊出来:10 条安全问题(SEC)+ 5 条坏味道(SMELL),每条带编号、级别、命中条件和改法。
安全类(SEC)
Critical:能直接走通的那种
- SEC001
eval()—— 把字符串当代码执行,任意代码执行风险。改法:用ast.literal_eval或白名单映射表。 - SEC002
exec()—— 同上,且更难静态分析。改法:重构成显式的函数表,别用字符串拼代码。 - SEC003
pickle.load()—— 反序列化不可信数据可直接执行代码。改法:换 JSON / MessagePack,或只加载自己签名的数据。 - SEC005 SQL 字符串拼接 —— 注入。判据看的是
execute的参数是不是 f-string、%、.format()或字符串相加。改法:参数化查询。 - SEC006
shell=True—— 命令注入。改法:参数传列表,shell=False。 - SEC007 硬编码 API 密钥 —— 长串
sk-开头的密钥或api_key = "..."。改法:环境变量或密钥管理服务,并立刻轮换已经写进代码的那一把。 - SEC010 模板里直接嵌入变量 ——
<%= 变量 %>这类写法有 XSS / 模板注入风险。改法:走模板引擎的转义过滤器。
High:明确的缺陷,但不一定能直接走通
- SEC004
yaml.load()未指定 Loader —— 默认 Loader 可以构造任意 Python 对象。改法:yaml.safe_load()。 - SEC008 硬编码密码 ——
password = "..."形态。改法:同上,配置与代码分离并轮换。 - SEC009 用
assert做数据校验 —— 生产环境跑python -O时 assert 会被整段优化掉,校验直接消失。改法:显式if加抛异常。
坏味道类(SMELL)
- SMELL001 裸 except —— 连
SystemExit、KeyboardInterrupt一起吞掉,出问题时什么都看不见。改法:指定异常类型。 - SMELL002 可变默认参数 ——
def f(x=[])的默认值在多次调用间共享,会越用越长。改法:默认None,函数体内初始化。 - SMELL003
global滥用 —— 函数和全局状态耦合,测不了也没法并行跑。改法:参数传入、结果返回。 - SMELL004 超长函数 / 遗留调试输出 —— 一个函数干了十几件事,改一处要读完全部;以及生产代码里留下的
console.log。改法:按职责拆分,日志走日志框架。 - SMELL005 重复代码块 /
var声明 —— 复制粘贴出来的分支,和 JS 里var的变量提升。改法:抽公共函数,用let/const。
为什么是这 15 条
先交代出处,因为我们是新工作室,真实成交订单是 0,编不出「跑了几百个项目、命中率多少」这种样本量。这 15 条的来源只有两样你能自己去核对的东西:
- 公开安全规范里对得上的条目:CWE 弱点分类、OWASP 那几类经典注入与反序列化问题
- 我们拿自己上线的站点做真机审计时,真实踩到过并修掉的坑
分级的意义在处置顺序:Critical 先修,因为它能直接走通;坏味道不致命,但会拖慢后面排障的速度。
还有一句要说在前头:这 15 条是我们承诺「逐条给结论」的下限,不是安全的全部。一条没命中不等于这个文件没问题——业务逻辑越权、权限模型写错、依赖包本身有漏洞,都不在这 15 条里。想要更宽的覆盖,得走人工逐行审查。
这三档怎么用
- ¥9.9 代码体检:单文件,跑其中的九条判据,Top3 由人过一遍确认不是误报
- 代码审查 + 安全审计(¥299 起):这 15 条全跑,报告按严重级分类,每条带文件路径、行号和修复建议
- 单文件深度审查(¥99):逐行级,机器扫不出来的逻辑问题由人来看
交付时限页面上不写数——每一单的时限写在确认邮件里,逐单确认。想看报告长什么样,案例与样板页摊着。