CVEReports
Reports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Reports
  • Sitemap
  • RSS Feed

Company

  • About
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Powered by Google Gemini & CVE Feed

|
•

CVE-2025-25182
CVSS 9.4|EPSS 0.33%

Trust Issues: Stroom Auth Bypass & SSRF via AWS ALB Spoofing

Alon Barad
Alon Barad
Software Engineer•January 2, 2026•6 min read
PoC Available

Executive Summary (TL;DR)

Stroom trusted the 'signer' field in AWS ALB headers without verification. Attackers can bring their own ALB signatures to log in as anyone, or inject malicious regions into the signer ARN to trigger SSRF against the AWS Metadata Service (IMDS).

A critical authentication bypass and SSRF vulnerability in GCHQ's Stroom data platform allows attackers to spoof AWS Application Load Balancer identities or reach internal AWS metadata services.

The Hook: When Spies Trust Blindly

Stroom is a data processing and analytics platform open-sourced by GCHQ. Yes, that GCHQ. When you're building software for intelligence agencies, you'd expect the authentication mechanism to be bulletproof. Stroom supports offloading authentication to an AWS Application Load Balancer (ALB). This is a common pattern: let Amazon handle the messy OIDC handshakes and MFA, and just trust the headers passed downstream.

Here is the setup: The ALB authenticates the user, signs a JSON Web Token (JWT), and stuffs it into the x-amzn-oidc-data header. The backend (Stroom) receives this header, validates the signature, and grants access. Sounds secure, right? It relies on a chain of trust. The backend must verify that the token was signed by Amazon.

But there is a nuance here that turned into a gaping hole. Stroom didn't just check if the token was signed by Amazon; it asked the token which Amazon key signed it. And then it trusted the answer. This is the cryptographic equivalent of a bouncer asking, "Is this ID fake?" and believing you when you say "No."

The Flaw: Bring Your Own Load Balancer

To verify the x-amzn-oidc-data header, the backend needs Amazon's public key. The header contains a claim called signer, which is the ARN (Amazon Resource Name) of the Load Balancer that signed the request. Stroom's logic was effectively:

  1. Read the signer ARN from the incoming header.
  2. Extract the AWS region from that ARN.
  3. Construct a URL to public-keys.auth.elb.<region>.amazonaws.com.
  4. Fetch the key and verify the signature.

Do you see the problem? The code verified that the signature was valid for some ALB, but it never checked if it was the ALB assigned to the Stroom instance.

This means an attacker can simply spin up their own AWS ALB in their own personal AWS account. They authenticate against their own ALB (which is perfectly valid), get a legitimate x-amzn-oidc-data header signed by Amazon, and send that header to the victim Stroom instance. Stroom sees a valid signature from a real AWS endpoint and rolls out the red carpet. It's an authentication bypass via trusted third-party spoofing.

But wait, it gets worse. Because the code extracted the region string directly from the signer ARN to build the URL, it also introduced a Server-Side Request Forgery (SSRF) vulnerability. If I control the string used to build the URL, I control where the server connects.

The Code: Anatomy of a Taint Failure

Let's look at the smoking gun in StandardJwtContextFactory.java. The vulnerability stems from trusting user input (the header) to determine security context.

The Vulnerable Code:

static String getAwsPublicKeyUri(final JwsParts jwsParts) {
    // Extracting the signer directly from the untrusted header
    final String signer = headerValues.get("signer"); 
    final String keyId = headerValues.get("kid");
    
    // Taint propagation: simple string split with no validation
    final String awsRegion = signer.split(":")[3]; 
    
    // Sinking the tainted data into a URL
    return "https://public-keys.auth.elb." + awsRegion + ".amazonaws.com/" + keyId;
}

If I send a signer like arn:aws:elasticloadbalancing:us-east-1:12345:loadbalancer/app/my-lb, it works normally.

