攻击面指系统里所有能被不信任输入触达的入口;威胁是可能利用这些入口的动因;漏洞是被威胁利用后会破坏保密性、完整性或可用性的实现缺陷;风险则是“某漏洞被利用”的可能与破坏程度的乘积。要判断一个安全问题有多严重,就是把这四个词摆到同一条线上对账。
这一幕需要一块共同的讨论标尺。技术人聊安全时最常见的尴尬是双方各说各话:甲方说“那是功能需求”,乙方说“那是漏洞”。矛盾往往不是代码错了,而是“漏洞”这个词没有对齐。本节先把四个核心词各自钉死,再给出 CIA 三元组,最后用一个换算公式把它们串成可计算的估值。
攻击面(Attack Surface)是系统里所有能被不信任方输入触碰的位置总和:开放的端口、接收参数的接口、上传文件的入口、第三方登录回调、甚至解析邮件附件的组件都一样算。攻击面是纯客观的清单,不涉及“坏不坏”。
威胁(Threat)是可能利用这些入口的动因——一台自动扫描互联网的僵尸网络、一个冲着加密钱包来的定向黑客、一个竞品雇的黑客团队,都属于威胁。威胁描述的是“谁可能来”,攻击面描述的是“哪里能进门”。
漏洞(Vulnerability)是系统里可被威胁利用且会破坏安全的缺陷。这一定义有两个判定条件:一是可利用(有人真能利用得动);二是破坏 CIA 三性的某一项。一个没有实际入口的死代码就算写得差,也不算漏洞。
风险(Risk)是数学概念:某漏洞被利用的可能性乘以事件发生的破坏度,再加一句“我们多久发现不了它”的时间系数。风险可高可低、可量化、可排序,它是安全预算用来排优先级的那把尺。

上面这张图串了两个动作:前四个框讲“是什么”,下面的 CIA 三元组讲“破坏什么”。安全讨论只要落到 CIA 的某一个字头,就从玄学变成了可评估的技术问题。
保密性(Confidentiality)关心“谁在读”。信用卡号被拖库是典型的 C 破坏——数据仍在,你没丢,但别人也读到了。完整性(Integrity)关心“数据对不对”。修改订单金额、篡改别人头像,都是动了 I。可用性(Availability)关心“服务在不在”。DDoS 把站点打挂,数据一字节没少,可用性已经崩了。
把三类危害分开,是为了给“严重性”排序时不打架。一次内部数据被员工打印带走,和一次对外接口被任何人拖走全量数据,虽然都算 C 破坏,但攻击面、暴露时长和破坏度差一个量级。对账时先问“破坏了 C/I/A 哪一个”,再追问“影响面有多大”,评估就稳了。
写一个不接受任何外部输入、只在本地拼字符串的脚本,它没有 CI、也没有攻击面,谈不上安全风险;把同一个脚本改成接收 HTTP 请求并回显参数,攻击面凭空多出一个,如果回显没做编码(后文 XSS 会讲),就出现了破坏 C 的潜在漏洞。可见“输入越界 = 攻击面 + 漏洞候选”这一因果在本节就打好了地基。
实操里我喜欢用一张三列表格给新功能排风险:第一列写“这个功能接收谁的不信任输入”,第二列写“输进去最坏会触发什么”(拖库、越权、刷接口……),第三列写“现有哪一层能拦住”。列不满第三列的行,就是要优先加固的对象。这张表是后面威胁建模(第七幕)的雏形,现在先手动养成习惯。
💡 关键直觉:判断一个输入是否需要防护,不看它“该不该被信任”,而看它“能不能被外部改变”。凡是终端用户、CDN、上游接口能改动的值,都按不信任处理。这是后续几乎所有注入类漏洞的同一根源。
一线最常遇到的是“感觉不对”的描述,但安全讨论需要一个能对齐的翻译表。举几个高频场景的“标准译法”:
这张翻译表不需要背,但需要能随手写出“术语——破坏哪条 CIA——影响面”三列的对应关系。能把一个模糊报障掐成这三段,就具备了把“灾难”量化为“风险”的起点,这也是每次安全评审要做的第一件事。下面是一个可直接套用的空表:
| 现象描述 | 标准术语 | 破坏 CIA | 影响面 | 是否高优先 |
|---|---|---|---|---|
| 看得到别人数据 | 越权 IDOR | C | 全量对象 | 高 |
| 错误信息回显 SQL 片段 | SQL 注入 | C/I | 底层数据 | 高 |
| 资源耗尽无法访问 | DoS | A | 全站 | 中高 |
| 支持文件被改成恶意内容 | 上传/篡改 | I | 可执行区域 | 高 |
第一,把“影响面”等同于“被感染量”,漏算“多久没被发现”。一条数据在库里躺一年才被拖走,与当天就被封堵,后果差一个数量级,时间系数必须进公式。第二,只看“技术可能性”不看“暴露开口”——一个只在内网开放的弱凭据接口,与一个公网裸奔的弱凭据接口,前者被人利用的概率低好几个档。第三,默认“没人会盯着我们”,遇到高价值目标(金融、社交、政企)这句话多半不成立。把这三点补进估值,你的风险排序才不会在真正出险时爆冷门。