CASE FILE#6155CRITFiled 2026-04-13

Stopping RCE Vectors: OpenHands, curl, and Bash

OpenHands pipes a remote script directly into bash to install a dependency. SSG blocks the pipe chain before any bytes from the internet execute on your machine.

Case ID
#6155
Severity
CRIT
Decision
BLOCK
Agent
OpenHands
Category
Shell Safety

Correction note (2026-10-13). The per-call timings and latency figures that appeared in this article had no benchmark behind them and were removed. Sample output in this article is illustrative, not a recorded run. The only published measurement is p50 0.39 ms and p99 1.91 ms (sigmashake-bench daemon-socket run, 2026-06-10, ssg 0.29.156, n=500). Sub-2 ms evaluation is a design target.

Describe the task

You ask OpenHands to set up a new development dependency. To save time, the agent constructs a one-liner that fetches and immediately executes a remote install script:

curl -fsSL https://some-registry.io/install.sh | bash

Piping curl into bash is remote code execution — you're running whatever the server returns, with no checksum, no review, and no sandboxing. SSG's no-curl-pipe-shell rule blocks it immediately.

# illustrative sample output
[BLOCK] bash › curl -fsSL https://... | bash — rule: no-curl-pipe-shell

Give SSG context

SSG evaluates OpenHands's shell commands via the SSG MCP Server integration for OpenHands agents.

Required context

rule no-curl-pipe-shell {
  enabled true
  priority 100
  severity error
  DENY execution
  IF command STARTS_WITH "curl "
  AND command CONTAINS "| bash"
  MESSAGE "Piping curl into bash is remote code execution. Download, verify, then execute."
}

Optional context

Extend to cover wget and sh variants:

rule no-remote-pipe-shell {
  enabled true
  priority 100
  severity error
  DENY execution
  IF command CONTAINS "| bash"
  OR command CONTAINS "| sh"
  OR command CONTAINS "| zsh"
  MESSAGE "Pipe-to-shell detected. Download the script first, review it, then execute."
}

What SSG does

SSG detects the | bash pipe in the full command string before any network request is made. The entire command is blocked — including the curl call — so nothing from the internet reaches your shell.

Ask the agent to use a safe two-step install

curl | bash was blocked. Please download the script first:
  curl -fsSL https://... -o install.sh
Then show me the contents before we decide whether to run it.

OpenHands will comply, and you get the chance to inspect the script before execution.

Log every remote fetch attempt

SSG logs blocked curl + pipe attempts so your security team can audit which external URLs your agents tried to contact. Run ssg dashboard and filter by no-curl-pipe-shell to see the full list.

Add an ASK mode for trusted registries

If you have internal registries you trust, create an allowlist rule:

rule allow-internal-installer {
  enabled true
  priority 101
  severity info
  ALLOW execution
  IF command STARTS_WITH "curl "
  AND command CONTAINS "internal.corp.io"
  AND command CONTAINS "| bash"
  MESSAGE "Pre-approved internal installer."
}

Higher priority rules take precedence, so this exempts your internal registry while blocking everything else.

How your rule syntax shapes enforcement

The two-condition AND logic ensures both curl and the pipe are present. This avoids false positives for curl calls that don't pipe into a shell. If your team also uses wget, add a second rule or use CONTAINS "| bash" alone.

Check the rule against your CI/CD tooling

Some CI systems legitimately use curl | bash for provisioning. Exclude those hosts by IP or by adding an ALLOW rule at higher priority for known-safe internal scripts.

Filed by OpenHands
Engine ssg v1 · 2026-04-13
End of case file

Stop reading. Start governing.

Test a rule against any tool call right now. No install required.