2.4 KiB
Root Cause Analysis: Shell Actuator Security Hardening
- Executive Summary
- 1. Issue: Command Injection Vulnerability
- 2. Side-Issue: Missing Package Context
- 3. org-agent Mandate Alignment
- 4. Permanent Learnings
Executive Summary
During the formal verification of the `org-skill-shell-actuator`, a critical command injection vulnerability was identified and patched. The previous implementation relied on a naive whitelist check that could be bypassed using shell metacharacters.
1. Issue: Command Injection Vulnerability
Symptoms
Commands like `ls ; rm -rf /` were potentially executable if the first word (`ls`) was in the whitelist.
Root Cause
The `execute-shell-safely` function only checked the first space-delimited word of the command string against the `*allowed-commands*` whitelist. Since `uiop:run-program` executes string-based commands via `/bin/sh -c`, the shell would process the entire string, including injected commands following metacharacters like `;`, `&`, or `|`.
Resolution
- Metacharacter Blacklist: Introduced `*shell-metacharacters*` containing dangerous shell symbols (`; & | > < $ \` \ !`).
- Strict Validation: Updated `execute-shell-safely` to scan the entire command string for these characters before performing the whitelist check.
- Defense-in-Depth: Any command containing a metacharacter is now rejected with a "Security Violation" error, even if the primary command is whitelisted.
2. Side-Issue: Missing Package Context
Symptoms
`UNDEFINED-FUNCTION EXECUTE-SHELL-SAFELY` during unit tests.
Root Cause
`src/shell-logic.lisp` was missing an `(in-package :org-agent)` declaration, causing symbols to be defined in the default `COMMON-LISP-USER` package instead of the harness package.
Resolution
Added the `in-package` header to `shell-logic.lisp`.
3. org-agent Mandate Alignment
Invariant Check
- High-Integrity Memory: The shell actuator is now formally verified with 4 new unit tests covering whitelist enforcement and injection blocking.
- Literate Programming: Updated `org-skill-shell-actuator.org` Phase A and Build sections to reflect the hardened logic.
4. Permanent Learnings
- Whole-String Validation: Never assume that whitelisting the "head" of a command string is sufficient when passing that string to a shell.
- Subshell Avoidance: While the current fix blacklists metacharacters, future iterations should move toward passing command arguments as a Lisp list to `uiop:run-program`, bypassing the shell entirely.