Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-18108

CVE-2026-18108: Net::SAML2 Auth Bypass Vulnerability

CVE-2026-18108 is an authentication bypass flaw in Net::SAML2 for Perl that allows attackers to authenticate as arbitrary users via unsigned encrypted assertions. This article covers technical details, affected versions, and mitigations.

Published:

CVE-2026-18108 Overview

CVE-2026-18108 is an authentication bypass in the Net::SAML2 Perl module affecting all versions before 0.86. The _verify_encrypted_assertion function decrypts an EncryptedAssertion and returns it as verified when the decrypted content contains no dsig:Signature element. Signature and trust anchor checks are skipped entirely, so an unsigned assertion reaches new_from_xml unverified. Because a Service Provider's encryption certificate is published in its SAML metadata, any unauthenticated party can encrypt a forged assertion, wrap it in a samlp:Response, and post it to the Assertion Consumer Service to authenticate as an arbitrary user. This weakness is classified as improper verification of a cryptographic signature [CWE-347].

Critical Impact

Unauthenticated attackers can impersonate any user on Service Providers that configure a decryption key_file in Net::SAML2.

Affected Products

  • Net::SAML2 for Perl, all versions before 0.86
  • Perl Service Provider applications that configure a decryption key_file and accept EncryptedAssertion elements
  • Fixed in Net::SAML2 version 0.86

Discovery Timeline

  • 2026-08-03 - CVE CVE-2026-18108 published to NVD
  • 2026-08-03 - Last updated in NVD database

Technical Details for CVE-2026-18108

Vulnerability Analysis

The vulnerability resides in lib/Net/SAML2/Protocol/Assertion.pm inside the _verify_encrypted_assertion routine. After decrypting an EncryptedAssertion, the function short-circuits verification using return $xml unless $xpath->exists('dsig:Signature', $assert);. When no dsig:Signature element is present in the decrypted assertion, the code path treats the assertion as trusted and returns it directly. The subsequent signature validation and trust anchor checks never execute for unsigned assertions. new_from_xml then reads the NameID and attributes from the untrusted XML into the assertion object, and the calling Service Provider consumes those identity fields as authenticated user data.

Root Cause

The root cause is a missing precondition: the code assumes that presence of a signature is optional and that absence implies trust rather than rejection. SAML security requires that assertions used for authentication be signed by a trusted Identity Provider (IdP), or, when only the assertion is encrypted, that the enclosing Response be signed. Net::SAML2 versions before 0.86 enforce neither, so an unsigned decrypted assertion is treated as verified.

Attack Vector

A Service Provider's encryption certificate is public because it is published in SAML metadata so that IdPs can encrypt assertions to it. An attacker retrieves the certificate, constructs a SAML assertion containing arbitrary NameID and attribute values, encrypts it to the SP's public key, wraps the ciphertext in a samlp:Response, and posts the payload to the SP's Assertion Consumer Service (ACS) URL over the network. No credentials, user interaction, or IdP compromise is required. Only callers that do not configure a key_file remain unaffected, because they do not decrypt EncryptedAssertion elements.

text
         @candidate_refs = @trusted_refs;
     }
     else {
-        # No cacert configured, or no signatures present. Best-effort
-        # anchoring at the first signature's reference URI.
-        my $ref = $xpath->findvalue(
-            '//dsig:Signature[1]/dsig:SignedInfo/dsig:Reference/@URI'
-        );
-        $ref =~ s/^#//;
-        @candidate_refs = ($ref) if length $ref;
+        croak("No trusted signature found in the assertion. Pass "
+            . "insecure_trust_embedded_cert => 1 to new_from_xml() to trust "
+            . "embedded certificates (dev/test only).")
+            unless $insecure_trust_embedded_cert;
+
+        my $ids = $xpath->findnodes('//saml:Assertion/@ID');
+        if ($ids->size == 1) {
+            (my $ref = $ids->get_node(1)->value) =~ s/^#//;
+            @candidate_refs = ($ref) if length $ref;
+        }
     }

Source: GitHub commit d9164685. The patch replaces the best-effort anchoring with a hard failure via croak unless the caller opts into insecure_trust_embedded_cert for development or test use, and only anchors when exactly one assertion ID is present.

Detection Methods for CVE-2026-18108

Indicators of Compromise

  • SAML Response messages posted to the ACS endpoint containing an EncryptedAssertion element whose decrypted contents lack a dsig:Signature child.
  • Successful authentication events for users where the corresponding IdP session log shows no matching assertion issuance.
  • Access from unusual source IPs immediately following posts to the ACS URL from unauthenticated clients.

Detection Strategies

  • Inspect application logs for SAML assertions processed by Net::SAML2 versions below 0.86 and correlate consumed NameID values against IdP-side issuance records.
  • Instrument the SP to log whether each processed assertion contained a dsig:Signature element after decryption; any assertion without one on a vulnerable build indicates exposure.
  • Scan Perl deployments and CPAN inventories for installed Net-SAML2 versions less than 0.86.

Monitoring Recommendations

  • Alert on HTTP POST requests to Assertion Consumer Service endpoints from IP addresses that never completed an IdP redirect flow.
  • Monitor for authentication anomalies such as privileged accounts logging in without matching IdP authentication events.
  • Track the Perl module manifest of production hosts and flag Net::SAML2 versions below 0.86.

How to Mitigate CVE-2026-18108

Immediate Actions Required

  • Upgrade Net::SAML2 to version 0.86 or later on every host running a Perl Service Provider.
  • Audit all deployed Perl SP applications for a configured decryption key_file; those callers are the vulnerable population.
  • Review recent authentication logs for suspicious ACS submissions and, where in doubt, invalidate active sessions and force re-authentication.

Patch Information

The fix is included in Net::SAML20.86, released on MetaCPAN. See the MetaCPAN release changes for Net-SAML2 0.86 and the upstream security commit. The patched _verify_encrypted_assertion requires a valid signature anchored to a trusted certificate, or an explicit insecure_trust_embedded_cert => 1 opt-in intended only for development.

Workarounds

  • Remove the decryption key_file from Net::SAML2 configuration if EncryptedAssertion support is not required, since callers without a key_file do not decrypt and are unaffected.
  • Require IdPs to sign the full samlp:Response and reject any response whose signature does not cover the assertion at the SP layer or upstream proxy.
  • Filter inbound SAML responses at a reverse proxy to drop messages whose decrypted assertion lacks a dsig:Signature element until the upgrade to 0.86 is complete.
bash
# Upgrade Net::SAML2 to the patched release
cpanm Net::SAML2@0.86

# Verify installed version
perl -MNet::SAML2 -e 'print "$Net::SAML2::VERSION\n"'

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.