Vulnerability HighRUSTSEC-2026-0194 · quick-xml
RUSTSEC-2026-0194: Quadratic run time when checking a start tag for duplicate attribute names
Short answerA security vulnerability in the quick-xml crate: Quadratic run time when checking a start tag for duplicate attribute names. High severity (CVSS 7.5). Fixed in 0.41.0: update to a fixed version.
| Crate | quick-xml |
|---|---|
| Type | Vulnerability (denial-of-service) |
| Affected versions | Before 0.41.0. |
| Fixed in | 0.41.0 |
| Severity | High, CVSS 7.5 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H |
| Published | 2026-06-29 |
| Last changed | 2026-07-02 |
| Also known as | none |
What to do
- See which version you have:
cargo tree -i quick-xml(it also shows which of your dependencies pulls it in). - Update within your version requirement:
cargo update -p quick-xml. If the fix is a newer major or minor than your requirement allows, raise it in Cargo.toml (for examplequick-xml = "0.41.0") or update the dependency that pulls it in. - Check again with
cargo audit, or paste your Cargo.lock into our Cargo.toml checker.
Details from the advisory
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).
References
- Package: crates.io/crates/quick-xml
- Advisory: rustsec.org/advisories/RUSTSEC-2026-0194.html
- Report: github.com/tafia/quick-xml/issues/969
- Web: github.com/tafia/quick-xml/pull/971
- Web: github.com/tafia/quick-xml/commit/07f3db8343cf152f5bc3483ef5b3164582489bea
From the RustSec Advisory Database (CC0-1.0) via the OSV export, downloaded Oct 24, 2026. Severity score computed from the published CVSS vector.
Other advisories for quick-xml
Up next
Same cratequick-xml: security historyEvery advisory for this crate, and whether it is safe to use today.Read it next →Did this answer your question?