资讯动态

需求阶段威胁建模实战:安全左移怎么落地才不走过场

发布时间:2026/10/15 4:46:57 来源:尧图企业网站定制
我见过太多开发团队把安全测试当成上线前的压轴戏提测之后扫描器跑一轮漏洞列表甩过来开发打开一看全是需求阶段没想清楚的设计缺陷。这种事后补漏的滋味谁做谁知道。所以这几年“安全左移”被反复提起但它不该只是口号落到最前端是一个非常具体的动作——需求阶段做威胁建模。这篇文章就把这件事的完整思路、实操步骤和踩坑记录一次性盘清楚。如果你正打算在团队里推动安全左移或者刚被叫去牵头搞威胁建模这篇文章应该能帮你少走不少弯路。1. 为什么这笔账算到最后需求阶段的威胁建模最划算1.1 安全左移不是新概念为什么大家还是做不到“安全左移”这四个字绝大多数人都认同但能真正做到的团队不多。我见过不少团队号称在做安全左移实际动作只是请安全工程师提前参加了一次评审会平时依然各干各的。原因不在意愿而在于安全工程师在需求阶段根本没有可以落手的抓手。开发阶段有代码测试阶段有系统安全工程师可以做代码审计、可以做渗透测试、可以跑扫描器。需求阶段有什么只有一份PRD或者用户故事上面写满了业务流程没有一行是安全属性。很多安全工程师面对这种材料第一反应是不知道从哪儿问起产品经理也不知道该怎么回答。于是需求评审变成了“安全确认无异议”威胁建模也就沦为走过场。要让安全左移真正生效第一步就是在需求阶段建立一套所有人都能用的分析语言。威胁建模恰恰就是这套语言它不要求你立刻发现漏洞而是要求你顺着需求把系统内外的角色、数据和信任关系捋一遍再针对性地问“如果这里被恶意利用会怎样”。做完这一步安全需求就会自然浮现出来不需要谁拍脑袋。1.2 修复成本曲线需求阶段改一个决定能省下多少返工先聊一个多数人都听过但很少认真算过的数字。行业里普遍接受一条缺陷修复成本曲线需求阶段修复一个缺陷的成本系数大约是1编码阶段大约是10测试阶段大约是20到50上线之后可能是100甚至更高。不同团队的具体数字会有差异但量级基本不会错。为什么跨度这么大因为阶段越靠后修改一个决定要牵动的东西越多。举个支付类项目的例子需求里只写了“用户可以通过手机找回密码”。在需求阶段如果多问一句“手机号要不要验证、验证码能不能重试”修改成本仅仅是改几行文字描述。可如果系统已经上线才发现找回密码逻辑允许攻击者无限重试验证码要改的不只是页面逻辑还有后端的频率限制、操作日志、风控规则、客服申诉流程甚至要考虑在途的恶意请求怎么追溯。一次改动的成本差了不止一个量级。发现阶段相对修复成本以找回密码需求为例需求阶段约1改一句验证码规则描述编码阶段约10改接口加频率限制重新联调测试阶段约20到50改完还要补回归测试用例上线后100甚至更高数据修复加灰度加客服联动全局所以需求阶段做威胁建模本质上是用一轮头脑风暴去买断后面可能出现的返工。它不是“额外增加工作量”而是把本来就要花的修复成本提前挪到最便宜的时间窗口里花掉。理解这一点你就明白为什么越是复杂的业务系统越值得在这个阶段多花半小时到一小时。1.3 需求阶段的威胁建模产出物不止是一张威胁清单很多人以为威胁建模的产出物就是一张“威胁列表加修复建议”。实际跑过一次之后你会发现更值钱的产出物是三个首先是安全需求条目这是要写回用户故事卡的其次是风险决策记录哪些威胁本次接受、哪些必须修理由是什么都要留底最后是待确认问题清单需求描述里讲不明白、需要产品方补充澄清的点也要记下来后面去问。这三个产出物让威胁建模从“一次讨论”变成“一份基线”。下次同一个模块有需求变更时直接翻上次的记录就能知道哪些点动过、哪些风险已经被接受。没有这份基线每次建模都要从头再来团队很快就会疲倦。2. 建模之前先看懂需求角色、数据、信任边界三个输入威胁建模不是凭空想象。它的原材料就是需求文档里被当成常识忽略掉的信息。我习惯把输入收敛成三个问题谁在用这个功能功能经手了哪些数据哪些环节是外部不可信的这三个问题覆盖了大多数需求也是下面整条分析链的地基。2.1 谁在用别把“用户”当成一个角色第一次做需求阶段威胁建模时最常见的错误是把“用户”当成单一角色。实际上一个真实系统里的角色至少可以拆成未登录用户、普通登录用户、管理员、客服、第三方系统。每个角色能碰到的数据和操作都不一样威胁自然也不一样。以“用户找回密码”为例普通用户能发起重置请求管理员可能能看到重置记录客服在协助用户时可能需要临时查看验证信息第三方短信网关直接触达用户手机。如果只写一个“用户”你就永远不会去问“客服能不能帮用户重置密码”“重置密码的操作是否要留痕”。角色列表一旦写不完整后面设计权限模型时一定会出问题。所以建模会上哪怕需求文档只字未提角色列表也要先花五分钟把角色写出来包括“系统它自己”也算一个角色。写不出来的部分恰恰是需求最模糊的部分也是最容易出现越权漏洞的部分。2.2 经手哪些数据敏感字段的边界在哪里第二个问题是数据。这里说的不只是“手机号是敏感数据”这种常识而是要具体到这个需求从哪个环节开始收集数据数据存在哪里要传给谁谁有权看到日志里会不会记录。拿找回密码举例子这个需求经手的数据至少有手机号、验证码、重置后的新密码、操作记录、日志。其中验证码是最容易出问题的很多团队只在传输时做了加密却忘了日志里明文打印验证码于是攻击者拿到日志就能直接重置任意账号。在需求阶段这类问题特别好拦下来。你只需要在数据列出来之后逐项问一句“这条数据如果泄露后果是什么”。不需要懂密码学也不需要懂扫描器只需要顺着业务流程走一遍。这一步做扎实了后面设计数据脱敏和日志规范就有明确依据而不是安全部门拍一个通用要求让开发去猜。2.3 信任边界系统内部和外部世界在哪儿分界信任边界这个概念听起来玄其实就是问一个问题从哪个点开始经过的数据不再受当前系统控制。用户手机上的App是不受控制的终端短信网关是外部系统第三方登录服务也是外部系统。凡是跨过这些边界的数据都必须默认不可信。还以找回密码为例手机短信验证码从短信网关返回再到用户输入整条链路跨越了至少三条信任边界。如果开发在某个接口里认为“既然验证码是我发的回传时就不用太严格”那就是在信任边界上埋雷。常见的处理方式是验证码要带一次性属性要和会话绑定要限时生效重试次数要封顶。这些不是安全工程师的个人偏好而是信任边界两端的必然要求。需求阶段如果能把信任边界画出来产品经理和开发就很容易达成共识边界两侧的所有输入都要验证。这份共识比任何一份安全规范文档都管用因为它长在具体需求上不会被人当作空泛的合规条款。2.4 隐式步骤需求文字里最容易漏掉的威胁角落还有一个实操习惯做任何需求威胁建模之前先把需求文字里没有写、但业务流程中必须存在的“隐式步骤”补出来。找回密码这个故事字面上只有“输入手机号、收验证码、设新密码”三步但真实流程还隐含着“系统发送验证码”“验证码校验”“失败计数”“触发锁定”“发送提醒通知”。如果建模时只对着表面步骤分析很多威胁就会藏在隐式步骤里。隐式步骤往往是攻击者最喜欢下手的地方。比如“失败计数”如果没人提到开发可能就不会实现锁定策略验证码爆破就成了必然结果。你可以在建模会上专门留出一段时间让产品讲一遍“这个单子背后系统还要替用户做哪些事”把每一个隐含动作都补进数据流图里再分析。3. 从需求描述到威胁清单一条可复制的五步流程有了三个输入之后就可以开始建模了。我常用的流程一共五步可以在一次一小时的建模会上全部完成。以下每一步都配找回密码的例子方便对照复现。3.1 把需求翻译成数据流图越简单越好第一步是画数据流。不需要标准软件工程里那种复杂的DFD符号白板上画几个圆几个箭头就行用户、前端页面、后端服务、数据库、短信网关谁向谁请求什么数据画清楚即可。有人会问需求阶段连接口都没定画什么数据流我的经验是越没确定细节越适合画粗粒度流程。你要的不是精确到字段的时序图而是确认数据“从哪进、在哪处理、落哪存储、往哪流出”。画完图之后多数模糊需求会立刻暴露比如需求里写了“支持手机验证码”但没说验证码调用的短信网关从哪来这就值得追问。3.2 用威胁分类逐项过筛第二步是用威胁分类法过一遍。这里最常用的是STRIDE把威胁分成六类伪装、篡改、抵赖、信息泄露、拒绝服务、权限提升。我不推荐一上来就背全称直接记中文语义就够了。威胁分类中文理解找回密码示例伪装Spoofing冒充别人发起请求攻击者冒充用户重置密码篡改Tampering数据被非法修改重置过程中的数据包被改写抵赖Repudiation用户否认做过操作用户否认发起过重置请求信息泄露Information Disclosure敏感数据被不该看到的人看到日志明文打印验证码拒绝服务Denial of Service系统资源被恶意耗尽短信验证接口被刷爆权限提升Elevation of Privilege低权限拿到高权限重置逻辑被用来操作管理员账号对照数据流图逐个节点问有没有可能冒充别人发起请求数据在传输或者存储过程中能不能被改用户做完敏感操作后是否无法证明他做过数据会不会被不该看到的人看到请求能否把系统打挂低权限用户能否干高权限的事六类过完一个需求的威胁面基本上就完整了后面的修复方向也自然指向对应的节点。3.3 按影响和可能性排优先级第三步不是把威胁全都列为必修而是排序。我给团队用的简化方法是两个维度影响程度高、中、低发生可能性高、中、低。九宫格里只有“高影响加高可能”和“高影响加中可能”需要立即处理其他可以先记录后面再说。需求阶段没必要上CVSS那种精细评分因为此时很多细节还没定。粗粒度排序的好处是大家不用为了一个不存在的补丁去争论“严重性到底是不是8.5”。排序的结论最好当场定下来负责人也当场指定不要拿回会后邮件里讨论。一旦出了会议室优先级讨论就很容易不了了之。3.4 把威胁变成可验收的安全需求条目第四步把选中的威胁转成安全需求条目。安全需求条目必须写清楚条件和预期结果要能做到验收。格式可以统一为“当……时系统必须……以防范……风险”。比如“当用户请求发送短信验证码时系统必须要求先完成图形验证码并通过频率限制同一手机号每分钟不超过1次、每天不超过5次以防范短信轰炸风险。”这句话开发能懂测试能验证产品能接受。相比之下写“注意短信安全”这种话等于没写。顺带提醒一下写安全需求条目时条件、动作、目的三个要素缺一不可。条件决定触发点动作决定实现逻辑目的决定为什么存在。有了目的将来做需求变更时团队才能判断这条限制能不能放宽。纯堆砌指标的条目一旦和业务冲突第一个被砍的就是它。3.5 回写到用户故事让开发看一眼就知道安全要求最后一步是把安全需求写回用户故事。很多团队在建模会上讨论得热火朝天散会之后威胁清单躺在Wiki里没人再看。要避免这个结果最好从一开始就把安全验收条件写进故事卡的“验收标准”部分。用故事卡的语言表达就是“作为注册用户我希望通过短信验证码找回密码以便在我忘记密码时恢复登录同时验证码仅5分钟内有效最多可尝试5次连续失败后该手机关联账号将锁定10分钟。”这样开发看到的不是安全部门外来的要求而是需求本身的一部分。这一步做不做直接决定了威胁建模能不能真正改变开发结果。4. 实测最常翻车的四个场景每个我都踩过流程写出来很简单真正落地的时候问题非常多。下面这几个翻车场景是过去几年我和不同团队协作时反复遇到的提前知道能帮你省下不少会议时间。4.1 翻车场景一威胁清单变成了合规填空题没人聊业务最常见的问题是建模会开着开着变成了填表大会。安全工程师准备了一份模板上面列了二十种威胁大家照着勾选SQL注入勾上跨站脚本勾上越权勾上完事。会后一问数据流向哪儿、验证码存在哪里没人说得清。这种威胁清单对业务没有意义因为它是通用项不是针对这个需求的分析。要破这个局建模会上应该少看模板多看那张数据流图。如果大家能围绕图里某一个箭头争论起来说明建模进入了正题。我甚至建议会议前五分钟先禁止碰模板专门把数据流画完再进入威胁分类。你还可以在会议开始时立一个规则每人发言必须引用具体角色或具体数据流节点禁止说“可能不安全”这种空话。这个规则听起来机械但能有效防止会议滑向空对空的讨论。4.2 翻车场景二工具带着团队跑业务问题反而没人问有些团队买了威胁建模工具期望导入需求描述后自动输出威胁清单。工具确实能生成候选列表但它无法理解你的业务。比如工具能提示“接口缺乏身份验证”可它不知道这个接口面向的是内部管理后台还是公开注册页面这决定了威胁的严重程度和修法。我的建议是把工具当成题库别当成裁判。威胁建模的核心是对具体需求的分析而不是从工具的结果里挑选项。自动化可以用于建模之后的持续跟踪但不能在需求阶段取代人的判断。工具能帮我们把威胁分类枚举得更全却永远代替不了那个“这段流程如果被打会怎样”的业务直觉。4.3 翻车场景三所有威胁都排成高危等于没有优先级另一种常见画面是会上大家为了保险起见把几乎所有威胁都标成“高影响”理由是“万一出事谁负责”。结果就是安全团队拿着二十条高危威胁去压排期开发的反应是免疫反正每条都是高危那就都不紧急。排优先级不是做安全检测报告而是做风险管理决策。高影响的威胁如果可能性极低在资源有限时可以先接受并记录后续再评估。我在会上常常要主动说一句“这条我们可以放到观察清单不代表不处理只是本周不为它排期。”敢于画重点建模才有实际效果。低危威胁不是被忽略而是被清楚地记录在决策档案里。观察清单不是垃圾桶每一条都要写清楚接受风险的理由和重估触发条件否则它就成了一个免责口袋。4.4 翻车场景四会议产出没有回写故事卡散会即遗忘这是最可惜的一种翻车。建模会开得不错威胁识别准确安全需求也写出来了但团队下一步排期时发现故事卡里没有一个字提到安全。原因是会议产出只停留在单独的安全需求清单没有同步进迭代的管理工具也没有绑定负责人。要避免这个坑至少做两件事第一给每条安全需求指定一个明确的交办对象不写“团队负责”第二确认它进入了迭代积压列表并在验收标准里注明关联的故事卡编号。没有这两步威胁建模就只能算一次成本产生不了收益。事后大家还会得出一个错误结论威胁建模没用。其实不是方法没用是流程断在那里了。5. 让需求阶段威胁建模稳定运行的协作机制流程和避坑都聊完了最后说说怎么让这件事在团队里持续运转起来。威胁建模不是一次性活动它需要靠协作机制固定下来否则永远是某一次领导推动后就没下文。5.1 谁该坐在建模会上控制在六人以内需求阶段的威胁建模会参会人不用很多但角色必须覆盖产品经理、开发的架构或后端负责人、前端负责人如果涉及前后端交互、安全工程师、测试工程师。如果需求改动涉及外部第三方系统再把对接方拉进来。人数超过六个会议的节奏和效率会明显下降很容易变成各说各话。我一般建议采用“核心三人组加按需扩展”的方式产品、开发、安全必须到测试和前端在涉及界面或验证环节时再参与。宁可多开半小时小会也不要开两小时大会。多人大会容易让最会表达的开发主导讨论反而是最了解业务流程的同事可能没机会开口。另外建议建模会设一个明确的时间盒不要超过90分钟。需求阶段的威胁建模追求的是覆盖主要威胁面不是穷举所有攻击路径。时间一到把未完成项列入待确认问题清单比拖堂更有效。5.2 建模的时机赶在需求评审之前别等需求冻结很多团队的威胁建模放在需求评审之后、开发开始之前这时候需求已经接近冻结讨论空间变小了。更好用的节奏是需求刚有雏形时先做一轮轻量威胁建模把高风险点暴露出来产品在评审前就能把安全要求带进PRD。需求冻结后如果还有重大变更再做一轮增量分析。我见过一个配合得比较顺的团队他们的产品每次组织需求评审前都会在内部先和开发、安全花半小时过一遍数据流图。这半小时让评审会的效率高了很多因为大家讨论的已经不是“这个方案行不行”而是更具体的安全设计取舍。需求阶段的威胁建模不是一次性大动作而是跟随需求演进的轻交互。5.3 记录工具和模板能进Wiki就行别让工具成为门槛工具不是门槛记录才是。最简单的做法是在Wiki里维护一张威胁建模记录表字段包括需求编号、需求描述、相关角色、数据与信任边界、威胁清单、优先级、安全需求条目、关联故事卡编号、状态、负责人、备注。有人问要不要引入专门的威胁建模软件。我的建议是如果团队规模不大先用在线白板加Wiki完全够用等流程稳定了再考虑用自动化工具辅助管理。引入工具的核心目的是让结果可追踪而不是为了显得专业。工具越重团队越容易推迟落地反而丢掉了“先跑起来再优化”的节奏感。5.4 度量什么才不跑偏盯安全需求落地率而不是威胁发现数量最后聊度量。千万不要用“一次建模会识别了多少条威胁”作为指标因为它会鼓励大家把建模会变成凑数大会。真正值得盯的是两个指标安全需求落地率和设计变更率。安全需求落地率统计进入故事卡并完成开发验证的安全需求占全部安全需求的比例设计变更率统计需求冻结后因为安全原因发生的设计变更次数。这两个指标一个看“有没有落地”一个看“是不是及时发现”。它们不会给人制造虚假的安全感只会让团队逐步意识到威胁建模减少的是上线后被迫返工而不是减少了工作量。指标的意义是引导行为不是被衡量本身绑架。我自己的体会是需求阶段威胁建模这件事最难的不是学会STRIDE或者画数据流而是让团队愿意在一张白板前面认真问一句“这个需求如果被坏人盯上会怎样”。一旦这个问题被问出来后面所有工具、模板、流程都是水到渠成。最后再分享一个小技巧如果你们是第一次尝试拿一个中等复杂度的需求练手不要直接挑最核心的登录模块从一个能上线的次要功能开始跑通一次全流程团队就会自己开始问那句话了。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