CVE-2025-23369GitHub Enterprise Server SAML bypass via libxml2 canonicalization
What broke
GitHub Enterprise Server's SAML verifier trusted libxml2's canonicalization of the signed assertion. Canonicalization quirks let an attacker present XML that verifies one way and is interpreted another. The result is an authentication bypass on self-hosted GitHub SSO. GitHub shipped a patched GHES release.
Why it matters
GHES is often the crown-jewel service provider in an enterprise: source, secrets in Actions, and production deploy keys. An SSO bypass there is not "just a forge login." It is a path to the codebase and the CI identity plane. The bug is also a reminder that XML DSig is only as strong as the canonicalizer you share with the attacker.
What to do
- Apply the GHES security update that lists CVE-2025-23369. Confirm the version on every appliance, including DR.
- If GHES SAML was reachable while unpatched, review new organization owners and PAT grants that have no matching IdP session.
- Prefer OIDC to GitHub where you can. The OIDC path does not inherit this XML stack.
After you patch
A SAML bypass means the service provider accepted an assertion it should have rejected, so anyone who exploited it authenticated as a real user and left a normal-looking log line.
- Revoke every session issued by the affected service provider, then rotate its session signing keys. Patching stops new forgeries and does nothing about sessions already minted.
- Audit administrative accounts and group memberships for changes during the exposure window. Signing in as an administrator is the point of this class, and adding a second account is the standard persistence step.
- Rotate the identity provider signing certificate if the flaw involved signature validation, and confirm the service provider pins the expected certificate rather than trusting anything in the assertion.
- Check your own implementation for the same class: exact-match comparison on verification results, rejection of unexpected signature algorithms, and audience and recency checks on every assertion. See SAML 2.0 and SAML vs OIDC.
Sources
- NVD: CVE-2025-23369
- GitHub Enterprise Server release notes
Related identity CVEs
- CVE-2025-47949samlify signature wrapping, forge SAML as any user
- CVE-2025-25291ruby-saml parser differential enables signature wrapping
- CVE-2024-9487GitHub Enterprise Server SAML encrypted-assertion, incomplete fix
- CVE-2024-6800GitHub Enterprise Server SAML XML signature wrapping
- CVE-2024-4985GitHub Enterprise Server SAML encrypted-assertion bypass
Related on Start with Identity
- CVEGitHub Enterprise Server SAML encrypted-assertion bypass
GHES with optional encrypted SAML assertions accepted a forged response. An unauthenticated attacker could provision a site administrator. Fixed in 3.9.15, 3.10
- CVEGitHub Enterprise Server SAML encrypted-assertion, incomplete fix
The leftover path after CVE-2024-4985. Encrypted SAML assertions on GHES could still be forged. GitHub shipped a second hardening pass. Treat 4985 and 9487 as o
- CVEGitHub Enterprise Server SAML XML signature wrapping
A third 2024 GHES SAML path. An attacker with network access could wrap a signature and provision a privileged user. Same product, same year, same lesson: do no
- BlogFortinet's January SSO bypass hit boxes already patched for December's SAML bug
CVE-2026-24858 is the follow-on FortiCloud SSO SAML bypass. Devices patched for CVE-2025-59718 and 59719 were still exploitable. Actively exploited. CISA guidan
- GlossaryIdentity Federation
A trust relationship between identity providers and service providers that lets users authenticate once at their home IdP and access applications at the other p
- GlossarySSO
Single Sign-On. A user authenticates once and gains access to multiple applications without re-entering credentials. Implemented with SAML or OIDC in modern dep
Technique
This CVE is an instance of Federation trust abuse and SAML forgery. A service provider that accepts a SAML assertion it should have rejected treats a forged identity as authenticated, because the failure sits in signature validation code, not in cryptography.