Repository navigation
fix: diagnose Algorithm URI whitespace - #576
Conversation
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (3)
🚧 Files skipped from review as they are similar to previous changes (1)
Included review availability: This review used your included allowance. Your plan provides up to 2 included reviews per hour; 0 remain after this review. 📝 WalkthroughWalkthroughUnsupported signature, canonicalization, and hash algorithm errors now use a shared formatter. When XML whitespace collapse produces a supported algorithm name, the error adds a diagnostic. Algorithm lookup and construction remain unchanged. ChangesAlgorithm whitespace diagnostics
Priority: ⬇️ Low Estimated code review effort: 2 (Simple) | ~10 minutes Change: Bug fix · Severity of issue fixed: Low Suggested reviewers: Merge Risk: ⚪ Minimal · up to The change improves unsupported-algorithm diagnostics without accepting whitespace-padded identifiers or changing signature verification. No actionable merge-blocking risk remains, subject to normal build and test checks. Security Architecture ReviewSecurity architecture risk: ⚪ Minimal · up to The current revision improves diagnostics without accepting whitespace-padded algorithm identifiers. The previously described normalization bypass is not present in this change, and no introduced or worsened security risk was identified in the reviewed paths. Retained concerns Security review detailsSecurity Blast Radius
Security Findings and Attack Paths
Trust Boundaries and Controls
Resilience and Maintainability Implications
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
Full details: Linked Issues checkExplanation Issue
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #576 +/- ##
==========================================
+ Coverage 83.63% 83.89% +0.25%
==========================================
Files 9 9
Lines 1210 1217 +7
Branches 307 308 +1
==========================================
+ Hits 1012 1021 +9
+ Misses 119 118 -1
+ Partials 79 78 -1 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
Thanks, Wes. This implements the normalization requested in #548, but review uncovered a concrete algorithm-policy bypass. We should hold this PR in its current form. Reproduced against master Start with a valid RSA-SHA1 signature and a consumer that rejects RSA-SHA1 by comparing the raw
This reduces security for that consumer: the upgrade turns an attacker-modified document that was rejected into one that passes the combined policy and verification checks. The attacker needs an existing valid RSA-SHA1 signature under the verifier's trusted key, but does not need the signing key to insert the decoy. The demonstrated impact is bypassing the consumer's SHA-1 prohibition; the cryptographic signature still verifies over the original signed content. The broad lookup predates this PR. Both algorithm selectors search descendants of There is a further constraint on fixing this separately: an isolated experiment that only scopes the library's selectors to namespace-qualified direct children of Controls confirmed that checking the actual method directly under For #548, the immediate change should preserve rejection and explain the whitespace in the error. The existing selector/structure problem needs a separate security fix with public-API regression tests. Any later normalization proposal needs review against consumer algorithm policies as well as XML schema semantics. |
|
Further AI analysis: A safe design needs three pieces:
The existing registries around signed-xml.ts are already close to algorithm allowlists, but a constructor-level verification policy would make the security decision explicit and cover all four algorithm types consistently. That produces these behaviors:
I would therefore split this into:
There is no general way for the library to make unconditional normalization safe for arbitrary consumers that inspect the raw DOM themselves. The policy decision has to move inside the verifier—or normalization must remain an explicit compatibility opt-in. This directly addresses the concern documented in the security review. |
Unconditional anyURI collapse let an unsigned, whitespace-padded SignatureMethod decoy verify while a raw-string RSA-SHA1 ban still allowed the padded identifier. Keep the exact attribute for registry lookup and name the whitespace mismatch in the unsupported-algorithm error. Refs node-saml#548
dad8530 to
b0e76dc
Compare
|
@cjbarth, I've updated the branch to have a clean commit history with the patch you requested. Let me know if you have any follow-up change requests. |
|
A note for the review, since it bears on the milestone. |
…hitespace Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The algorithm registries are object literals, so `Algorithm=" constructor "` collapsed to `constructor`, found `Object.prototype.constructor`, and the error said it matched a supported algorithm. The diagnostic now takes the registry and checks only its own properties. The tests that expect no whitespace clause now compare the whole message: a substring match passed with or without it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Maintainer review — 2026-09-11: held for a security regression (review). Resolved on 2026-09-25: the branch was reset, and it no longer collapses the value for verification.
Author update — 2026-09-25: branch reset to address security regression and limit scope.
Fixes #548. This is the diagnostic path requested after the security hold on unconditional anyURI collapse.
Algorithmis typed asxsd:anyURI(XML Schema 2 §3.2.17), which collapses whitespace. XML 1.0 §3.3.3 attribute-value normalization turns a pretty-printer line wrap into trailing spaces but does not collapse them, so a supported URI fails registry lookup with a genericis not supportederror. Collapsing on read fixed that for legitimate wraps, but also let an unsigned, whitespace-paddedSignatureMethoddecoy verify while a consumer that bans RSA-SHA1 by comparing the raw attribute string still allowed the padded identifier:masteris not supportedcheckSignaturereturnstrueThe broad descendant lookup that selects the decoy predates this PR. An exact, unpadded decoy is already honored on
master.Changes
findSignatureAlgorithm,findCanonicalizationAlgorithm, andfindHashAlgorithmkeep looking up the exact attribute value. On miss,utils.formatUnsupportedAlgorithmMessage()collapses for diagnostics only: if the collapsed form is one of the registry's own keys, the error says so and that whitespace is not collapsed. Own keys only, because the registries are object literals and would otherwise matchconstructorortoString.collapseAnyUristays module-private inutils.ts.formatUnsupportedAlgorithmMessageis not re-exported from the package barrel.JSON.stringify, so trailing spaces are visible in the message.This does not make line-wrapped algorithms verify. That, with the structure and policy changes it needs, is #628 on 7.0 (discussion).
Tests
rejects line-wrapped {CanonicalizationMethod,Transform,SignatureMethod,DigestMethod} Algorithm with a whitespace diagnostic: still rejects; message names the supported URI after collapse.still rejects a genuinely unregistered Algorithm URI: trailing spaces, no "matches the supported algorithm" clause.does not report an inherited Object property as a supported algorithm:" constructor "collapses to anObject.prototypename, and the error has no whitespace clause.does not treat NBSP as Algorithm whitespace:\u00A0is not collapsed as XML whitespace.rejects a whitespace-padded SignatureMethod decoy outside SignedInfo:ObjectbeforeSignedInfois selected (same asmaster); verification throws the diagnostic rather than returningtrue.documents that an exact SignatureMethod decoy outside SignedInfo is selected: RSA-SHA256 decoy is selected; verification fails withinvalid signature: the signature value … is incorrect.npm run build,npm test(517 passing) andnpm run lintpass.Summary by CodeRabbit
Release Notes