2. 代码安全缺陷分类与风险建模

代码安全缺陷治理的第一步不是“修”,而是“认”。同一段有问题的代码,在不同业务场景下的风险等级可能相差两个数量级:一个只在内部管理后台触发的反射型 XSS,与一个在支付回调链路上可被未授权触发的反序列化漏洞,修复优先级完全不同。因此,本节要建立两件事:一是把常见缺陷按“成因—触发路径—影响面”分类清楚;二是用 CWE/OWASP 作为共同语言,把缺陷映射到可比较的风险坐标上,再结合业务影响做出评级。

一、按触发机制划分的六类常见缺陷

从扫描器告警到人工确认,最有效的分类维度是“数据从哪里来、经过什么处理、最终到达哪里”。据此可归纳为六类:

  • 注入类(CWE-89/78/94):外部输入未经参数化或白名单校验,直接拼接进 SQL、OS 命令、表达式引擎。典型特征是“字符串拼接 + 解释器执行”。
  • 跨站脚本 XSS(CWE-79):用户可控内容未按输出上下文编码就写入 HTML/JS/属性/URL。分存储型、反射型、DOM 型,危害从会话劫持到前端供应链投毒。
  • 跨站请求伪造 CSRF(CWE-352):浏览器自动携带 Cookie,服务端仅凭会话凭证判断身份,缺少一次性令牌或 SameSite 约束。
  • 越权(CWE-639/862/863):认证通过但授权缺失,分水平越权(同角色访问他人资源)与垂直越权(低权限执行高权限操作)。
  • 不安全反序列化(CWE-502):不可信字节流被还原为对象,触发魔术方法或 gadget 链,常直接导致 RCE。
  • 敏感信息泄露(CWE-200/798/312):密钥硬编码、日志打印身份证/卡号、异常堆栈外泄、传输未加密。

这六类并非并列,而是存在“前置条件—放大效应”的关系:越权往往是注入的放大器(拿到他人数据),信息泄露常为反序列化提供密钥或路径。下图给出六类缺陷的触发链与关键控制点,可作为扫描告警归类时的对照图。

常见缺陷触发链与关键控制点 不可信输入源 HTTP 参数 请求体 / JSON Cookie / Header 上传文件 消息队列 第三方回调 缓存 / DB 回读 注入 CWE-89/78/94 拼接 → 解释器执行;控制点:参数化/白名单 XSS CWE-79 未按上下文编码;控制点:输出编码+CSP CSRF CWE-352 浏览器自动带凭证;控制点:Token/SameSite 越权 CWE-639/862 认证≠授权;控制点:对象级鉴权 反序列化 CWE-502 字节流还原对象;控制点:禁原生/签名校验 信息泄露 CWE-200/798 硬编码/日志/堆栈;控制点:密钥托管+脱敏 业务影响面 数据泄露:用户隐私、订单、密钥 资金损失:支付篡改、优惠券套现 服务中断:RCE、删库、资源耗尽 合规处罚:等保、GDPR、个人信息保护法 声誉与信任:品牌、客户流失 横向移动:内网渗透、供应链投毒 风险评级四要素 可利用性:是否需要认证、是否远程 影响范围:单用户 / 全租户 / 全系统 数据敏感度:公开 / 内部 / 个人 / 密钥 暴露面:公网 / 内网 / 仅本地 → 综合得出 P0~P3 修复优先级

二、CWE 与 OWASP Top 10 的映射关系

CWE 是缺陷的“物种分类”,粒度细、数量多;OWASP Top 10 是风险的“榜单”,粒度粗、面向业务。扫描器通常报 CWE 编号,而管理层更关心 OWASP 类别。建立映射表能让同一份扫描报告同时服务研发与决策。以 2021 版 OWASP Top 10 为例:

OWASP 类别典型 CWE本节对应缺陷
A01 访问控制失效CWE-639、CWE-862、CWE-863越权
A02 加密机制失效CWE-327、CWE-312、CWE-798敏感信息泄露
A03 注入CWE-89、CWE-78、CWE-79、CWE-94注入、XSS
A04 不安全设计CWE-209、CWE-256、CWE-522信息泄露、设计缺陷
A05 安全配置错误CWE-16、CWE-611、CWE-1004配置类缺陷
A07 身份认证失效CWE-287、CWE-384、CWE-798会话、硬编码凭证
A08 软件与数据完整性失效CWE-502、CWE-829反序列化
A10 服务端请求伪造CWE-918SSRF(注入变体)

注意 CSRF 在 2021 版中不再单列,而是并入 A01 访问控制失效,但 CWE-352 仍然独立存在。这说明映射不是一一对应,而是多对多。实际落地时,建议在扫描平台维护一张“CWE → OWASP → 业务域 → 默认优先级”的四列映射表,扫描结果入库时自动打标,避免每次人工翻查。

三、风险评级:从 CVSS 到业务加权

CVSS 3.1 给出的是技术严重性,公式为 Base = f(AV, AC, PR, UI, S, C, I, A)。例如一个公网可达(AV:N)、无需认证(PR:N)、无需交互(UI:N)、可导致完全数据泄露(C:H)的反序列化漏洞,Base 分通常在 9.8 左右,属于 Critical。但技术分不等于业务优先级。业务加权需要引入三个修正因子:

  • 数据敏感度系数 D:公开数据 0.6,内部数据 0.8,个人信息 1.0,密钥/支付数据 1.3。
  • 暴露面系数 E:仅本地 0.5,内网 0.8,公网 1.0,公网且无 WAF 1.2。
  • 业务关键度系数 B:边缘功能 0.7,一般业务 1.0,核心交易 1.3。

业务风险分可近似为 Risk = Base × D × E × B,再按区间映射到 P0~P3。举例:某内部报表系统的 SQL 注入,Base=8.8,D=0.8(内部数据),E=0.8(内网),B=0.7(边缘功能),Risk≈3.94,可降级为 P2;而同样的注入出现在公网支付接口,D=1.3、E=1.2、B=1.3,Risk≈17.8,必须 P0 立即修复。这个计算过程应在扫描平台的工单生成逻辑中固化,而不是靠人工拍脑袋。

评级不是一次性的。当业务从内网迁移到公网、或数据从脱敏变为真实个人信息时,同一缺陷的 Risk 会跳变,需要重新评估。

四、业务影响分析的落地方法

业务影响分析要回答三个问题:这个缺陷被利用后,攻击者能拿到什么、能改什么、能中断什么。建议按“资产—威胁—影响”三步走:先列出该代码路径涉及的资产(用户表、订单表、密钥管理服务),再对照缺陷类型推断威胁(读取、篡改、删除、横向移动),最后量化影响(受影响用户数、资金规模、恢复时长)。

以敏感信息泄露为例:若日志中打印了完整身份证号,资产是个人信息,威胁是批量读取,影响是合规处罚与用户投诉。修复动作不是简单删日志,而是引入脱敏组件,在日志框架层对 idCard、phone、bankCard 等字段做掩码,并保留审计所需的哈希值。验证方式是构造一条含身份证号的请求,检查日志输出是否为 110***********1234 形式,同时确认审计系统仍能通过哈希关联到具体用户。

不要把“扫描器报了多少个高危”当作治理目标。真正的目标是:每个 P0/P1 缺陷都有明确的责任人、修复方案、验证用例和关闭时间,且同类缺陷不再重复出现。