Feb 21, 2026·6 min read·53 visits
Ray's dashboard middleware tried to block browser requests by banning POST and PUT. They forgot DELETE. Attackers can use CSRF or DNS rebinding to wipe your running AI jobs.
Ray, the popular open-source framework for scaling AI and Python applications, contained a logic flaw in its dashboard security middleware. While the developers implemented a check to block browser-based state-changing requests (CSRF protection), they explicitly blacklisted `POST` and `PUT` methods but forgot to include `DELETE`. This oversight allows an unauthenticated attacker to trick a victim's browser into deleting jobs, stopping services, and causing a Denial of Service (DoS) on the cluster.
Ray is the heavy lifter of the AI world. It's the engine underneath massive training runs, serving infrastructure, and distributed computing tasks. When you're running a cluster that costs thousands of dollars an hour, availability isn't just a metric; it's money. To manage this beast, Ray exposes a Dashboard—a cockpit for your cluster.
Now, usually, these dashboards bind to 0.0.0.0 or are accessible on a local network. The developers knew that browsers are dangerous. If a developer visits a malicious site while their local Ray dashboard is running, that site shouldn't be able to start crypto miners on the cluster. So, they built a middleware. A bouncer.
This bouncer was told to stop any browser trying to POST or PUT data. It's a classic security approach: "Block the bad stuff." But in the world of vulnerability research, we know that blacklists are destined to fail. If you block the front door and the garage door, you'd better hope you didn't leave the patio door wide open. In Ray's case, they left the DELETE door off the hinges.
The root cause here is a textbook case of Incomplete Filtering. The developers implemented a check called is_browser_request. This utility looks at headers like User-Agent and Origin to decide if a request is coming from a web browser (as opposed to a python script or CLI tool). This is actually a decent heuristic for an internal tool.
The failure happened in how they used it. They wrote logic that essentially said: "If this is a browser, AND it's trying to POST or PUT, stop it." They assumed these were the only methods that could change state or cause harm.
But Ray's API is RESTful. And what does a RESTful API use to remove resources? The DELETE verb. Because DELETE wasn't in the blacklist, the middleware looked at the request, saw it was from a browser, checked the method, saw it wasn't POST or PUT, and waved it through. The code failed to recognize that destruction is just as dangerous as modification.
Let's look at the vulnerable code in dashboard/http_server_head.py. It's almost painful in its simplicity.
# The Vulnerable Logic
if (
# Deny mutating requests from browsers.
dashboard_optional_utils.is_browser_request(request)
# OOPS: We forgot one.
and request.method in [hdrs.METH_POST, hdrs.METH_PUT]
):
return aiohttp.web.Response(
status=405, text="Method Not Allowed for browser traffic."
)If you send a DELETE request, the condition request.method in [...] evaluates to False. The code skips the 405 error and passes the request to the handler. The handler, assuming the request is valid, proceeds to execute the deletion logic.
Here is how they fixed it in version 2.54.0. They switched to a Whitelist approach (allowing only safe methods) or a complete block, depending on the component.
# The Fix: Whitelisting
allowed_methods = {"GET", "HEAD", "OPTIONS"}
if request.method not in allowed_methods:
return aiohttp.web.Response(
status=405, text="Method Not Allowed for browser traffic."
)See the difference? Instead of listing what is bad, they listed what is safe. Anything else—including DELETE, PATCH, or some weird custom HTTP verb—is now blocked by default.
How do we weaponize this? We need a victim developer who has access to the Ray dashboard (e.g., running on localhost:8265 or a corporate LAN IP). We also need that developer to visit our malicious website.
Since modern browsers enforce CORS (Cross-Origin Resource Sharing), a simple fetch with DELETE might trigger a Preflight (OPTIONS) check. However, the most robust attack vector here is DNS Rebinding.
evil.com with a short TTL (Time To Live).evil.com. The DNS initially resolves to the attacker's server, serving a malicious JavaScript payload.evil.com to point to 127.0.0.1 (or the internal IP of the Ray cluster).DELETE /api/jobs/job_12345 request to evil.com. The browser, thinking it's talking to the same origin, allows the request without strict CORS preflight checks (or bypasses them because the Origin matches). The request hits the Ray Dashboard.Because the Ray middleware sees a browser request (User-Agent is 'Mozilla...') but the method is DELETE, it allows it. The Ray API processes the command. The running AI job—perhaps a week-long training session—is instantly terminated.
The CVSS score of 5.9 (Medium) feels low until you consider the context. Ray is infrastructure. It's not just a blog; it's the brain of the operation.
An unauthenticated attacker can:
While there is no data exfiltration (Confidentiality) or code execution (RCE) directly via this CVE, the Availability impact is High. Imagine an adversary sitting in a coffee shop, rebinding DNS, and shutting down the AI models of every developer on the WiFi.
The fix is straightforward, but urgency is key.
127.0.0.1 and not exposed to the wider network (0.0.0.0).--dashboard-auth-token). Use it. This vulnerability relies on the endpoints being unauthenticated.For developers, the lesson is clear: Never use blacklists for security controls. Always define what is allowed, and block everything else by default.
CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:N/I:L/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
Ray Anyscale | <= 2.53.0 | 2.54.0 |
| Attribute | Detail |
|---|---|
| CWE | CWE-396 (Technically Incomplete Filtering) |
| CVSS | 5.9 (Medium) |
| Attack Vector | Network (CSRF/DNS Rebinding) |
| Impact | Denial of Service (DoS) |
| Exploit Status | No Known Exploitation |
| Patch | Pull Request #60526 |
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.
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.
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.
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.
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.
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.