[PR #6557] [MERGED] feat(sso): add SAML replay attack protection via InResponseTo validation #32344

Closed
opened 2026-04-17 23:11:02 -05:00 by GiteaMirror · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/better-auth/better-auth/pull/6557
Author: @Paola3stefania
Created: 12/5/2025
Status: Merged
Merged: 12/11/2025
Merged by: @Bekacru

Base: canaryHead: feat/saml-authnrequest-inresponseto


📝 Commits (10+)

  • d2f7c00 feat: add SAML replay attack protection
  • 9ed9a0a Merge branch 'canary' into feat/saml-authnrequest-inresponseto
  • b180306 make spell happy
  • 6ed1dbf Merge remote-tracking branch 'upstream/canary' into feat/saml-authnrequest-inresponseto
  • 593b26c Merge branch 'canary' into feat/saml-authnrequest-inresponseto
  • a1be1e7 fix: from in-memory default to verification table
  • 49ce659 Merge branch 'feat/saml-authnrequest-inresponseto' of https://github.com/Paola3stefania/better-auth into pr/6557
  • 7865235 Merge branch 'canary' into feat/saml-authnrequest-inresponseto
  • efedd51 Merge branch 'canary' into feat/saml-authnrequest-inresponseto
  • 6094955 Merge branch 'canary' into feat/saml-authnrequest-inresponseto

📊 Changes

7 files changed (+922 additions, -9 deletions)

View changed files

📝 docs/content/docs/plugins/sso.mdx (+135 -0)
packages/sso/src/authn-request-store.ts (+76 -0)
packages/sso/src/authn-request.test.ts (+99 -0)
📝 packages/sso/src/index.ts (+19 -7)
📝 packages/sso/src/routes/sso.ts (+208 -1)
📝 packages/sso/src/saml.test.ts (+336 -1)
📝 packages/sso/src/types.ts (+49 -0)

📄 Description


Summary by cubic

Adds SAML replay attack protection by validating InResponseTo against stored AuthnRequest IDs. Prevents replay and cross-provider injection, and can block IdP-initiated (unsolicited) responses while keeping existing setups backward compatible.

  • New Features

    • InResponseTo validation for SP-initiated SAML; enable via saml.enableInResponseToValidation or by providing saml.authnRequestStore.
    • AuthnRequestStore interface with default persistence via the verification table when no store is provided; in-memory test store and DEFAULT_AUTHN_REQUEST_TTL_MS exported.
    • Validation in SAML callback/ACS with allowIdpInitiated and requestTTL options, plus clear redirect errors on failure.
    • Docs updated with single vs multi-instance setup examples.
  • Migration

    • Single instance: set enableInResponseToValidation: true (no custom store needed). Optionally set allowIdpInitiated: false.
    • Multi instance: provide a shared authnRequestStore (e.g., Redis) so AuthnRequest IDs are available across nodes.

Written for commit c17b01b4d1. Summary will update automatically on new commits.

Summary

Adds InResponseTo validation for SAML SP-initiated flows to prevent replay attacks, unsolicited responses, and cross-provider injection.

Breaking Changes

None — This feature is opt-in to ensure backward compatibility.

How to Enable

Users can opt-in to this security enhancement in two ways:

**Single-instance deployments:**
sso({
    saml: {
        enableInResponseToValidation: true,
    },
})**Multi-instance deployments (automatically enabled):**
sso({
    saml: {
        authnRequestStore: redisStore, // providing a store enables validation
    },
})

What's Included

  • AuthnRequest ID tracking for SP-initiated SAML logins
  • InResponseTo validation against stored requests
  • One-time use enforcement (deleted after validation)
  • Configurable IdP-initiated flow restriction
  • Unit and integration tests
  • Documentation updates

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/better-auth/better-auth/pull/6557 **Author:** [@Paola3stefania](https://github.com/Paola3stefania) **Created:** 12/5/2025 **Status:** ✅ Merged **Merged:** 12/11/2025 **Merged by:** [@Bekacru](https://github.com/Bekacru) **Base:** `canary` ← **Head:** `feat/saml-authnrequest-inresponseto` --- ### 📝 Commits (10+) - [`d2f7c00`](https://github.com/better-auth/better-auth/commit/d2f7c00303dd27592c7b78a745da55935e56346d) feat: add SAML replay attack protection - [`9ed9a0a`](https://github.com/better-auth/better-auth/commit/9ed9a0a859564798b6f5a9cb39497eae0a8d2fb2) Merge branch 'canary' into feat/saml-authnrequest-inresponseto - [`b180306`](https://github.com/better-auth/better-auth/commit/b180306d67de281936de367be4ba0e936a08d9e8) make spell happy - [`6ed1dbf`](https://github.com/better-auth/better-auth/commit/6ed1dbf3a196ab7f2566e6a792575a853216c9a4) Merge remote-tracking branch 'upstream/canary' into feat/saml-authnrequest-inresponseto - [`593b26c`](https://github.com/better-auth/better-auth/commit/593b26ceb8cc86858574ee028414c5cc81dcaaf2) Merge branch 'canary' into feat/saml-authnrequest-inresponseto - [`a1be1e7`](https://github.com/better-auth/better-auth/commit/a1be1e7e3aa39e4c280f6e26336ec9f3ed12e879) fix: from in-memory default to verification table - [`49ce659`](https://github.com/better-auth/better-auth/commit/49ce65993bdd47fb1eeee10a176945a3afc609e3) Merge branch 'feat/saml-authnrequest-inresponseto' of https://github.com/Paola3stefania/better-auth into pr/6557 - [`7865235`](https://github.com/better-auth/better-auth/commit/786523570c0435ad186858de4bf21db98c43fb65) Merge branch 'canary' into feat/saml-authnrequest-inresponseto - [`efedd51`](https://github.com/better-auth/better-auth/commit/efedd517aec200ee20bfc5358554f83a9b114f46) Merge branch 'canary' into feat/saml-authnrequest-inresponseto - [`6094955`](https://github.com/better-auth/better-auth/commit/60949558d92ab3341e81362428dbd6f79330b3d9) Merge branch 'canary' into feat/saml-authnrequest-inresponseto ### 📊 Changes **7 files changed** (+922 additions, -9 deletions) <details> <summary>View changed files</summary> 📝 `docs/content/docs/plugins/sso.mdx` (+135 -0) ➕ `packages/sso/src/authn-request-store.ts` (+76 -0) ➕ `packages/sso/src/authn-request.test.ts` (+99 -0) 📝 `packages/sso/src/index.ts` (+19 -7) 📝 `packages/sso/src/routes/sso.ts` (+208 -1) 📝 `packages/sso/src/saml.test.ts` (+336 -1) 📝 `packages/sso/src/types.ts` (+49 -0) </details> ### 📄 Description <!-- This is an auto-generated description by cubic. --> --- ## Summary by cubic Adds SAML replay attack protection by validating InResponseTo against stored AuthnRequest IDs. Prevents replay and cross-provider injection, and can block IdP-initiated (unsolicited) responses while keeping existing setups backward compatible. - **New Features** - InResponseTo validation for SP-initiated SAML; enable via saml.enableInResponseToValidation or by providing saml.authnRequestStore. - AuthnRequestStore interface with default persistence via the verification table when no store is provided; in-memory test store and DEFAULT_AUTHN_REQUEST_TTL_MS exported. - Validation in SAML callback/ACS with allowIdpInitiated and requestTTL options, plus clear redirect errors on failure. - Docs updated with single vs multi-instance setup examples. - **Migration** - Single instance: set enableInResponseToValidation: true (no custom store needed). Optionally set allowIdpInitiated: false. - Multi instance: provide a shared authnRequestStore (e.g., Redis) so AuthnRequest IDs are available across nodes. <sup>Written for commit c17b01b4d1de9c04077995a3809380c54a10efd4. Summary will update automatically on new commits.</sup> <!-- End of auto-generated description by cubic. --> ## Summary Adds InResponseTo validation for SAML SP-initiated flows to prevent replay attacks, unsolicited responses, and cross-provider injection. ## Breaking Changes **None** — This feature is opt-in to ensure backward compatibility. ## How to Enable Users can opt-in to this security enhancement in two ways: ``` **Single-instance deployments:** sso({ saml: { enableInResponseToValidation: true, }, })**Multi-instance deployments (automatically enabled):** sso({ saml: { authnRequestStore: redisStore, // providing a store enables validation }, }) ``` ## What's Included - AuthnRequest ID tracking for SP-initiated SAML logins - InResponseTo validation against stored requests - One-time use enforcement (deleted after validation) - Configurable IdP-initiated flow restriction - Unit and integration tests - Documentation updates --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
GiteaMirror added the pull-request label 2026-04-17 23:11:02 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#32344