Loading...
Skip to main content

GHSA-5wp8-q9mx-8jx8 — Vulnerability in zeptoclaw — Advisory Details

CRITICAL

zeptoclaw has Shell allowlist-blocklist bypass via command/argument injection and file name wildcards

Published March 5, 2026Updated March 5, 2026Source: osv

Summary

### Summary [zeptoclaw](https://github.com/qhkm/zeptoclaw) implements a allowlist combined with a blocklist to prevent malicious shell commands in [src/security/shell.rs](https://github.com/qhkm/zeptoclaw/blob/v0.5.8/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 the `python3 -P -c "..."` - to bypass the `LITERAL_BLOCKED_PATTERNS`, file name wildcards can do the work, such as `cat /etc/pass[w]d` ### Details In code [src/security/shell.rs#L218-L243](https://github.com/qhkm/zeptoclaw/blob/fe2ef07cfec5bb46b42cdd65f52b9230c03e9270/src/security/shell.rs#L218-L243), one can see the allowlist only checks the first token and thus makes command injection possible. ```rust // 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](https://github.com/qhkm/zeptoclaw/blob/fe2ef07cfec5bb46b42cdd65f52b9230c03e9270/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: ```rust 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 ```rust #[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()); } ``` ### Impact Unauthorized command execution. ### Credit [@zpbrent](https://github.com/zpbrent)

Advisory Timeline

  • First published March 5, 2026 (221 days ago).
  • Last revised March 5, 2026 — 0 days after initial publication.

Remediation

Upgrade to the fixed version using your package manager.

Cargo
Update zeptoclaw to 0.6.2 or later
cargo update -p zeptoclaw --precise 0.6.2

After upgrading, run your dependency scanner again to confirm the vulnerability is resolved.

Affected Packages (1)

Affects 1 ecosystem: crates.io (1).

PackageEcosystemAffectedFixed In
zeptoclaw
crates.io
All versions0.6.2

Vulnerability Classification

Common Weakness Enumeration (CWE) identifiers for this vulnerability type.

CVSS Score Breakdown

What the CVSS (Common Vulnerability Scoring System) 10.0 score means for each attack dimension.

Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Changed
Confidentiality
High
Integrity
High
Availability
High

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H

Frequently Asked Questions

What is GHSA-5wp8-q9mx-8jx8?
zeptoclaw has Shell allowlist-blocklist bypass via command/argument injection and file name wildcards This vulnerability has been assigned a severity rating of CRITICAL (CVSS score: 10.0/10).
How do I check if my project is affected by GHSA-5wp8-q9mx-8jx8?
GHSA-5wp8-q9mx-8jx8 affects zeptoclaw. Use GeekWala's free vulnerability scanner to check your dependencies against GHSA-5wp8-q9mx-8jx8 and 200,000+ other known vulnerabilities.

Severity & Exploitability

CVSS Score
10.0

Exploitation is straightforward and causes maximum impact. Patch immediately.

Related CVEs

  • RUSTSEC-2026-0327
    CRITICAL

    Wasmtime component async-lifted callback result count is unvalidated, causing a native stack buffer overflow

  • CVE-2026-75856
    CRITICAL

    CodeWhale: SSRF bypass - TOCTOU on DNS failure for DNS pinning

  • CVE-2026-32232
    HIGH

    ZeptoClaw: Path boundary checks bypass via symlink, TOCTOU, and hardlink

  • CVE-2026-32231
    HIGH

    ZeptoClaw: Generic webhook channel trusts caller-supplied identity fields; allowlist is checked against untrusted payload data

Check if you're affected

Scan your dependencies to see if this vulnerability affects your projects.

Scan Your Dependencies