[PR #6719] [MERGED] feat(saml): enforce one-time use of SAML assertions #6847

Closed
opened 2026-03-13 13:13:42 -05:00 by GiteaMirror · 0 comments
Owner

📋 Pull Request Information

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

Base: canaryHead: feat/saml-replay-protection


📝 Commits (10+)

📊 Changes

8 files changed (+570 additions, -453 deletions)

View changed files

📝 docs/content/docs/plugins/sso.mdx (+28 -57)
packages/sso/src/authn-request-store.ts (+0 -76)
packages/sso/src/authn-request.test.ts (+0 -99)
packages/sso/src/constants.ts (+42 -0)
📝 packages/sso/src/index.ts (+0 -11)
📝 packages/sso/src/routes/sso.ts (+226 -87)
📝 packages/sso/src/saml.test.ts (+274 -112)
📝 packages/sso/src/types.ts (+0 -11)

📄 Description

Summary by cubic

Adds SAML assertion replay protection to enforce one-time use of assertions during SSO callback and ACS. Assertion IDs are stored with a TTL and replays are rejected with an error redirect.

  • New Features

    • Tracks each SAML Assertion ID in the verification store until NotOnOrAfter + clock skew (or a default TTL) and rejects re-use with error=replay_detected.
    • Replay protection is always enabled (no configuration toggle).
    • Centralized SAML constants in constants.ts (key prefixes, TTLs, clock skew) and added USED_ASSERTION_KEY_PREFIX.
    • Extracts assertionId from SAML XML using fast-xml-parser.
    • Expanded tests covering callback, ACS, and cross-endpoint replay scenarios with a shared mock IdP.
  • Migration

    • DEFAULT_CLOCK_SKEW_MS and DEFAULT_AUTHN_REQUEST_TTL_MS are now exported from constants.ts and are no longer re-exported from the package root. Update imports accordingly.
    • Removed AuthnRequestStore, createInMemoryAuthnRequestStore, and the saml.authnRequestStore option. InResponseTo validation now always uses the verification table—remove any custom store usage.

Written for commit 24ffbc6bca. Summary will update automatically on new commits.


🔄 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/6719 **Author:** [@Paola3stefania](https://github.com/Paola3stefania) **Created:** 12/12/2025 **Status:** ✅ Merged **Merged:** 12/17/2025 **Merged by:** [@Bekacru](https://github.com/Bekacru) **Base:** `canary` ← **Head:** `feat/saml-replay-protection` --- ### 📝 Commits (10+) - [`662a617`](https://github.com/better-auth/better-auth/commit/662a61795a54c9a7e3d316d20cd89e8a4162c64c) feat: replay protection - [`0ef1988`](https://github.com/better-auth/better-auth/commit/0ef19889d1db38d7de57f3dfce22d7ff8380c05f) Merge branch 'canary' into feat/saml-replay-protection - [`5453747`](https://github.com/better-auth/better-auth/commit/5453747575b84a48b5c671f76cfb9cf1a9516330) feat: docu - [`1e08083`](https://github.com/better-auth/better-auth/commit/1e0808322684892cd39a5c8a73f853bc9c0f1fdf) Merge branch 'feat/saml-replay-protection' of https://github.com/better-auth/better-auth into feat/saml-replay-protection - [`560e9db`](https://github.com/better-auth/better-auth/commit/560e9db914f4c14c00a11797c485ae628b21581d) feat: add acsendpoint protection - [`b97a2c6`](https://github.com/better-auth/better-auth/commit/b97a2c6b1e8a615429cc846a5542de75fa5052a7) feat: more test scenario and docu - [`1e5beb7`](https://github.com/better-auth/better-auth/commit/1e5beb7913167fa5272e3b7de8b98ac7d294aa45) Merge branch 'canary' into feat/saml-replay-protection - [`635d07f`](https://github.com/better-auth/better-auth/commit/635d07f27f35275d897791d374a88b727dfe8f5c) make lint happy - [`4f9c8ba`](https://github.com/better-auth/better-auth/commit/4f9c8ba780a925443b4a218b0fdfa0281a1fd682) Merge branch 'feat/saml-replay-protection' of https://github.com/better-auth/better-auth into feat/saml-replay-protection - [`61e9f2e`](https://github.com/better-auth/better-auth/commit/61e9f2e01a87017e154d9411cc3c40409103a511) Merge branch 'canary' into feat/saml-replay-protection ### 📊 Changes **8 files changed** (+570 additions, -453 deletions) <details> <summary>View changed files</summary> 📝 `docs/content/docs/plugins/sso.mdx` (+28 -57) ➖ `packages/sso/src/authn-request-store.ts` (+0 -76) ➖ `packages/sso/src/authn-request.test.ts` (+0 -99) ➕ `packages/sso/src/constants.ts` (+42 -0) 📝 `packages/sso/src/index.ts` (+0 -11) 📝 `packages/sso/src/routes/sso.ts` (+226 -87) 📝 `packages/sso/src/saml.test.ts` (+274 -112) 📝 `packages/sso/src/types.ts` (+0 -11) </details> ### 📄 Description <!-- This is an auto-generated description by cubic. --> ## Summary by cubic Adds SAML assertion replay protection to enforce one-time use of assertions during SSO callback and ACS. Assertion IDs are stored with a TTL and replays are rejected with an error redirect. - **New Features** - Tracks each SAML Assertion ID in the verification store until NotOnOrAfter + clock skew (or a default TTL) and rejects re-use with error=replay_detected. - Replay protection is always enabled (no configuration toggle). - Centralized SAML constants in constants.ts (key prefixes, TTLs, clock skew) and added USED_ASSERTION_KEY_PREFIX. - Extracts assertionId from SAML XML using fast-xml-parser. - Expanded tests covering callback, ACS, and cross-endpoint replay scenarios with a shared mock IdP. - **Migration** - DEFAULT_CLOCK_SKEW_MS and DEFAULT_AUTHN_REQUEST_TTL_MS are now exported from constants.ts and are no longer re-exported from the package root. Update imports accordingly. - Removed AuthnRequestStore, createInMemoryAuthnRequestStore, and the saml.authnRequestStore option. InResponseTo validation now always uses the verification table—remove any custom store usage. <sup>Written for commit 24ffbc6bca2051e36526dcef411a3f4573ee133c. Summary will update automatically on new commits.</sup> <!-- End of auto-generated description by cubic. --> --- <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-03-13 13:13:42 -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#6847