网络安全工程师-作业1,这个标题乍一看平平无奇,但真正上手做过的人会懂,这份作业远不是"交差"那么简单。它既不是让你背几个漏洞类型,也不是让你跑一遍扫描器截图交差——它是从学生思维转向工程思维的第一道门槛。我把自己完成这份作业的完整过程、踩过的坑、以及后来在工作中回头看时的反思整理出来,希望能给同样在写这份作业的人一些参考。
我接到的作业要求很简洁:对一个给定的业务系统做威胁建模,给出安全风险评估报告,并提出加固建议。没有给标准答案,没有给模板,只给了系统架构说明和一份数据流图草稿。正因如此,这份作业其实有大量的自由发挥空间,而自由发挥恰恰是大部分人会翻车的地方。
1. 作业1的真正考点:不是找漏洞,而是建立系统化安全思维
1.1 拿到作业的第一反应,大部分人在这里跑偏
说实话,我一开始也差点走错路。看到"威胁建模"四个字,第一反应是"那我得找几个漏洞出来",于是开始查这个系统用什么框架写的、有哪些已知CVE、能不能构造一个SQL注入……就这么折腾了大半天,发现自己根本是在做渗透测试,而不是在做威胁建模。
这是一个非常典型的误区:把威胁建模当成了漏洞挖掘。威胁建模的目标不是"找出某个具体漏洞",而是"系统地识别这个系统可能面临哪些类别的威胁,以及这些威胁可能从哪里进来、会造成什么影响"。漏洞是一个个具体的点,威胁是一条条可能的路径。你需要先有路径,才能谈得上堵住某个点。
1.2 作业真正考核的三项能力
等我静下心来仔细拆解这份作业的评分标准(或者说,我猜的评分标准)之后,我意识到它其实是在考核三件事:
- 资产识别能力:你能不能清楚地说出这个系统里最重要的东西是什么,是用户数据、是业务连续性、还是系统本身的可用性。
- 信任边界与数据流梳理能力:你能不能把系统拆成若干个可信区域,准确标出数据在哪些区域之间流动,边界在哪里,谁有权限跨越边界。
- 威胁分类与防护映射能力:你能不能把识别到的威胁按类别整理,并且为每一类威胁给出对应的、可落地的防护手段,而不是写一堆"加强安全意识"这种正确的废话。
只要围绕这三项能力去组织作业内容,不管系统长什么样,都不会跑偏。反过来,如果这三项能力没有体现,哪怕你写了几十页,评审也很容易看出你是东拼西凑的。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 先跑通威胁建模:STRIDE方法从零开始拆解一个最小系统
2.1 为什么选STRIDE而不是别的模型
威胁建模的方法论有不少,常见的有STRIDE、DREAD、PASTA、VAST,还有近年比较火的MITRE ATT&CK。作为一份入门作业,我没必要把每种方法都研究一遍,但至少得知道它们之间的区别,才能理直气壮地告诉评审"我为什么选这个"。
STRIDE是微软提出的一套威胁分类方法,把威胁分成六类:仿冒(Spoofing)、篡改(Tampering)、否认(Repudiation)、信息泄露(Information Disclosure)、拒绝服务(Denial of Service)、权限提升(Elevation of Privilege)。它的核心价值在于"以数据流为中心",每一条数据流都需要过一遍这六类问题,基本不会漏。
DREAD是一种风险评级模型,它负责给威胁打分数,而不是发现威胁。PASTA更偏业务风险分析,适合大型企业做安全战略规划,对一份作业来说太重了。MITRE ATT&CK则更偏攻击者视角,适合做检测和响应规划,而不是入门学习。
所以我选了STRIDE。理由很实在:它简单、系统化、覆盖面广,而且特别适合用来交作业——你只要老老实实把数据流图画出来,然后逐条数据流过STRIDE,就已经完成了一大半。
2.2 用作业里的示例系统,逐步套STRIDE
作业给的示例系统是一个简化版的学生选课系统,大概结构是:客户端浏览器 -> Web应用服务器 -> 数据库服务器,中间还有一个用于单点登录的认证服务,以及一台用于记录日志的日志服务器。听着简单,但用来套STRIDE已经足够了。
我先把系统画成一张数据流图,标出所有数据流动的路径,大致是这几条:
| 数据流编号 | 源 | 目标 | 传输内容 |
|---|---|---|---|
| 1 | 浏览器 | Web应用 | 登录账号密码、选课请求 |
| 2 | Web应用 | 认证服务 | 用户凭证校验请求 |
| 3 | 认证服务 | Web应用 | Token、用户身份信息 |
| 4 | Web应用 | 数据库 | SQL查询、写入选课记录 |
| 5 | 日志服务器 | Web应用 | 日志查询结果、审计信息 |
然后我拿着这张数据流表逐条过STRIDE。以数据流4(Web应用 -> 数据库)为例:
- 仿冒:有没有可能有人直接伪装成Web应用向数据库发起请求?如果数据库只认IP,那攻击者拿到Web服务器权限后是不是就能直接访问数据库?
- 篡改:Web应用发往数据库的SQL语句有没有可能被中间人篡改,或者在应用层就被注入了恶意SQL逻辑?
- 否认:数据库的写入操作能不能追溯到具体是哪个用户、哪个Session发起的?如果没有事务ID关联,用户可以说"我没选过这门课"。
- 信息泄露:SQL查询结果里有没有包含不该返回的字段?比如查询选课列表时是不是把其他学生的姓名、学号也带出来了?
- 拒绝服务:大量恶意的慢查询会不会耗尽数据库连接池?
- 权限提升:数据库账号用的如果是高权限账号(比如DBA),那么一次SQL注入就有可能通过
xp_cmdshell或into outfile直接拿到系统权限,这就是典型的权限提升。
每一条数据流都过一遍这六类问题,最后整理成一张风险清单。这个过程看着机械,但它能逼你把系统里的每个连接都想到,反而比"凭感觉列几个常见漏洞"要实在得多。
2.3 最容易漏掉的关键细节:数据流图
我在做数据流图时踩了一个不大不小的坑:一开始我把"日志服务器"画在了Web应用的旁边,却没标出它是单向接收日志还是可以查询。这就导致后面做威胁分析时,我漏掉了"日志服务器被用来做跳板"的可能性。
后来我重新审视数据流图,才意识到信任边界才是关键。系统里有几个信任区域:
- 用户区域:浏览器所在的终端环境,不可信。
- DMZ区域:Web应用服务器,部分可信,因为暴露在公网。
- 内部区域:认证服务、数据库、日志服务器,相对可信。
- 运维区域:管理员的运维终端,高可信但同时也是高价值目标。
数据从不可信区域流向可信区域,或者从高可信区域流出的过程,才是威胁最容易发生的地方。比如用户区域的浏览器被种植了恶意插件,那么账号密码在输入框里就可能已经被窃取,这属于在信任边界之前就出问题了,Web应用再安全也无法防护。
我在最终版的数据流图上,把每一条跨越信任边界的数据流都用红色标了出来,然后在分析部分专门讨论了这些跨边界流动的威胁。这一步应该是整份作业里最加分的地方,因为大多数人画数据流图只是画了个拓扑,没有真正想清楚信任边界在哪里。
3. 把威胁清单变成可落地的加固方案:风险评估与优先级
3.1 风险定级,不要让所有威胁看起来都一样严重
发现威胁之后,最忌讳的做法就是列一个长长的清单,把所有威胁都写成"高危"——评审只要看一眼就知道你没动脑子。正确的做法是给每个威胁做风险定级,用可能性 × 影响程度来量化。
我采用的评分体系很简单:
| 维度 | 1分 | 2分 | 3分 |
|---|---|---|---|
| 可能性 | 低:需要物理接触或高级攻击技巧 | 中:需要网络访问或普通攻击技巧 | 高:仅需浏览器操作或公开工具即可利用 |
| 影响 | 低:单个非敏感数据受影响 | 中:部分用户数据泄露或服务短时中断 | 高:大量敏感数据泄露或系统完全沦陷 |
风险值 = 可能性 × 影响,1-2分属于低风险,3-4分属于中风险,6-9分属于高风险。
拿我之前说的"数据库连接池耗尽"这个威胁举例子:可能性是3(任何人都可以向公网发起请求,通过批量请求触发慢查询),影响是2(服务中断,但不涉及数据泄露),所以风险值=6,属于高风险。
再比如"日志服务器被入侵":可能性是2(需要先通过其他漏洞拿到内网权限),影响是3(日志被篡改会导致审计失效,掩盖攻击痕迹,甚至成为横向移动跳板),风险值也是6,高风险。
真正让我拿到这份作业里最深刻体验的,是我最终统计出来的那张风险矩阵表。原来"高发威胁"和"高危险威胁"完全是两回事——有的威胁几乎一定会发生但危害很小,有的威胁极难发生但一旦发生就是灾难。你只有在矩阵上把它们标注出来,才能看清楚资源的优先级该放在哪里。
3.2 用"可操作、可验证、有层次"的原则来写加固建议
风险清单列完还不算完,作业要求里有一句话我记得很清楚:"每一条威胁都必须有对应的防护措施,并且需要说明为什么这个措施有效。"这句话才是真正的筛子,它淘汰掉了所有"加强安全意识""定期进行安全培训"这类空话。
我给自己定了一个原则:每条加固建议必须满足三个条件——可操作、可验证、有层次。
- 可操作:建议里必须包含具体的配置、工具、策略。比如"限制数据库账号权限"就不如"为Web应用单独创建只具备
SELECT、INSERT、UPDATE、DELETE权限的账号,并禁止该账号访问系统表"可操作。 - 可验证:建议必须自带验证方法。比如"对登录接口加验证码"的验证方法是"使用脚本模拟连续10次错误登录,确认第5次开始被拦截"。
- 有层次:不能只靠单一控制点。比如防SQL注入,既要有代码层的参数化查询,也要有数据库层的权限收窄,还要有WAF层的规则阻断,三层互为补充。
举个例子。针对"SQL注入导致权限提升"这一条威胁,我写了这样的加固建议:
- 预防层:全量代码审计,所有SQL语句改为参数化查询或预编译语句,严禁字符串拼接SQL。这是最根本的解法,因为参数化查询从语法层面让注入逻辑无法构成完整的SQL语句。
- 检测层:部署RASP或在WAF上配置SQL注入特征规则,拦截常见的注入Payload;数据库侧开启慢查询日志和错误日志,对异常SQL做监控告警。
- 响应层:建立账号锁定与IP封禁联动机制,当同一IP触发多次告警时自动封禁并通知安全管理员。
每条建议都写清楚"做什么、怎么做、怎么验证",这样评审想扣分都没法扣。
4. 作业提交前的自查清单与评审最常挑的毛病
4.1 提交前应该做的5项检查
我这份作业前后改了三版,前两版自己都看不下去。后来我给自己列了一个提交前的自查清单,每一条都过一遍,心里才有底。
- 数据流图是否完整:数据流图里不能只有"正常流程",还得有异常流程,比如登录失败、数据库超时、日志写入失败。每条异常分支都可能引出额外的威胁。
- 威胁是否真正对应STRIDE类别:最常见的翻车是把"数据被加密传输"写成"信息泄露"类威胁的防护措施——这不是威胁,这是已有控制。威胁应该是"明文传输导致信息泄露",而不是"加密传输"本身。
- 风险定级是否有依据:不要把"敏感数据泄露"一律标成9分,要结合具体场景。一个只能被登录用户访问的小功能和一个对外开放的API,风险等级完全不同。
- 防护措施是否具体到可验证:如果建议里出现了"加强""完善""提升"这种词,赶紧重写。评审看到这种词就知道你在凑字数。
- 是否区分了已有控制和待加固项:系统里可能已经有防火墙、有登录认证,你要说明哪些威胁已经被现有控制覆盖了,哪些还需要新增控制。这才是工程思维——不是从零开始堆安全设备。
4.2 评审几乎一定会问的几个问题
我在提交后收到了反馈,其中有几个问题非常有代表性,基本可以预测任何一份威胁建模作业都会被问到:
"你到底保护的是什么资产?"
这个问题看似基础,但容易答不好。如果你的答案是"保护系统安全",那相当于没说。我当时回答的是:核心资产是"学生的选课记录和成绩数据"以及"系统的可用性",因为前者是隐私数据,泄露会面临合规风险;后者影响核心教学业务,中断会造成直接影响。这个回答把资产和业务价值绑在一起,马上就不一样了。
"信任边界画对了吗?"
我最初的版本把认证服务画在了Web应用的"旁边",没有明确标注它是独立信任区域。后来我意识到问题:认证服务存放的凭证属于高价值数据,如果它和Web应用在同一信任区域,等价于说"Web服务器被攻破后,可以直接读取认证服务里的数据"。这是绝对不可以的。
"这条加固措施真的可行吗?"
我写了一条"所有数据库访问必须通过堡垒机"的建议,结果被问了"堡垒机自身的安全怎么保证?"我一开始没想过这个问题,后来才知道,堡垒机如果属于高权限资产,它本身就是攻击者最想打的目标——你要么给它单独做加固和审计,要么就考虑更轻量的方案,比如仅对敏感操作强制二次审批。
这几个问题本质上都在考察一件事:你有没有真的动脑子去理解系统的边界和信任关系,而不是套模板。
5. 作业之外的延伸:从课堂作业到真实业务环境的距离
5.1 课堂系统和真实系统的差别
交完作业之后我一度觉得"威胁建模也就那样了"。直到后来在公司真正负责一个业务系统的安全评审,才发现课堂作业和现实工作之间的差距,大致可以总结为四点:
- 规模差:课堂系统只有三台服务器,真实系统可能有几十个微服务、多个Kubernetes集群、若干云服务商组件,数据流图连起来能铺满整面墙。数据流的数量上升了两个数量级之后,问题已经不是"覆盖到",而是"如何排序"。
- 边界模糊:课堂系统的信任边界很清晰:外部、DMZ、内部。真实系统里,云厂商的托管服务到底算不算可信?第三方SDK的代码算不算你的攻击面?供应链的组件版本谁来负责?这些问题比单纯画一条边界线复杂得多。
- 风险容忍度不同:课堂上的选课系统挂了就挂了,顶多被老师扣分。真实业务的可用性直接关联营收和口碑,风险决策经常要在"安全"和"业务"之间做权衡。威胁打分表写得再漂亮,最后还是要回到业务价值上来讨论。
- 合规要求介入:作业里不需要考虑,但真实系统必须考虑,比如个人信息保护相关的合规要求、等保测评的指标、行业监管机构的检查要求。这些会给威胁建模增加很多"必须防御"的硬性条件,没有讨价还价的余地。
5.2 我把作业里的方法用在工作中的一次经历
有一次我们上线一个新的对外API服务,开发的同学很兴奋地演示功能,我脑子里却自动开始跑STRIDE。
- 仿冒:这个API只靠一个Token做鉴权,Token过期时间设成48小时,而且没有刷新机制——风险:Token泄露后48小时内都可以被滥用。建议:缩短过期时间,增加短期refresh token。
- 篡改:API接受JSON数据,但入口没有JSON Schema校验,传进来的字段名和类型都没限制——风险:外部可直接提交异常数据进入核心业务链路。建议:加Schema校验层。
- 否认:API没有全量请求日志,出问题后无法回溯谁调用了接口、传了什么参数——风险:客户投诉时我们只能干瞪眼。建议:开启访问日志,保留至少90天。
- 信息泄露:错误响应里直接把异常堆栈返回给了调用方——风险:攻击者可以借此探测代码结构。建议:统一错误码,异常详情只写日志不上屏。
- 拒绝服务:接口没有做限流和并发控制,一个调用方的死循环就能打爆整个后端——风险:测试环境就能看到的状况,上生产必然更严重。建议:网关层加全局限流,核心接口单账号限流。
- 权限提升:API的Service账号权限设置得过大,只为了少改两行权限配置——风险:一旦被利用,数据泄露面远大于预期。建议:按最小权限原则重新分配。
说白了,STRIDE这种结构化的威胁分析方法,在真实工作中常常不是以"一次正经威胁建模会议"的形式出现,而是像这样片段化地贯穿在日常评审里。但它能起作用的前提,是你真的理解了它背后的分类逻辑,而不是只会背模型。
这份作业1给我最大的收获,不是学会了某个模型,而是建立了一种条件反射——看到任何一个系统,先问它要保护什么、信任边界在哪、数据怎么流动。这种思维方式一旦形成,后面的很多安全分析工作都是水到渠成的事。如果你也正在写这份作业,建议别急着找漏洞、堆漏洞报告,先老老实实把系统拆清楚,把数据流画完整,把STRIDE六类威胁一个个过掉,你会发现答案早就自己浮出水面了。
