GitHub Advisoryadvisory · NuGet

GHSA-36h8-r92j-w9vw The AspNetCore Remote Authenticator for SPID Allows SAML Response Signature Verification Bypass

CRITICAL Published 2025-02-18 Modified 2025-02-18 Official page ↗
Aliases
CVE-2025-24894
Ecosystem
NuGet
Packages
SPID.AspNetCore.Authentication
Severity
Critical
CVSS vector
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N
Weaknesses
CWE-290
Reviewed
2025-02-18

Affected packages

• NuGet SPID.AspNetCore.Authentication: < 3.4.0 → fixed in 3.4.0

Description

Description Authentication using Spid and CIE is based on the SAML2 standard which provides for two entities: Identity Provider (IdP): the system that authenticates users and provides identity information ( SAML assertions ) to the Service Provider, essentially, it is responsible for managing user credentials and identity; Service Provider (SP): The system that provides a service to the user and relies on the Identity Provider to authenticate the user, receives SAML assertions from the IdP to grant access to resources. The library `spid-aspnetcorerefers` to the second entity, i.e. the SP, and implements the validation logic of the SAML assertions present within the SAML response . The following is a summary diagram of an authentication flow via SAML: As shown in the diagram, the IdP, after verifying the user's credentials, generates a signed SAML response, this is propagated to the SP by the user's browser and the SP, after verifying the signature, can extract the data needed to build the user's session. The signature validation logic is central as it ensures that you cannot craft a SAML response with arbitrary assertions and thus impersonate other users. The following is the validation code implemented in `spid-aspnetcore`. ```csharp internal static bool VerifySignature(XmlDocument signedDocument, IdentityProvider? identityProvider = null){ //...SNIP... SignedXml signedXml = new SignedXml(signedDocument); if (identityProvider is not null) { bool validated = false; foreach (var certificate in identityProvider.X509SigningCertificates){ var publicMetadataCert = new X509Certificate2(Convert.FromBase64String(certificate)); XmlNodeList nodeList = (signedDocument.GetElementsByTagName("ds:Signature")?.Count > 1) ? signedDocument.GetElementsByTagName("ds:Signature") : (signedDocument.GetElementsByTagName("ns2:Signature")?.Count > 1) ? signedDocument.GetElementsByTagName("ns2:Signature") : signedDocument.GetElementsByTagName("Signature"); signedXml.LoadXml((XmlElement)nodeList[0]); validated |= signedXml.CheckSignature(publicMetadataCert, true); } return validated; } else{ XmlNodeList nodeList = (signedDocument.GetElementsByTagName("ds:Signature")?.Count > 0) ? signedDocument.GetElementsByTagName("ds:Signature") : signedDocument.GetElementsByTagName("Signature"); signedXml.LoadXml((XmlElement)nodeList[0]); return signedXml.CheckSignature(); } //...SNIP... } ``` The parameter `signedDocument` contains the SAML response in XML format, while the parameter `identityProvider` can contain the IdP info. If the parameter `identityProvider` has been specified, the public certificates of that IdP are extracted, so as to force their use during the signature verification, otherwise the certificates configured within the application are used. Next, a response envelope is generated nodeList within which all XML elements containing an XML signature of part or all of the SAML response envelope are saved. Finally, the first element of this list, i.e. the first signature found, is extracted and verified. In a normal authentication flow, the SAML response looks like this (note that some fields and attributes have been omitted for ease of reading): ```xml https://demo.spid.gov.it/validator https://demo.spid.gov.it/validator AGID-001 ``` The SDK code would get as the first element of the `nodeList`, that is `nodeList[0]`, the signature referring to the entire SAML response, in fact the reference of the first signature `` points to the root object ``. Therefore, verifying this signature will ensure that the entire content of the SAML response is intact and authentic. However, there is no guarantee that the first signature refers to the root object, so if an attacker injects a signed element as the first element, all other signatures will not be verified. The only requirement is to have a legitimately signed XML element from the IdP, which is easily accomplished using the public metadata of the IdP. The SAML response would be structured like this: …

Related

Alias · CVE (1)

  • CVE-2025-24894 SPID.AspNetCore.Authentication is an AspNetCore Remote Authenticator for SPID. vulnerability

Weakness · CWE (1)

  • CWE-290 Authentication Bypass by Spoofing weakness

References