本节摘要:安全开发生命周期(SDLC)把安全活动嵌进软件开发的每个阶段——需求定安全需求、设计做威胁建模、编码守规范、测试跑安全测试、上线走检查单;代码审计(Code Audit)是对代码库的系统性安全检查,人工审计与自动化工具互补。本节鉴定 SDL 的阶段要点与审计的方法论。承接 6.5 节的新战场,本节回到软件的生产现场——安全从"事后补"转向"源头造"的路径,通往 6.7 节的测试工具与供应链。
软件行业有一条反复被验证的成本曲线:一个缺陷在需求阶段修复的成本是一,编码阶段是数倍,测试阶段是十倍级,上线之后是百倍级——上线后的修复要经过紧急响应、版本发布、客户沟通,甚至触发 6.3 节的完整事件流程。安全缺陷完全遵循这条曲线,而且更陡:线上安全漏洞除了修复成本还有实际的暴露窗口(攻击者可不会等你排期)。
SDLC 的全部动机就是把安全活动左移:在缺陷最便宜的阶段抓住它。这不是道德倡议,是纯粹的成本工程。
需求阶段:把安全需求写进需求文档——认证要求、数据保护级别、合规约束(6.2 节的条款在这里变成需求项)。没有需求阶段的输入,后面的安全测试连"测什么"都不知道。
设计阶段:做威胁建模。对着设计图问四个问题(业界称为四问框架):要处理什么数据(资产)、谁会来攻击(威胁)、哪里会破(弱点)、破了怎么办(缓解)。1.3 节的攻击面分析与 5.1 节的信任边界在这里是最顺手的工具——设计评审时把信任边界画出来,每条边界上问"数据跨过它时谁验证谁"。
编码阶段:安全编码规范加框架兜底。2.3 节的三类漏洞各有标准解法(参数化、输出编码、限速),规范的最高形态不是让程序员背规则,而是默认框架与库里就长着安全写法——团队越依赖规范记忆,犯错率越高。
测试阶段:安全测试上场(6.7 节的 SAST/DAST 细讲),外加 3.4 节的渗透测试在重大版本前介入。
上线与运维:安全检查单(配置基线核对、密钥就位、日志接入)加持续的漏洞管理(6.4 节)。

代码审计是对代码库的系统性安全检查,目标是找出"写了但不应存在"的漏洞。它分两条路子,各自的长短板互补:
人工审计的优势在业务逻辑漏洞——权限校验绕过、支付金额的竞态条件、越权的数据访问链。这类问题不表现为固定代码模式(每个业务的逻辑都不一样),工具的规则库对它们天然失明,只有理解业务的人顺着"钱和权限的流向"读代码才能抓到。人工审计的性价比优化:不逐行读全库,沿"敏感操作入口"(登录、支付、文件、权限变更)追踪数据流,重点看"输入到危险操作之间的路径上有没有校验"。
工具审计的优势在已知模式——注入、XSS、硬编码密钥这类有稳定代码指纹的缺陷,工具扫得又快又全,且可以每次提交都跑。它的弱点恰是人工的强项:误报需要人复核,逻辑漏洞看不见。
两条路子在 6.6 的流水线里分工明确:工具审计自动化进 CI(下一节的 SAST),人工审计按风险节奏安排(核心模块变更时、重大版本前、或年度例行)。审计产出的不是"漏洞清单"就完事——每条发现要回到 SDL 的上游去问"为什么这类问题会进来",把答案变成规范或框架约束,让同类问题不再产生。这才是审计与 SDL 的闭环。
给审计排期留出修复预算。 审计发现若没有配套的修复排期,结果就是报告归档——和 6.1 节的风险评估同病。审计合同的正确形态是"审计加复验":修完之后审计方回来确认关闭,一轮才算完成。
审计范围按信任边界切。 全库审计贵而慢,务实的切法是按 5.1 节的信任边界定优先级:直接暴露的入口模块最高危,先审;内部工具类低危,后排。把预算花在刀刃上。
⚠️ 常见坑:把代码审计当成合规表演——"每年审一次,报告放抽屉"。审计的产出应该进入开发团队的缺陷知识库:同类问题历史上在哪里出现过、为什么、怎么防。没有沉淀的审计,第二年还会审出一模一样的问题。
💡 关键直觉:SDL 五阶段里设计阶段的威胁建模性价比最高——此刻改动只是一张图,越往后改动越贵;凡是"设计图上没画信任边界"的项目,后面每个阶段都会为这张缺图买单。
安全左移的第一站是需求评审。给评审人一张提问清单,八个问题问完,安全需求基本就齐了:
问一: 这个功能处理哪些数据? 分级是什么? (挂 6.2 节数据分级) 问二: 谁有资格使用? 没资格的人看到什么? (授权口径前置) 问三: 输入来自哪里? 哪些来源不可信? (挂 2.3 节信任边界) 问四: 有没有跨信任边界的写操作? 谁验证谁? 问五: 操作要不要留痕? 留给谁看? (审计需求前置) 问六: 失败或被滥用时, 最坏的画面是什么? (威胁建模四问入口) 问七: 有没有等价但更安全的实现方式? 问八: 合规上有没有新增义务? (个人信息、留存、跨境)
八个问题不要求逐字问,但评审纪要里要能看到它们被回答过的痕迹。问题六是入口——"最坏的画面"写出来后,威胁建模就有了靶子;写不出来,说明功能边界还没想清,那本身就是最大的发现。问题三与问题四对应 2.3 节的"信任边界画错"病根,在纸面上拦它只要改一行设计,上线后拦它要改半套系统。
审计发现的回灌机制再补一个具体做法:每季度把代码审计与渗透测试(6.7 节)的发现按"缺陷模式"归类,挑出重复出现最多的三类,写进团队的评审清单与框架默认配置。回灌的检验标准很简单——如果今年的审计还能发现和去年一模一样的问题,回灌机制就是空转。6.6 节说"审计的产出不是清单",这份季度归类就是那句话的操作化。
SDL 的最后一关是上线检查。十个检查项的最小集,逐项打勾再放行:
1 依赖清单已锁定, 无已知高危 2 静态扫描无未处置的高危发现 3 敏感配置走配置中心, 无硬编码密钥 4 日志接入聚合平台, 关键操作有留痕 5 权限按最小化配置, 默认账号已禁用 6 传输全链路加密, 内部调用无明文 7 备份与回滚方案验证过一次 8 告警规则随新功能更新(新接口新风险) 9 数据分级与存储位置符合分类要求 10 责任人(开发/运维/安全)三列齐全
十项设计的逻辑是"前三关技术、中四关运营、后三关兜底"。检查单的价值在它的不可跳过性——发布流程里把十项做成硬门禁(未勾选不允许点发布),它就是 SDL 的牙齿;做成挂在墙上的口号,它就是第八十五份没人读的文档。每次线上事故后回看检查单:哪一条本可以拦住这次事故,就把那一条加重一格——检查单和检测规则一样,要靠事件喂养才能长成靠谱的样子。
给开发负责人留一句选型建议:SDL 工具链(扫描、依赖检查、检查单)不必一步买齐,但"上线检查单硬门禁"这一件必须第一天就上线——它是 SDL 唯一零成本、立竿见影的部件,也是后续所有工具的挂载点。门禁立住了,扫描器接上来才有牙齿;门禁没有,再贵的工具也只是多几份没人看的报告。