CVEReports
CVEReports

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

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-24048

Backstage Pass: Bypassing SSRF Filters via Open Redirects

Alon Barad
Alon Barad
Software Engineer

Feb 15, 2026·5 min read·46 visits

Executive Summary (TL;DR)

Backstage checked your ID at the door but didn't watch where you went inside. By exploiting the default redirect behavior of the `fetch` API, attackers could trick the backend into accessing restricted internal resources if they could chain a request through an allowed host with an open redirect.

A logic flaw in the Backstage `FetchUrlReader` component allowed Server-Side Request Forgery (SSRF) bypass via HTTP redirects. While the initial URL was validated against a security allowlist, the fetch implementation automatically followed redirects to unvalidated destinations, potentially exposing internal services or cloud metadata.

The Hook: The Butler Who Knew Too Much

Backstage has become the darling of platform engineering—a unified portal where developers can find everything from API docs to service catalogs. To make this magic happen, Backstage needs to be a bit of a librarian. It reaches out to GitHub, GitLab, S3 buckets, and generic URLs to fetch catalog-info.yaml files and documentation. This heavy lifting is handled by a component in @backstage/backend-defaults called the FetchUrlReader.

Here’s the catch: when you give a server the power to fetch arbitrary URLs, you are handing it a loaded gun pointed at your internal network. To prevent developers from accidentally (or maliciously) fetching http://169.254.169.254/latest/meta-data/iam/security-credentials/ and stealing your AWS keys, Backstage implements a config called backend.reading.allow. It's essentially a bouncer list. You tell it: "Only talk to github.com and internal-docs.com."

But in CVE-2026-24048, we found out that the bouncer was only checking IDs at the front door. Once the request was inside, it could sneak out the back window to anywhere it pleased.

The Flaw: A Game of 'Follow the Leader'

The vulnerability stems from a classic developer oversight: trusting the default behavior of high-level APIs. The FetchUrlReader utilized a standard fetch implementation (specifically node-fetch or similar polyfills in the Node environment). By default, when fetch receives a 3xx HTTP redirect status code (like 301 Moved Permanently or 302 Found), it automatically follows the Location header to the new URL.

In the vulnerable versions of Backstage, the code looked something like this:

  1. Check: Is user_provided_url in the allow list? Yes? Proceed.
  2. Fetch: Execute fetch(user_provided_url).
  3. Redirect: The server at user_provided_url says "Go to evil_internal_url".
  4. Follow: The fetch client says "Okay!" and requests evil_internal_url.

The security check happened only at step 1. The automatic redirect at step 4 completely bypassed the allowlist validation. It's a classic Time-of-Check to Time-of-Use (TOCTOU) logic failure, applied to network hops.

The Code: Trust vs. Verify

Let's look at the smoking gun. The fix involved ripping out the automatic redirect handling and replacing it with a manual loop that treats every hop as a potential threat.

The Vulnerable Logic (Conceptual):

// Blindly trusts the fetch client to handle redirects
const response = await fetch(url, {
  // defaults follow redirects
});

The Fix (Commit 27f9061d...): In the patched version, the developers explicitly disabled automatic redirects and wrote a loop to validate the Location header of every 3xx response.

// The new, paranoid approach
const response = await fetch(url, {
    redirect: 'manual', // STOP! Don't move.
});
 
if (response.status === 301 || response.status === 302) {
    const location = response.headers.get('location');
    const newUrl = new URL(location, url);
 
    // The critical check that was missing:
    if (!isAllowed(newUrl)) {
        throw new Error(`Redirect to ${newUrl} is not allowed`);
    }
    // If allowed, loop and fetch the new URL...
}

This change shifts the security model from "Trust the chain" to "Zero Trust for every hop."

The Exploit: Pinball Wizard

So, why is this rated Low severity (CVSS 3.5)? Because pulling this off requires the stars to align. You can't just feed Backstage http://evil.com because the initial check will block it. You need a pivot point.

To exploit this, an attacker needs two things:

  1. A host that is already whitelisted in backend.reading.allow.
  2. A way to make that allowed host redirect to a target of the attacker's choosing (an Open Redirect vulnerability).

