Repository navigation
Upgrade @xmldom/xmldom from 0.9.10 to 0.9.12 to close its security advisories - #147
Merged
Merged
Conversation
…visories The published 0.1.0 pins @xmldom/xmldom 0.9.10, and every install of @cosyte/ccda gets it. pnpm audit --prod reported 13 advisories against it (11 high, 2 moderate), all fixed in 0.9.12. The pin moves to 0.9.12, still exact; pnpm why @xmldom/xmldom --prod now shows 0.9.12 and nothing older, and pnpm audit --prod reports no known vulnerabilities. No source change was needed. The 0.9.10 to 0.9.12 changelog and the lib diff were read first, then the upgrade was run differentially: the same inputs through the built package against each version. Every fixture document, 26 crafted edge cases and 3,000 seeded mutations gave the same warnings, model readings, serialized bytes and fatal codes, and buildCcda emitted the same bytes for all fifteen conformance cases. pnpm conformance reproduces the committed report byte for byte. test/security.test.ts gains two blocks: - Three denial-of-service shapes from the advisories, parsed through parseCcda under a 4 s budget: an unterminated processing instruction, an element with 80,000 attributes, and a run of `<` inside a malformed tag. On 0.9.12 the slowest takes about 0.5 s; on 0.9.10 they take 20 to 23 s and fail. The namespace-map advisory is a memory fix and 0.9.12 is still super-linear in time on that shape, so it has no case. - What the parser now reports differently. An end tag followed by a line break and trailing content is reported at the error level, which buildDom tolerates, so the document parses as before. A DOMException raised while building the DOM now arrives as a fatalError whose cause quotes the element name; ccda still throws NOT_WELL_FORMED_XML from the registry with no cause. An xml-stylesheet instruction, which 0.9.11's rewritten PI grammar touches, round-trips verbatim. Run against 0.9.10, the three timing cases and the cause probe fail; the other two pass on both, as they pin ccda's outcome rather than the parser's. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The published 0.1.0 pins
@xmldom/xmldom0.9.10, which every install of@cosyte/ccdagets.pnpm audit --prodreported 13 advisories against it (11 high, 2 moderate), all fixed in 0.9.12. This moves the exact pin to 0.9.12.Finish line
pnpm why @xmldom/xmldom --prod:@xmldom/xmldom@0.9.12, found 1 version.pnpm audit --prod: no known vulnerabilities (exit 0). The 8 dev-scope advisories are out of scope here..changeset/xmldom-security-upgrade.md.test:coverage(43 files, 1375 passed, 1 skipped, coverage gates green), build, attw, a CJS and ESM import smoke check, the examples job (typecheck, lint, 4 of 4 run) andpnpm conformance(15 built documents and 20 corpus round trips, committed report unchanged).What changed underneath, and how it was checked
No source change was needed. I read the 0.9.10 to 0.9.12 changelog and the
lib/diff first, then parsed the same inputs through the built package against each version:<in tag names, duplicate attributes,xmlnsrebinding, stylesheet and malformed processing instructions, CDATA, nested namespace declarations, a BOM) and 3,000 seeded mutations gave identical warnings, model readings, serialized bytes and fatal codes;buildCcdaemitted identical bytes for all fifteen conformance cases.The serializer never passes
requireWellFormed, and the builder and editor create elements only under constant names, so the serializer and creation-time advisories do not change what ccda emits. The parse-time denial-of-service fixes are reachable throughparseCcda, which is the real gain for users.Tests (
test/security.test.ts)Hostile input stays linear. Three shapes from the advisories run through
parseCcdaunder a 4,000 ms budget:<inside a malformed tagThe namespace-map advisory (GHSA-965w-775f-mr7g) has no case. Its fix is to memory, not time: at depth 10,000, 0.9.10 used 3 GB against 0.9.12's 200 MB, but 0.9.12 still took about 2.5 s, so a wall-clock budget cannot separate the versions cleanly.
What the parser reports differently, and what ccda does with it:
errorlevel.buildDomescalates onlyfatalError, so the document parses as before, with the same warning codes and serialized bytes as the clean document.DOMExceptionraised while building the DOM (an unbound prefix) now arrives as afatalError, and the parser's error keeps it ascause, which quotes the element name. ccda still throwsNOT_WELL_FORMED_XMLwith the registry message, an empty position and nocause. A probe asserts the parser-sidecauseexists, so the case cannot pass vacuously.xml-stylesheetinstruction, the shape 0.9.11's rewritten PI grammar touches and real C-CDA files often carry, round-trips verbatim. No test carried one before.Negative control: with
node_modules/@xmldom/xmldompointed at 0.9.10, the three timing cases fail (21.9 s, 19.6 s, 23.3 s) and so does thecauseprobe. The end-tag and stylesheet cases pass on both versions, as intended: they pin ccda's outcome, not the parser's.Left as is, for the owner to decide
ccda's
onErrordrops everywarninganderrorreport from the parser, including the new end-tag one. Surfacing these as a ccda warning would add a warning code (a minor bump) and is a decision of its own; the end-tag test is where that decision will show.Harness-Task: 106
🤖 Generated with Claude Code