Feb 21, 2026·6 min read·6 visits
A Blind SSRF vulnerability in OpenClaw's cron job webhook system allowed attackers to force the server to send HTTP POST requests to arbitrary internal destinations. Fixed in version 2026.2.19 via a custom fetch guard that implements DNS pinning and private IP blacklisting.
OpenClaw, the increasingly popular personal AI assistant, recently patched a significant Server-Side Request Forgery (SSRF) vulnerability in its cron webhook mechanism. This flaw allowed authenticated users to coerce the OpenClaw server into making arbitrary HTTP POST requests to internal network resources, local loopback interfaces, or cloud metadata services. By exploiting the lack of destination validation in the webhook dispatch logic, attackers could map internal infrastructure or interact with sensitive services protected only by network boundaries.
Automation is the lifeblood of the modern dev stack, and OpenClaw promised to be the ultimate personal AI assistant to manage it all. It schedules tasks, runs jobs, and—crucially—sends notifications when things happen. This notification system, specifically the cron webhook feature, is where our story begins.
The premise is simple and seductive: users can configure a cron job (a scheduled task) and tell OpenClaw, "Hey, when this runs, send a POST request to this URL with the results." It's a standard webhook implementation, a feature found in thousands of SaaS products. But in the world of self-hosted and personal cloud software, the distinction between "internet" and "intranet" is often just a flimsy firewall rule.
When a developer writes code to fetch a URL provided by a user, they are essentially handing the server's car keys to a stranger. Unless you explicitly tell the car not to drive off a cliff (or into your living room), that's exactly where it's going. In this case, OpenClaw was perfectly happy to drive straight into the internal network, turning a helpful assistant into a confused proxy for network reconnaissance.
The vulnerability lies in src/gateway/server-cron.ts. The code responsible for dispatching webhooks was, frankly, too trusting. It treated the webhookTarget.url as an immutable truth, a safe destination that would never betray the system. There were no checks, no balances, and definitely no SSRF guards.
Here is the logic in its raw, vulnerable form:
// src/gateway/server-cron.ts (Vulnerable)
// ... inside the job execution loop
void fetch(webhookTarget.url, {
method: "POST",
headers,
body: JSON.stringify(evt),
signal: abortController.signal,
})This is a textbook example of Server-Side Request Forgery (SSRF). The application takes a user-controlled input (webhookTarget.url) and feeds it directly into a network primitive (fetch).
Because OpenClaw is often deployed in Docker containers or cloud environments (AWS, GCP), this seemingly innocent fetch has access to things the outside world shouldn't see. We're talking about the loopback adapter (127.0.0.1), where local admin interfaces often listen without authentication. We're talking about the private VPC subnet (10.0.0.0/8), where that unpatched Elasticsearch cluster lives. And, of course, the holy grail of cloud exploits: the instance metadata service at 169.254.169.254.
The fix, landed in commit 99db4d13e5c1, is a masterclass in how to properly mitigate SSRF in a Node.js environment. The developers didn't just slap a regex on the URL string (which is easily bypassed); they implemented a DNS Pinning strategy.
The new implementation replaces the native fetch with a wrapper called fetchWithSsrFGuard. This guard does the heavily lifting before the first byte is even sent.
// src/gateway/server-cron.ts (Fixed)
const result = await fetchWithSsrFGuard({
url: webhookTarget.url,
init: {
method: "POST",
headers,
body: JSON.stringify(evt),
signal: abortController.signal,
},
});
await result.release();Under the hood, fetchWithSsrFGuard uses undici (a high-performance HTTP client for Node) to manually resolve the DNS hostname to an IP address. It then checks this IP against a rigorous blocklist of private ranges (RFC 1918, IPv6 Link-Local, etc.).
Why is this better than Regex?
Simple validation of the string http://127.0.0.1 fails against DNS rebinding attacks or alternative IP representations (like 0x7f.1). By resolving the IP first and then forcing the HTTP client to connect to that specific, validated IP, the patch eliminates the race condition known as Time-of-Check Time-of-Use (TOCTOU). Even if an attacker controls a DNS server that flips the IP from public to private between the check and the fetch, the pinned dispatcher ignores the change.
So, how does a hacker exploit this? Since the webhook sends a POST request with a JSON body, we aren't dealing with a simple GET-based SSRF. This limits us slightly—we can't easily fetch data from a REST API that expects GET. However, we can still cause chaos.
Scenario 1: Internal Service Interaction
Many internal services (like Redis via HTTP, Memcached, or poorly secured Admin panels) allow state changes via POST. If there's an internal service at http://10.0.0.5:8080/restart that restarts a critical database, we can trigger it.
Attack Steps:
http://10.0.0.1:80, http://10.0.0.2:80, etc.Connection Refused vs. a long Timeout tells us if a port is open.{
"target": "http://127.0.0.1:9200/_shutdown",
"schedule": "* * * * *"
}Scenario 2: Cloud Metadata (The Big One) While AWS IMDSv2 requires a specific PUT header (making it harder to exploit here), older setups or other cloud providers might be vulnerable. If the environment supports IMDSv1, a POST request might not retrieve the token, but in some misconfigured environments or other metadata endpoints (like Google Cloud), simply interacting with the endpoint can sometimes trigger logging or reveal information if the error messages are surfaced to the user.
More critically, if the OpenClaw instance is running a local agent that accepts commands via HTTP (common in microservices), the attacker can bypass the firewall and talk directly to it via the loopback interface.
This vulnerability is rated Medium (6.9), but don't let the score fool you. In the right (or wrong) environment, this is a critical breach point. SSRF is the gateway drug to Remote Code Execution (RCE).
If an attacker can reach an internal Redis instance, they can often overwrite crontabs or authorized_keys. If they can reach a legacy Struts application hiding on the intranet, they can exploit it without ever passing through the external WAF.
For OpenClaw users, specifically those running self-hosted instances in their home labs or corporate intranets, this means the AI you installed to help you organize your life could be used to map your entire network topology. It turns the server into a pivot point, bypassing network segmentation and allowing an attacker to poke at the soft underbelly of your infrastructure.
The remediation is straightforward: Update to OpenClaw v2026.2.19 immediately. This version includes the fetchWithSsrFGuard logic that essentially neutralizes the attack vector.
If you cannot update right away, you must rely on network-level controls:
10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, and 127.0.0.0/8.--network host mode. Isolate it in its own bridge network with strict routing rules.Remember, software patches fix the code, but network segmentation saves you when the code breaks again.
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:N/SC:N/SI:L/SA:L| Product | Affected Versions | Fixed Version |
|---|---|---|
openclaw OpenClaw | <= 2026.2.17 | 2026.2.19 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-918 (SSRF) |
| CVSS v4.0 | 6.9 (Medium) |
| Attack Vector | Network |
| Attack Complexity | Low |
| Privileges Required | None (or Low depending on auth config) |
| Exploit Status | PoC Available |
| Patch Commit | 99db4d13e5c1 |