The Attack Chain: Let's assume the victim has allowed trusted-partner.com in their Backstage config. The attacker discovers that trusted-partner.com/login?next=... has an open redirect.

  1. Trigger: The attacker registers a catalog entity pointing to https://trusted-partner.com/login?next=http://169.254.169.254/latest/meta-data/.
  2. Validation: Backstage checks the URL. trusted-partner.com is on the list. Green light.
  3. The Pivot: Backstage requests the URL. The partner server responds: HTTP/1.1 302 Found -> Location: http://169.254.169.254/....
  4. The Loot: The unpatched FetchUrlReader blindly follows the redirect to the AWS metadata service. Backstage reads the credentials and displays them (or stores them) as if they were valid catalog data.

While the prerequisites are high, the impact in a cloud environment is catastrophic—total account compromise via metadata credentials.

The Fix: Manual Override

The mitigation is straightforward: upgrade @backstage/backend-defaults to a patched version (0.12.2, 0.13.2, 0.14.1, or 0.15.0+). The patched component now manually iterates through redirects (up to 5 hops), validating the destination URL against the config at every single step.

If you cannot upgrade immediately, your defense-in-depth strategy is Egress Filtering. Your Backstage backend shouldn't be able to talk to the metadata service (169.254.169.254) or sensitive internal subnets anyway. A simple firewall rule dropping outbound traffic to RFC1918 addresses (excluding necessary services) renders this exploit inert, regardless of the application vulnerability.

Official Patches

BackstageGitHub Security Advisory and Patch Details

Fix Analysis (1)

Technical Appendix

CVSS Score
3.5/ 10
CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:C/C:L/I:N/A:N
EPSS Probability
0.03%
Top 92% most exploited

Affected Systems

Backstage BackendBackstage Catalog PluginBackstage Scaffolder Plugin

Affected Versions Detail

Product
Affected Versions
Fixed Version
@backstage/backend-defaults
Backstage
< 0.12.20.12.2
@backstage/backend-defaults
Backstage
>= 0.13.0, < 0.13.20.13.2
@backstage/backend-defaults
Backstage
>= 0.14.0, < 0.14.10.14.1
AttributeDetail
CWE IDCWE-918
Attack VectorNetwork
CVSS Score3.5 (Low)
EPSS Probability0.03%
Exploit MaturityNone (Theoretical)
PrerequisitesAllowed Host + Open Redirect

MITRE ATT&CK Mapping

T1190Exploit Public-Facing Application
Initial Access
T1005Data from Local System
Collection
CWE-918
Server-Side Request Forgery (SSRF)

Server-Side Request Forgery (SSRF)

Vulnerability Timeline

Fix committed to Backstage repository
2026-01-20
Security Advisory and CVE published
2026-01-21

References & Sources

  • [1]GHSA-q2x5-4xjx-c6p9
  • [2]CWE-918: SSRF

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.

More Reports

•37 minutes ago•CVE-2026-115921
6.2

CVE-2026-115921: Null Pointer Dereference and Integer Conversion in ONNX ScanInferenceFunction

Open Neural Network Exchange (ONNX) versions 1.4.0 prior to 1.22.0 contain a null pointer dereference (CWE-476) and a signed-to-unsigned integer conversion error (CWE-195) in the shape inference functions for the Scan operator. When processing an untrusted ONNX model, the functions ScanInferenceFunction, ScanInferenceFunction_opset8, and ScanInferenceFunction_opset9 fail to validate the presence and value of the required num_scan_inputs attribute. Omitting the attribute results in a direct null pointer dereference that crashes the host process via SIGSEGV, while supplying a negative value triggers an integer wrap-around during type narrowing that leads to an unhandled allocation failure. Notably, models containing a negative num_scan_inputs value bypass standard validation via onnx.checker.check_model().

Amit Schendel
Amit Schendel
2 views•9 min read
•about 1 hour ago•CVE-2026-91403
9.1

CVE-2026-91403: Cryptographic Trust Validation Bypass in Oracle Java SE JSSE via Compromised eMudhra Intermediate CAs

