Skip to content

Reject a signature with more than one reference instead of ignoring it #465

Open

Description

@cjbarth

getVerifiedXml() in src/xml.ts returns null when a signature has more than one Reference (xml.ts#L99), so the caller treats the element as unsigned. Every other ambiguity check in that function throws, which rejects the whole message with a specific error. Those checks cover a second signature on the element, a reference that doesn't point at the signature's parent, a quote in the reference URI, an ID carried by more than one element, and too many transforms.

For three of the four callers, the difference is only the message. An assertion, an encrypted assertion and a POST LogoutRequest must verify, so a null becomes a generic rejection: Invalid signature, Invalid signature from encrypted assertion or Invalid signature on documentElement.

The exception is a Response's own signature under wantAuthnResponseSigned: false. The signature is ignored, and if the assertion is signed separately, the response is accepted. I checked this against the build with a Response whose root signature references both the Response and the assertion, over a separately signed assertion. It is accepted with wantAuthnResponseSigned: false, and rejected with Invalid document signature by default.

This isn't a bypass. The assertion's own signature is verified, and the profile comes from its verified bytes. But the document carries a signature the library can't read one way, and AGENTS.md says to refuse such a document rather than pick a reading. "Unsigned" is a reading.

Scope

  • Make getVerifiedXml() throw when a signature doesn't have exactly one Reference, with a specific message, as its sibling checks do. For example: Invalid signature: a signature must have exactly one reference. xml-crypto's loadSignature() already throws when there are none.
  • In test/test-signatures.spec.ts, assert the new message for response.root-signed-2references.assertion-unsigned.xml (added in Add tests for the signature ambiguity rejections, the SHA-1 fallback, and error statuses #460). Add a fixture for the case that 5.x accepts: a root signature with two references, over a separately signed assertion, under wantAuthnResponseSigned: false.
  • Name the rejection in the v6 release notes.

This rejects a response 5.x accepts, so it waits for the major. 5.2.0 warns first: #466.

🤖 Generated with Claude Code

Activity

  1. added this to the v6 milestone on Sep 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions