Skip to content

🔐 Security / XML Signature Wrapping (XSW) defenses + test corpus #39

@docJerem

Description

@docJerem

Context

XML Signature Wrapping (XSW) is the most common real-world break of SAML SP implementations: an attacker takes a legitimately signed assertion, wraps or relocates it in the document, and injects a second, attacker-controlled assertion that the consuming code reads — while signature verification still succeeds against the original signed node.

ExSaml.Core.Sp extracts the assertion via XPath and then calls Dsig.verify/2. We need to guarantee the invariant: the node whose signature was verified is exactly the node whose contents are consumed (subject, NameID, attributes, conditions). If verification and extraction can ever resolve to different nodes, the SP is exploitable.

Goal

  1. Review the response/assertion consumption path (Core.Sp, Core.Xml.Dsig) and make the "verified node == consumed node" binding explicit and enforced (not incidental to XPath ordering).
  2. Add a dedicated XSW test corpus that fails closed.

Proposed scope

  • Audit decrypt/extract/verify ordering in Core.Sp for:
    • response-level signature vs assertion-level signature (and both present),
    • multiple saml:Assertion elements in one response,
    • signed element relocated under a different parent (classic XSW),
    • Reference URI pointing to an Id that is not the consumed element,
    • duplicated Id attributes.
  • Bind digest/reference resolution to the concrete consumed node rather than re-querying the document.
  • Test fixtures covering each wrapping variant above, each asserting rejection (:bad_signature / :bad_digest / a dedicated reason).

Why

This is the single highest-value SAML security check after "verify is actually cryptographic" (already satisfied — Dsig.verify/2 calls :public_key.verify and binds trust to configured IdP fingerprints). Without explicit XSW defenses, a valid signature on a benign assertion can authorise a forged one.

Out of scope

  • General XXE / c14n corpus (tracked separately).

Relates to #32.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions