RUSTSEC-2026-0194: Quadratic run time when checking a start tag for duplicate attribute names
还没有人认领这个 Issue。
评估
调研方向
定位 graph-node 的 quick-xml 依赖声明,并检查该依赖在 lockfile 中的解析方式。将依赖更新到 0.41.0 或更高版本,然后运行相关的 Rust 测试套件或构建。完成标准是项目不再解析到存在漏洞的版本,且现有测试通过。
由索引模型根据 Issue 内容生成。
描述
Quadratic run time when checking a start tag for duplicate attribute names
| Details | |
|---|---|
| Package | quick-xml |
| Version | 0.40.1 |
| URL | https://github.com/tafia/quick-xml/issues/969 |
| Date | 2026-06-29 |
| Patched versions | >=0.41.0 |
BytesStart::attributes() returns an Attributes iterator which, by default
(with_checks(true)), rejects a start tag that repeats an attribute name. For
each attribute yielded, the iterator compared the new name against every name
seen so far in the same tag using a linear scan, so a start tag with N
distinct attribute names cost O(N²) byte comparisons. There was no bound on
N other than the size of the buffered start tag.
Impact
Any code that parses untrusted XML and iterates a start tag's attributes with
the default duplicate check enabled can be made to spend CPU time quadratic in
the number of attributes on a single tag. Because the check is pure computation
with no .await/I/O, an I/O-based timeout on the consumer (for example a read
or request timeout) cannot interrupt it while it runs.
Measured cost of a single start tag, release build:
| Attributes on one tag | Time |
|---|---|
| 80,000 | ~6 s |
| 800,000 | ~10 min |
The cost grows with the square of the attribute count, so a start tag of a few
tens of megabytes can stall a parsing thread for hours. No memory is exhausted
and the parser does not crash; the effect is CPU exhaustion on the thread doing
the parsing: a single crafted start tag can pin a CPU core for minutes to hours,
denying service to that worker. A deployment that places a wall-clock bound on
parsing, or confines it to a non-critical thread, may consider the availability
impact lower.
Affected code paths
BytesStart::attributes()/Attributesiterated with checks enabled (the
default), andBytesStart::try_get_attribute.NsReader, which resolves namespaces by iterating a tag's attributes and so
reaches the same check internally.
Consumers that iterate attributes with .attributes().with_checks(false) and do
not use NsReader are not affected.
This was reported as reachable by a remote, unauthenticated attacker in a
real-world RPKI relying party (NLnet Labs Routinator) via a crafted RRDP
snapshot.xml.
Remediation
Upgrade to quick-xml >= 0.41.0, where the duplicate check keeps the linear
scan for start tags with a small number of attributes and switches to an O(1)
hash pre-filter above a threshold, making the whole tag O(N). The reported
AttrError::Duplicated positions are unchanged.
If upgrading is not possible and duplicate-name detection is not required,
disable it with .attributes().with_checks(false) (this does not help
NsReader consumers, which have no equivalent opt-out before 0.41.0).
See advisory page for additional details.
- 主要语言
- Rust
- 星标
- 3.2k
- 派生
- 1.1k
- 平均合并
- 4 天 1 小时
- 30 天内合并 PR
- 1
贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
graphprotocol/graph-node 的其他 Issue
-
current: include emits an all-null bucket for dimensionless aggregations, nulling the whole response 未关闭
难度 2/5 1-3 小时 新手友好度 78/100
graphprotocol/graph-node#6719 ·
-
难度 2/5 1-3 小时 新手友好度 70/100
graphprotocol/graph-node#6650 · 1 条评论 ·
-
难度 4/5 3-5 天 新手友好度 48/100
graphprotocol/graph-node#6722 ·
-
难度 3/5 1-2 天 新手友好度 68/100
graphprotocol/graph-node#6721 ·
-
难度 3/5 1-2 天 新手友好度 74/100
graphprotocol/graph-node#6720 ·
查看 graphprotocol/graph-node 的全部 Issue
相似的 Issue
-
risk:low runtime status:in-progress type:test
难度 1/5 1 小时以内 新手友好度 92/100
zeroclaw-labs/zeroclaw#11023 ·
-
good first issue refactor
难度 2/5 1-3 小时 新手友好度 72/100
-
难度 2/5 1-3 小时 新手友好度 86/100
kwakseongjae/auto-hwp#319 ·
-
area:cli bug filter-quality good first issue priority:medium
难度 2/5 1-3 小时 新手友好度 84/100
-
难度 1/5 1 小时以内 新手友好度 72/100
bevyengine/bevy#25861 ·