Canonicalization · Attribution · Resolution Engine —
Pre-Execution Command Verification for Shell-Executing LLM Agents
LLM agents now run your shell. CARE checks every command before it executes: deterministic, shell-aware evidence decides the common case in a fraction of a millisecond — and only the genuinely ambiguous 4% ever wake an LLM judge.
$ rm -rf /var/log/* ✗ DENY score 0.765 · L2+L3+L4 · MITRE T1485 · 0.3 ms $ cat /etc/os-release ✓ ALLOW read-context on system path · 0.2 ms $ bash -c 'trap "nohup sh …/echo-art.sh" EXIT' ⚠ WARN score 0.18 → LLM judge → DENY persistence hook $ x=rm; y=-rf; eval "$x$IFS$y$IFS/tmp/*" ✗ DENY canonicalized first — obfuscation unwrapped
TL;DR
On the leakage-controlled main split (549 commands, 12 baselines), CARE occupies the region no prior guard reaches: high F1, sub-1% false positives, and millisecond latency — with a full evidence trace for every decision.
WHY
Coding agents like Claude Code and Codex don't just write text — they run commands. One unsafe dispatch can delete files, leak secrets, or plant persistence. CVE-2025-66032 showed Claude Code's command validation bypassed with a simple $IFS rewrite. Yet existing guards force a bad trade: regex-style rules are fast but blind (29–73% F1); always-on LLM judges are smart but slow, costly, and erratic (17–460 ms, up to 46% FPR).
KEY IDEA
A bounded, non-executing normalizer unwraps shell wrappers, resolves $IFS/variable splitting, decodes base64/printf tricks — turning an obfuscated command into a stable verification target. The exact bypass class behind CVE-2025-66032 dies here, before any analysis runs.
Five deterministic views — AST structure, command semantics, read/write-aware path sensitivity, and 139 provenance-tagged rules (92 MITRE ATT&CK · 31 GTFOBins · 16 curated) — aggregate into ALLOW / WARN / DENY. Every decision ships an auditable trace: which layer fired, which rule, which catalog it came from.
High-confidence ALLOW/DENY never touch a model. Skip predicates keep catalog-attested and sensitive-path denies fully static; only the residual WARN band — 23 of 549 commands — goes to a safety-biased LLM judge. Judge errors fail closed to DENY.
RESULTS
| Guard (main split, 549 cmds) | F1 % ↑ | DR % ↑ | FPR % ↓ | Latency ↓ |
|---|---|---|---|---|
| Best static baseline (OpenClaw4Layer) | 72.62 | 57.27 | 0.30 | 0.02 ms |
| Best LLM judge (LLMJudge, Qwen3-30B) | 73.09 | 67.27 | 11.25 | 45.9 ms |
| Best guard model (Granite Guardian 2B) | 65.58 | 82.27 | 45.90 | 17.3 ms |
| CARE (w/o Resolution) — static only | 84.99 | 75.91 | 1.82 | 0.34 ms |
| CARE — full pipeline | 85.64 | 75.91 | 0.91 | 2.32 ms |
Significant over PromptOnly, LLMJudge, ClawGuardSim, OpenClaw4Layer and Llama Guard 3 under McNemar's test (all p < 10⁻⁵).
NL2SH-ALFA benign tasks: 57.00% resolved with CARE vs 57.33% with no guard at all — a single deny in 300 tasks. Over 5-turn agent loops: identical 65.33% resolve rate, 4 cumulative denies (Granite Guardian: 529).
600 attack commands generated by an LLM agent, executed in a Docker sandbox: realised harm drops from 74.8% (unguarded) to 37.3% with CARE's static profile — the most conservative non-LLM operating point, at a 38.7% deny rate instead of Granite's 71.8% blanket blocking.
Full CARE when benign recovery matters: the judge rescues dual-use commands like rsync/scp, halving FPR. Static-only when conservatism matters: 84.99% F1 at 0.34 ms, zero LLM dependency, strongest harm reduction on LLM-paraphrased attacks.
CITATION
@inproceedings{liu2026care,
author = {Liu, Yu and Zhang, Wenxiao and Yang, Zhiwei and Zhang, Zhongyi and
Feng, Hanqi and Wang, Xinyu and Qiu, Peng and Liu, Yanbing and
Poczos, Barnabas and Hong, Jin B.},
title = {{CARE}: Pre-Execution Command Verification for Shell-Executing {LLM} Agents},
booktitle = {IEEE International Symposium on Software Reliability Engineering (ISSRE)},
year = {2026}
}