参考披露:GHSL-2023-055 / CVE-2023-32991, CVE-2023-32992
说明:仓库里旧标题曾误写成「2019 API 安全建议」,与文件名及 advisory 不符;本次按真实漏洞主题重写,并补上可迁移的防护结论。
背景
企业内网很常见的架构是:Jenkins + SSO(SAML)。构建系统一旦接入身份联邦,XML 解析就会出现在登录断言(Assertion)校验路径上。XML 是老格式,但解析器默认行为往往「过于友好」——允许外部实体、允许远程 DTD——于是历史经典问题 XXE 会重新出现。
GitHub Security Lab 在 SAML Single Sign-On (SSO) for Jenkins 插件中发现了与 XML 解析相关的问题,并分配了:
- CVE-2023-32991
- CVE-2023-32992
影响面不只是「解析失败」,而是可能升级为 服务端请求伪造(SSRF) 或敏感文件读取,取决于解析器配置与运行环境。
问题本质:不可信 XML + 不安全解析器
SAML 流程里,IdP 返回的 Assertion 是 XML。若插件在校验签名前后,用了允许外部实体的解析方式,攻击者可以构造类似:
<?xml version="1.0"?>
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<foo>&xxe;</foo>
或指向内网地址:
<!ENTITY xxe SYSTEM "http://169.254.169.254/latest/meta-data/">
解析器一旦解析外部实体:
- 可能把本地文件内容拼进 DOM(信息泄露)
- 可能由 Jenkins 所在主机 向内网/元数据地址发起 HTTP 请求(SSRF)
- 在云环境中,SSRF 常常比「读一个文件」更危险
这与「API 安全」其实是同一类问题:把不可信输入交给了能力过强的解析器。
为何 SSO 场景特别容易中招
| 因素 | 说明 |
|---|---|
| 信任错觉 | 开发以为「来自 IdP」的数据可信任,忽略中间人或错误配置的 IdP |
| XML 遗留默认项 | 许多 XML 库默认未禁用 DTD / external entity |
| 高权限宿主 | Jenkins 往往能触达源码、凭证、内网服务 |
| 日志与报错 | 解析异常有时会把实体展开结果打到日志 |
修复与加固思路
1. 升级插件到修复版本
第一优先级永远是:安装厂商/维护者发布的安全版本。不要只靠 WAF 或「内网所以安全」。
2. 解析 XML 时默认拒绝外部能力
无论 Java 还是其它生态,原则都是:
- 禁用 DTD
- 禁用 external general/parameter entities
- 如需 schema,使用本地可信 XSD,而不是远端 DTD
Java 侧常见方向(示意):
// 概念示意:按你使用的解析 API 设置对应 feature
factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
factory.setXIncludeAware(false);
factory.setExpandEntityReferences(false);
3. 网络层给 Jenkins 最小出站权限
即使解析器失手,Egress 控制也能降低 SSRF 危害:
- 默认拒绝访问云元数据地址
- 限制 Jenkins 只能访问明确的制品库、插件源
- 对内网管理面分段
4. SAML 集成的额外检查
- 严格校验签名、Audience、Recipient、时间窗
- 拒绝未签名或签名算法过弱的断言
- 对解析失败做统一错误页,避免回显 XML 细节
推广到「API 安全」的四条可执行建议
旧标题想讲的其实可以落到这四条(与年份无关,今天仍然成立):
- 不要信任「看起来来自身份提供方」的结构化载荷
JWT、SAML、Webhook JSON/XML 都要按不可信输入处理。 - 解析器做能力最小化
用不到的特性全部关闭;默认安全 > 默认方便。 - 服务端发起的请求要有允许列表
SSRF 的根因是「服务器变成了攻击者的代理」。 - 密钥与会话绑定要完整
SSO 成功后的会话固定、CSRF、二次绑定账号,都要在应用层收口。
运维自查清单
- Jenkins 与 SAML 插件版本是否包含修复
- 是否还有其它插件自行解析 XML/HTML
- Jenkins 主机出站策略是否过宽
- 日志是否可能记录敏感实体展开内容
- SSO 失败路径是否信息泄露
小结
CVE-2023-32991 / 32992 再次说明:身份联邦不是安全边界的终点,解析器配置才是。对安全工程来说,比记住 CVE 编号更重要的是建立习惯——凡是 XML/YAML/模板/URL 拉取,先问一句:「这份输入若完全恶意,我的库默认会帮攻击者做什么?」
若你的环境仍在使用 Jenkins SAML SSO 插件,请对照 advisory 升级,并同步收紧 XML 解析与出站网络策略。