CVE-2026-91403 is a critical cryptographic trust validation flaw (CWE-327) in the Java Secure Socket Extension (JSSE) component of Oracle Java SE, Oracle GraalVM, and OpenJDK builds. Triggered by the compromise of private signing keys for eight intermediate Certificate Authorities operated by eMudhra (emSign), unpatched Java runtime environments implicitly trust fraudulent TLS and code-signing certificates issued by these compromised intermediates. Because Java disables online certificate revocation checking (OCSP/CRL) by default, an unauthenticated network attacker in an Adversary-in-the-Middle (AiTM) position can intercept, decrypt, and modify encrypted TLS communications or bypass code signature verification without triggering security exceptions.

Alon Barad
Alon Barad
4 views•12 min read
•about 2 hours ago•CVE-2026-115922
6.2

CVE-2026-115922: Denial of Service via Unchecked Expansion of Packed Sub-Byte Tensors in ONNX

Open Neural Network Exchange (ONNX) prior to version 1.22.0 contains a memory exhaustion vulnerability (CWE-789) in its Python tensor unpacking helpers and C++ model checker. Specifically, the _unpack_2bit() and _unpack_4bit() functions in onnx.numpy_helper unconditionally resize unpacked NumPy arrays to match attacker-controlled TensorProto.dims metadata without verifying that the underlying raw_data or int32_data buffers contain a corresponding number of packed bits. Furthermore, onnx.checker.check_tensor() previously bypassed length verification for sub-byte data types. Processing an untrusted ONNX model with packed sub-byte tensors (UINT2, INT2, UINT4, INT4, or FLOAT4E2M1) allows an unauthenticated attacker to trigger disproportionate memory allocations from minimal payloads, resulting in an out-of-memory (OOM) crash and denial of service.

Alon Barad
Alon Barad
6 views•10 min read
•about 3 hours ago•CVE-2026-115920
6.2

CVE-2026-115920: Out-of-Bounds Read in ONNX ConvTranspose Shape Inference

An out-of-bounds read vulnerability (CWE-125) exists in the Open Neural Network Exchange (ONNX) library across versions 1.2.1 prior to 1.22.0. The flaw occurs within the shape inference routines for the ConvTranspose operator when processing a model with a weight tensor rank less than three and an omitted kernel_shape attribute. Unchecked indexing into an empty vector triggers a memory segmentation fault, resulting in a Denial of Service (DoS) against applications inspecting or loading untrusted ONNX models.

Amit Schendel
Amit Schendel
3 views•10 min read
•about 4 hours ago•CVE-2026-115910
6.8

CVE-2026-115910: OpenID Connect Session-Binding Bypass and Account Takeover in Python Social Auth

A session-binding vulnerability in Python Social Auth (social-core) versions prior to 6.2.0 allows an attacker to perform authorization code injection against the OpenID Connect authentication backend. By storing generated OIDC nonces in a global database table without binding them to the initiating browser session, the library accepts any valid, unexpired nonce returned in an ID token regardless of which session originated the authentication transaction. When combined with the default disablement of Proof Key for Code Exchange (PKCE), an attacker who intercepts an unused authorization code can inject it into their own authentication flow to achieve full account takeover.

Amit Schendel
Amit Schendel
6 views•13 min read
•about 4 hours ago•CVE-2026-111497
9.8

CVE-2026-111497: Out-of-Bounds Heap Write and Remote Code Execution in Google Brotli Decoder (Node2Shell)

CVE-2026-111497, tracked in threat intelligence under the aliases Node2Shell, Broccoli2Shell, and HTTP2Shell, is a critical out-of-bounds heap write and denial-of-service vulnerability in the reference Google Brotli decompression library (c/dec/decode.c). The flaw originates from an unchecked return value and error-code conflation in DecodeBlockTypeAndLength() when processing malformed streams with single-block-type declarations (max_block_type <= 1). On the fast decoding path, the ignored error return causes the 32-bit unsigned block_length counter to underflow from 0 to UINT32_MAX (0xFFFFFFFF), corrupting internal decoder tables and enabling arbitrary heap memory overwrites via memmove16(). On the streaming path, the error return is misinterpreted as an incomplete bit-stream, trapping the worker process in an infinite 100% CPU loop. Because Google Brotli is embedded across major runtimes and infrastructure components—including Node.js, Envoy Proxy, Microsoft .NET, Istio, and Python—the vulnerability exposes a broad attack surface via standard HTTP Content-Encoding: br request and response bodies.

Amit Schendel
Amit Schendel
9 views•12 min read