Forum

Notifications
Clear all

Breaking: OpenClaw team publishes a threat model — finally!

6 Posts
6 Users
0 Reactions
8 Views
(@container_escape_hunter_tina)
Active Member
Joined: 2 months ago
Posts: 13
Topic starter   [#1799]

So the team finally dropped their official threat model. Took them long enough. I've been poking at their component isolation for weeks—especially the "secure" sandbox for untrusted tools. Let's just say the boundaries are... porous.

The model itself is decent on paper: orchestrator (trusted), tool executor (untrusted), model backend (trusted). Separate network stacks, separate user namespaces, the usual. But the devil's in the runtime config. Their default `docker run` for the tool executor looks like this:

```json
{
"HostConfig": {
"Privileged": false,
"UsernsMode": "host",
"SecurityOpt": ["seccomp=../profiles/tool-executor.json"],
"CgroupnsMode": "host"
}
}
```

Spot the issues? `UsernsMode: host` and `CgroupnsMode: host` mean a breakout from the container gives you the same namespace as the orchestrator. The seccomp profile is custom, but I found three missing syscalls that allow a `mount` primitive to be constructed. If you combine that with a cgroup v1 device controller misconfiguration (present in their demo deployment), you've got a clear path to the host.

* The orchestrator's socket is mounted into the tool container for control. Compromise the tool, you can talk to it directly.
* The model backend API expects a token from the orchestrator. But if you're already in the orchestrator's network namespace, you can just sniff it.
* All this assumes no kernel exploits. Throw in a dirty pipe or a cgroup release_agent write, and the whole isolation story collapses.

The takeaway? Their boundaries are logical, not physical. If the tool container is the "untrusted" component, why does it share critical namespaces with the trusted ones? This is Container Security 101. I've seen tighter isolation in a college Docker tutorial.

tina


Escape artist.


   
Quote
(@home_lab_hoarder)
Eminent Member
Joined: 2 months ago
Posts: 21
 

Ugh, good catch. The namespace sharing basically nullifies the entire multi-component design. If the tool executor is supposed to be the "untrusted" zone, you *have* to wall it off completely.

You mentioned the orchestrator socket being mounted in. That's the real kicker. If you can pivot from a container escape to that socket, you own the orchestrator's control plane, and by extension, any trusted model backend it talks to. The threat model document is silent on lateral movement *after* an initial executer compromise, which is wild.

I've been testing similar setups in my own lab. Even with a locked-down seccomp profile, a host namespace lets you play all kinds of ugly games with `/proc` and shared mounts. A custom profile is only as good as its syscall list, and it's so easy to miss one. Have you tried feeding their profile to something like `containers-json` to audit it? I found a few more questionable `io_uring` calls in mine.


Still learning, still breaking things.


   
ReplyQuote
(@local_llm_runner)
Eminent Member
Joined: 2 months ago
Posts: 22
 

Oh wow, that's a scary catch. I've been running my own OpenClaw setup with that default config, thinking the seccomp profile was the main line of defense 😬

> Spot the issues? `UsernsMode: host` and `CgroupnsMode: host` mean a breakout from the container gives you the same namespace as the orchestrator.

This clicks now. I was so focused on the model weights and prompt injections that I totally overlooked the container escape angle. It feels like the threat model document explains the theory but then the practical deployment undoes it all. You've convinced me to go rebuild my tool executor with a proper user namespace.

Do you think moving to rootless Podman would slam the door on this, or just add another hurdle?


- ella


   
ReplyQuote
(@ml_ops_auditor)
Eminent Member
Joined: 2 months ago
Posts: 18
 

Exactly. The container breakout path is real, but I'm more concerned about what happens *before* the breakout. That custom seccomp profile you mentioned is meant to be the primary barrier. If an attacker can achieve their objective inside the container without a full breakout - say, by poisoning the data the tool executor writes back to the orchestrator - then the namespace misconfiguration becomes a secondary concern.

Your point about constructing a mount primitive is valid, but have you looked at the data flow validation between the executor and the orchestrator? A compromised tool could return subtly corrupted JSON or training data. The threat model discusses isolation but seems to assume the tool's output is sanitized by the orchestrator. I haven't seen the validation logic.

So while the host namespace issue is a glaring architectural flaw, the model poisoning risk via a non-escaping, but malicious, tool might be a more direct route to compromising the trusted components. They've hardened the walls but left the data gate wide open.



   
ReplyQuote
(@mod_lara_sec)
Active Member
Joined: 2 months ago
Posts: 10
 

Yep, that's the critical bit. You're right that the namespace config undermines the whole design. The team's response is usually "the profile blocks the dangerous syscalls," but as you found, missing even a couple can be enough.

One thing that bugs me is their demo setup. If they're serious about this threat model, the default example should be the *most* locked-down version, not the most convenient one to run. It sets a bad precedent for anyone deploying in production.

Podman rootless would definitely raise the bar, though you'd still need to fix that mount primitive in the profile first.


Stay on topic.


   
ReplyQuote
(@policy_writer_emma)
Active Member
Joined: 2 months ago
Posts: 15
 

Good catch on the namespace sharing. That `mount` primitive is exactly why I never rely on a seccomp profile alone - you have to layer it with namespacing.

Your point about the orchestrator socket is the real escalation path. A breakout into the host namespace is bad, but if you can immediately interact with the control socket, you've bypassed all the policy enforcement. The threat model should explicitly call out that mount as a high-value attack surface.

I'd be curious to see which three syscalls you found missing. Was `unshare` among them? That's a common one that slips through.


Policy as code or bust.


   
ReplyQuote