The Patch (PR #4320):

The fix introduces two critical checks: an allowlist for the signer ARN and a regex for the region.

// 1. Validate the region matches a strict regex (prevention of SSRF/Path Traversal)
private static final Pattern REGION_PATTERN = Pattern.compile("^[a-z0-9-]+$");
 
// 2. Validate the signer against a configured allowlist
boolean isSignerAllowed = expectedSignerPrefixes.stream()
        .anyMatch(prefix -> signer.startsWith(prefix));
 
if (!isSignerAllowed) {
    throw new RuntimeException("Signer ... does not match any of the values in the expectedSignerPrefixes");
}

This forces the admin to explicitly define which ALBs are allowed to sign tokens, closing the loop.

The Exploit: From Zero to Cloud Compromise

A sophisticated attacker has two distinct paths to victory here. Let's walk through the kill chain.

Scenario A: The Golden Ticket (Auth Bypass)

  1. Setup: The attacker creates an AWS account and deploys an ALB configured with OIDC auth (e.g., Google or generic OIDC).
  2. Harvest: The attacker logs into their own ALB. AWS signs the request and appends x-amzn-oidc-data. The attacker captures this header.
  3. Inject: The attacker sends a request to the target Stroom instance (bypassing the target's ALB if possible, or tunneling through) with the captured header.
  4. Access: Stroom fetches the public key for the attacker's ALB (which is hosted on a valid amazonaws.com domain), verifies the signature, and logs the attacker in as a valid user.

Scenario B: The Metadata Heist (SSRF)

  1. Crafting: The attacker manually constructs a JWT header. In the signer field, instead of a region like us-east-1, they inject a payload designed to manipulate the URL.
  2. The Payload: Depending on the HTTP client library implementation, they might inject ../../ sequences or special characters to break out of the domain validation.
  3. Target: The goal is to force Stroom to make a GET request to http://169.254.169.254/latest/meta-data/iam/security-credentials/.
  4. Payday: If successful, Stroom returns or logs the IAM credentials attached to the EC2 instance. The attacker now owns the cloud infrastructure.

The Impact: Why You Should Panic

Stroom is a data pipeline tool. It ingests, transforms, and stores massive amounts of data. In a typical deployment (especially given its origin at GCHQ), this data is likely high-value intelligence or sensitive corporate logs.

Confidentiality Loss: The Auth Bypass allows an attacker to view all data within Stroom. They become an insider.

Integrity Loss: Stroom pipelines often involve data transformation logic (XSLT, scripting). An attacker with admin access could modify these pipelines to poison data or inject backdoors into downstream systems.

Cloud Compromise: The SSRF vector is the most dangerous for the hosting environment. Accessing the Instance Metadata Service (IMDS) allows the attacker to steal the temporary credentials of the role assigned to the Stroom server. If that role has S3FullAccess or EC2FullAccess, the game is over. The attacker pivots from the application layer to the infrastructure layer.

The Fix: Lockdown and Configuration

If you run Stroom, you need to patch immediately. The fixed versions are 7.2.24, 7.3-beta.22, 7.4.4, and 7.5-beta.2.

However, the patch alone isn't enough; you must configure it. The fix introduces a new configuration parameter: stroom.security.authentication.openId.expectedSignerPrefixes.

You must set this value. It takes a list of ARN prefixes.

stroom:
  security:
    authentication:
      openId:
        expectedSignerPrefixes:
          - "arn:aws:elasticloadbalancing:us-east-1:123456789012:loadbalancer/app/my-corp-alb/"

Network Defense: Ensure your Stroom backend ports (usually 8080/8443) are not public. They should only accept traffic from the Security Group of your ALB. If an attacker cannot reach the backend directly to inject the header, the attack surface is significantly reduced.

Official Patches

GCHQPull Request #4320 fixing the vulnerability

Fix Analysis (1)

Technical Appendix

CVSS Score
9.4/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:L
EPSS Probability
0.33%
Top 45% most exploited

Affected Systems

Stroom Data Platform (GCHQ)

Affected Versions Detail

ProductAffected VersionsFixed Version
Stroom
GCHQ
>= 7.2-beta.53, < 7.2.247.2.24
Stroom
GCHQ
7.3-beta.1 - < 7.3-beta.227.3-beta.22
Stroom
GCHQ
7.4-beta.1 - < 7.4.47.4.4
Stroom
GCHQ
7.5-beta.17.5-beta.2
AttributeDetail
CWECWE-290 (Auth Bypass by Spoofing)
CVSS9.4 (Critical)
Attack VectorNetwork
Exploit StatusPoC Available
ImpactAuthentication Bypass / SSRF
KEV StatusNot Listed

MITRE ATT&CK Mapping

MITRE ATT&CK Mapping

T1190Exploit Public-Facing Application
Initial Access
T1553Subvert Trust Controls
Defense Evasion
T1078Valid Accounts
Persistence
CWE-290
Authentication Bypass by Spoofing

Authentication Bypass by Spoofing

Exploit Resources

Known Exploits & Detection

Miggo SecurityOriginal research and discovery details
NucleiDetection Template Available

Vulnerability Timeline

Vulnerability Timeline

Fix Committed to GitHub
2024-06-05
Public Disclosure & CVE Published
2025-02-12

References & Sources

  • [1]GHSA Advisory
  • [2]AWS ALB OIDC Documentation

Subscribe to updates

Get the latest CVE analysis reports delivered to your inbox.

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.