CVE-2025-24895
Description
CIE.AspNetCore.Authentication is an AspNetCore Remote Authenticator for CIE 3.0. Authentication using Spid and CIE is based on the SAML2 standard which provides two entities: 1. Identity Provider (IDP): the system that authenticates users and provides identity information (SAML affirmation) to the Service Provider, in essence, is responsible for the management of the credentials and identity of users; 2. 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 cie-aspnetcore refers to the second entity, the SP, and implements the validation logic of SAML assertions within SAML responses. In affected versions there is no guarantee that the first signature refers to the root object, it follows that if an attacker injects an item signed as the first element, all other signatures will not be verified. The only requirement is to have an XML element legitimately signed by the IdP, a condition that is easily met using the IdP's public metadata. An attacker could create an arbitrary SAML response that would be accepted by SPs using vulnerable SDKs, allowing him to impersonate any Spid and/or CIE user. This issue has been addressed in version 2.1.0 and all users are advised to upgrade. There are no known workarounds for this vulnerability.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
CIE.AspNetCore.AuthenticationNuGet | < 2.1.0 | 2.1.0 |
Patches
1e66b7f336ff5Fix xml signature verification and update to .net 9.0 (#19)
4 files changed · +44 −97
CIE.AspNetCore.Authentication/CIE.AspNetCore.Authentication/CIE.AspNetCore.Authentication.csproj+23 −23 modified@@ -1,7 +1,7 @@ <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> - <TargetFrameworks>net7.0;net6.0;net5.0</TargetFrameworks> + <TargetFrameworks>net9.0;net8.0;net7.0;net6.0</TargetFrameworks> <LangVersion>latest</LangVersion> <Description>AspNetCore Remote Authenticator for CIE</Description> <Authors>Daniele Giallonardo, Stefano Mostarda</Authors> @@ -12,42 +12,42 @@ <PackageProjectUrl>https://github.com/italia/cie-aspnetcore</PackageProjectUrl> <PackageIcon>cie-nuget.png</PackageIcon> <PackageLicenseExpression>MIT</PackageLicenseExpression> - <PackageVersion>2.0.4</PackageVersion> - <Version>2.0.4</Version> - <AssemblyVersion>2.0.4</AssemblyVersion> - <FileVersion>2.0.4</FileVersion> - <InformationalVersion>2.0.4</InformationalVersion> + <PackageVersion>2.1.0</PackageVersion> + <Version>2.1.0</Version> + <AssemblyVersion>2.1.0</AssemblyVersion> + <FileVersion>2.1.0</FileVersion> + <InformationalVersion>2.1.0</InformationalVersion> <PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance> <PackageReadmeFile>README.md</PackageReadmeFile> <RepositoryUrl>https://github.com/italia/cie-aspnetcore</RepositoryUrl> </PropertyGroup> - <ItemGroup> - <PackageReference Include="Microsoft.AspNetCore.Authentication" Version="2.2.0" /> - <PackageReference Include="Microsoft.AspNetCore.Mvc.ViewFeatures" Version="2.2.0" /> - <PackageReference Include="Microsoft.AspNetCore.Razor" Version="2.2.0" /> - <PackageReference Include="Microsoft.AspNetCore.Razor.Language" Version="6.0.21" /> + <ItemGroup> + <FrameworkReference Include="Microsoft.AspNetCore.App" /> + </ItemGroup> + + <ItemGroup Condition=" '$(TargetFramework)' == 'net9.0' "> + <PackageReference Include="Microsoft.Extensions.Http" Version="9.0.1" /> + <PackageReference Include="System.Security.Cryptography.Xml" Version="9.0.1" /> + <PackageReference Include="Microsoft.Extensions.Identity.Core" Version="9.0.1" /> </ItemGroup> - <ItemGroup Condition=" '$(TargetFramework)' == 'net7.0' or '$(TargetFramework)' == 'net6.0'"> - <PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="7.0.4" /> - <PackageReference Include="Microsoft.Extensions.Http" Version="7.0.0" /> - <PackageReference Include="System.Security.Cryptography.Xml" Version="7.0.1" /> + <ItemGroup Condition=" '$(TargetFramework)' == 'net8.0' "> + <PackageReference Include="Microsoft.Extensions.Http" Version="8.0.1" /> + <PackageReference Include="Microsoft.Extensions.Identity.Core" Version="8.0.12" /> + <PackageReference Include="System.Security.Cryptography.Xml" Version="8.0.2" /> </ItemGroup> <ItemGroup Condition=" '$(TargetFramework)' == 'net7.0' "> - <PackageReference Include="Microsoft.Extensions.Identity.Core" Version="7.0.10" /> + <PackageReference Include="Microsoft.Extensions.Http" Version="8.0.1" /> + <PackageReference Include="Microsoft.Extensions.Identity.Core" Version="7.0.12" /> + <PackageReference Include="System.Security.Cryptography.Xml" Version="8.0.2" /> </ItemGroup> <ItemGroup Condition=" '$(TargetFramework)' == 'net6.0' "> + <PackageReference Include="Microsoft.Extensions.Http" Version="8.0.1" /> <PackageReference Include="Microsoft.Extensions.Identity.Core" Version="6.0.21" /> - </ItemGroup> - - <ItemGroup Condition=" '$(TargetFramework)' == 'net5.0' "> - <PackageReference Include="Microsoft.Extensions.Identity.Core" Version="5.0.17" /> - <PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="5.0.0" /> - <PackageReference Include="Microsoft.Extensions.Http" Version="5.0.0" /> - <PackageReference Include="System.Security.Cryptography.Xml" Version="5.0.0" /> + <PackageReference Include="System.Security.Cryptography.Xml" Version="8.0.2" /> </ItemGroup> <ItemGroup>
CIE.AspNetCore.Authentication/CIE.AspNetCore.Authentication/Helpers/XmlHelpers.cs+17 −70 modified@@ -1,12 +1,10 @@ using CIE.AspNetCore.Authentication.Resources; using System; -using System.Collections.Concurrent; using System.Linq; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography.Xml; using System.Xml; -using System.Xml.Serialization; namespace CIE.AspNetCore.Authentication.Helpers { @@ -36,7 +34,7 @@ internal static XmlElement SignXMLDoc(XmlDocument doc, try { - privateKey = certificate.PrivateKey; + privateKey = certificate.GetRSAPrivateKey(); } catch (Exception ex) { @@ -80,11 +78,9 @@ internal static bool VerifySignature(XmlDocument signedDocument, Saml.IdP.Entity try { - SignedXml signedXml = new SignedXml(signedDocument); - if (xmlMetadata is not null) { - bool validated = false; + var validated = false; var idpSSODescriptor = xmlMetadata.Items.FirstOrDefault(i => i is Saml.IdP.IDPSSODescriptorType) as Saml.IdP.IDPSSODescriptorType; if (idpSSODescriptor is not null) { @@ -96,14 +92,7 @@ internal static bool VerifySignature(XmlDocument signedDocument, Saml.IdP.Entity var x509Cert = keyData.Items.FirstOrDefault(i => i is byte[]) as byte[]; if (x509Cert is not null) { - var publicMetadataCert = new X509Certificate2(x509Cert); - 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); + validated |= VerifyAllSignatures(signedDocument, new X509Certificate2(x509Cert)); } } } @@ -112,11 +101,7 @@ internal static bool VerifySignature(XmlDocument signedDocument, Saml.IdP.Entity } else { - XmlNodeList nodeList = (signedDocument.GetElementsByTagName("ds:Signature")?.Count > 0) ? - signedDocument.GetElementsByTagName("ds:Signature") : - signedDocument.GetElementsByTagName("Signature"); - signedXml.LoadXml((XmlElement)nodeList[0]); - return signedXml.CheckSignature(); + return VerifyAllSignatures(signedDocument); } } catch (Exception) @@ -125,64 +110,26 @@ internal static bool VerifySignature(XmlDocument signedDocument, Saml.IdP.Entity } } - private static readonly ConcurrentDictionary<Type, XmlSerializer> serializers = new ConcurrentDictionary<Type, XmlSerializer>(); - /// <summary> - /// Serializes to XML document. - /// </summary> - /// <param name="o">The o.</param> - /// <returns></returns> - public static XmlDocument SerializeToXmlDoc(this object o) + private static bool VerifyAllSignatures(XmlDocument signedDocument, X509Certificate2? publicMetadataCert = null) { - XmlDocument doc = new XmlDocument() { PreserveWhitespace = true }; + bool internalResult = true; + + XmlNodeList signatureNodes = signedDocument.GetElementsByTagName("Signature", SignedXml.XmlDsigNamespaceUrl); - using XmlWriter writer = doc.CreateNavigator().AppendChild(); - if (!serializers.ContainsKey(o.GetType())) + if (signatureNodes.Count == 0) { - var serializer = new XmlSerializer(o.GetType()); - serializers.AddOrUpdate(o.GetType(), serializer, (key, value) => serializer); + return false; } - serializers[o.GetType()].Serialize(writer, o); - - return doc; - } - - public static XmlElement SerializeInternalExtensionToXmlElement(object o, string namespacePrefix, string xmlNamespace) - { - XmlDocument doc = SerializeExtensionToXmlElementInternal(o, namespacePrefix, xmlNamespace); - - return doc.DocumentElement.FirstChild as XmlElement; - } - public static XmlElement SerializeExtensionToXmlElement(object o, string namespacePrefix, string xmlNamespace) - { - XmlDocument doc = SerializeExtensionToXmlElementInternal(o, namespacePrefix, xmlNamespace); - - return doc.DocumentElement; - } - - private static XmlDocument SerializeExtensionToXmlElementInternal(object o, string namespacePrefix, string xmlNamespace) - { - XmlDocument doc = new XmlDocument(); - - using (XmlWriter writer = doc.CreateNavigator().AppendChild()) + foreach (var signatureNode in signatureNodes) { - var ns = new XmlSerializerNamespaces(); - ns.Add(namespacePrefix, xmlNamespace); - new XmlSerializer(o.GetType()).Serialize(writer, o, ns); + SignedXml signedXml = new(signedDocument); + signedXml.LoadXml((XmlElement)signatureNode); + internalResult &= publicMetadataCert is null + ? signedXml.CheckSignature() + : signedXml.CheckSignature(publicMetadataCert, true); } - - return doc; - } - - public static XmlElement GetXmlElement(string prefix, string prefixNamespace, string tag, string value = null) - { - XmlDocument doc = new XmlDocument(); - - XmlElement elem = doc.CreateElement(prefix, tag, prefixNamespace); - if(!string.IsNullOrEmpty(value)) - elem.InnerText = value; - - return elem; + return internalResult; } } }
CIE.AspNetCore.Authentication/CIE.AspNetCore.WebApp/CIE.AspNetCore.WebApp.csproj+2 −2 modified@@ -1,13 +1,13 @@ <Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> - <TargetFramework>net7.0</TargetFramework> + <TargetFramework>net9.0</TargetFramework> <CopyRefAssembliesToPublishDirectory>false</CopyRefAssembliesToPublishDirectory> <UserSecretsId>b637b4cd-be76-4dc7-851e-b721746073a1</UserSecretsId> </PropertyGroup> <ItemGroup> - <PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="7.0.10" /> + <PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="9.0.1" /> </ItemGroup> <ItemGroup>
.github/workflows/dotnet.yml+2 −2 modified@@ -22,7 +22,7 @@ jobs: - name: Setup .NET uses: actions/setup-dotnet@v1 with: - dotnet-version: 7.x + dotnet-version: 9.x - name: Restore dependencies run: dotnet restore working-directory: CIE.AspNetCore.Authentication @@ -44,7 +44,7 @@ jobs: - name: Update apt repo run: sudo apt update - name: Install dependencies - run: sudo apt install -y libxml2-dev libxmlsec1-dev libxmlsec1-openssl xmlsec1 python3-pip && pip install cryptography==38.0.4 + run: sudo apt install -y libxml2-dev libxmlsec1-dev libxmlsec1-openssl xmlsec1 python3-pip - name: Install spid-sp-test run: sudo pip install spid-sp-test --upgrade --no-cache - name: Test Metadata cie-sp-public with spid-sp-test
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
3News mentions
0No linked articles in our index yet.