{"answers":{"affected":"2 open source packages ship an affected version, including zeptoclaw.","exploited":"There is no known exploitation of GHSA-5wp8-q9mx-8jx8 in the wild and no public exploit code.","fix":"Upgrade zeptoclaw to 0.6.2 or later.","what":"GHSA-5wp8-q9mx-8jx8 is a command injection vulnerability in zeptoclaw, published on 5 Mar 2026. Any signed-in user can exploit it over the network, with no action from the victim."},"fix_prompt":"Check this codebase for GHSA-5wp8-q9mx-8jx8 and fix it if it is affected.\n\nWhat it is: GHSA-5wp8-q9mx-8jx8 is a command injection vulnerability in zeptoclaw, published on 5 Mar 2026. Any signed-in user can exploit it over the network, with no action from the victim.\nExploitation: There is no known exploitation of GHSA-5wp8-q9mx-8jx8 in the wild and no public exploit code.\n\nAffected packages and fixed versions:\n- zeptoclaw (crates.io): affected all versions; fixed in 0.6.2\n- zeptoclaw (crates.io): affected all versions; fixed in 0.6.2\n\nTask:\n1. Search the dependency manifests and lockfiles (for example package.json, package-lock.json, requirements.txt, poetry.lock, uv.lock, pom.xml, build.gradle, go.mod, Cargo.lock, Gemfile.lock) and any Dockerfiles for the affected packages, including transitive dependencies.\n2. If an affected version is in use, upgrade it to the fixed version for its release line with the project's package manager, so the lockfile is regenerated. Prefer the smallest upgrade that fixes it.\n3. If there is no fix, or the upgrade would break the build, do not guess: explain the risk and the safest workaround instead.\n4. Run the tests and summarise what changed and why.\n5. If nothing in the project is affected, say so and change nothing.\n\nReference: https://insights.sbomify.com/GHSA-5wp8-q9mx-8jx8/ (Markdown: https://insights.sbomify.com/GHSA-5wp8-q9mx-8jx8/index.md)","id":"GHSA-5wp8-q9mx-8jx8","markdown":"https://insights.sbomify.com/GHSA-5wp8-q9mx-8jx8/index.md","name":"GHSA-5wp8-q9mx-8jx8","record":{"aliases":[],"analysis":{"component_type":"library","fix_type":"patch","impacts":["code_execution"],"network_reachable":"yes","non_default_config":false,"product_category":"Rust shell security library","requires_auth":"low_privilege","summary":"Attackers can bypass shell command restrictions in zeptoclaw via injection techniques, leading to arbitrary code execution.","user_interaction":"not_required","vuln_class":"command_injection"},"analysis_generated_by":"qwen3.8-flash-next","assigner":null,"cpe":[],"cvss":{"score":null,"severity":null,"source":null,"vector":null,"version":null},"cwes":[],"description":"### Summary\n[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:\n\n- to bypass the `allowlist`, command injection is enough, such as `;`, `$()` etc.\n- to bypass the `REGEX_BLOCKED_PATTERNS`, argument injection is enough, such as the `python3 -P -c \"...\"`\n- to bypass the `LITERAL_BLOCKED_PATTERNS`, file name wildcards can do the work, such as `cat /etc/pass[w]d`\n\n### Details\nIn 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. \n```rust\n        // Allowlist check (runs after blocklist)\n        if self.allowlist_mode != ShellAllowlistMode::Off \u0026\u0026 !self.allowlist.is_empty() {\n            let first_token = command\n                .split_whitespace()\n                .next()\n                .unwrap_or(\"\")\n                .to_lowercase();\n            // Strip path prefix (e.g. /usr/bin/git -\u003e git)\n            let executable = first_token.rsplit('/').next().unwrap_or(\u0026first_token);\n            if !self.allowlist.iter().any(|a| a == executable) {\n                match self.allowlist_mode {\n                    ShellAllowlistMode::Strict =\u003e {\n                        return Err(ZeptoError::SecurityViolation(format!(\n                            \"Command '{}' not in allowlist\",\n                            executable\n                        )));\n                    }\n                    ShellAllowlistMode::Warn =\u003e {\n                        tracing::warn!(\n                            command = %command,\n                            executable = %executable,\n                            \"Command not in allowlist\"\n                        );\n                    }\n                    ShellAllowlistMode::Off =\u003e {} // unreachable\n                }\n```\n `!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.\n\nAs 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:\n```rust\nconst REGEX_BLOCKED_PATTERNS: \u0026[\u0026str] = \u0026[\n    // Piped shell execution (curl/wget to sh/bash)\n    r\"curl\\s+.*\\|\\s*(sh|bash|zsh)\",\n    r\"wget\\s+.*\\|\\s*(sh|bash|zsh)\",\n    r\"\\|\\s*(sh|bash|zsh)\\s*$\",\n    // Reverse shells\n    r\"bash\\s+-i\\s+\u003e\u0026\\s*/dev/tcp\",\n    r\"nc\\s+.*-e\\s+(sh|bash|/bin)\",\n    r\"/dev/tcp/\",\n    r\"/dev/udp/\",\n    // Destructive root operations (various flag orderings)\n    r\"rm\\s+(-[rf]{1,2}\\s+)*(-[rf]{1,2}\\s+)*/\\s*($|;|\\||\u0026)\",\n    r\"rm\\s+(-[rf]{1,2}\\s+)*(-[rf]{1,2}\\s+)*/\\*\\s*($|;|\\||\u0026)\",\n    // Format/overwrite disk\n    r\"mkfs(\\.[a-z0-9]+)?\\s\",\n    r\"dd\\s+.*if=/dev/(zero|random|urandom).*of=/dev/[sh]d\",\n    r\"\u003e\\s*/dev/[sh]d[a-z]\",\n    // System-wide permission changes\n    r\"chmod\\s+(-R\\s+)?777\\s+/\\s*$\",\n    r\"chmod\\s+(-R\\s+)?777\\s+/[a-z]\",\n    // Fork bombs\n    r\":\\(\\)\\s*\\{\\s*:\\|:\u0026\\s*\\}\\s*;:\",\n    r\"fork\\s*\\(\\s*\\)\",\n    // Encoded/indirect execution (common blocklist bypasses)\n    r\"base64\\s+(-d|--decode)\",\n    r\"python[23]?\\s+-c\\s+\",\n    r\"perl\\s+-e\\s+\",\n    r\"ruby\\s+-e\\s+\",\n    r\"node\\s+-e\\s+\",\n    r\"\\beval\\s+\",\n    r\"xargs\\s+.*sh\\b\",\n    r\"xargs\\s+.*bash\\b\",\n    // Environment variable exfiltration\n    r\"\\benv\\b.*\u003e\\s*/\",\n    r\"\\bprintenv\\b.*\u003e\\s*/\",\n];\n\n/// Literal substring patterns (credentials, sensitive paths)\nconst LITERAL_BLOCKED_PATTERNS: \u0026[\u0026str] = \u0026[\n    \"/etc/shadow\",\n    \"/etc/passwd\",\n    \"~/.ssh/\",\n    \".ssh/id_rsa\",\n    \".ssh/id_ed25519\",\n    \".ssh/id_ecdsa\",\n    \".ssh/id_dsa\",\n    \".ssh/authorized_keys\",\n    \".aws/credentials\",\n    \".kube/config\",\n    // ZeptoClaw's own config (contains API keys and channel tokens)\n    \".zeptoclaw/config.json\",\n    \".zeptoclaw/config.yaml\",\n];\n```\n\n### PoC\n```rust\n    #[test]\n    fn test_allowlist_bypass() {\n        let config =\n            ShellSecurityConfig::new().with_allowlist(vec![\"git\"], ShellAllowlistMode::Strict);\n        assert!(config.validate_command(\"/usr/bin/git status; python -P -c 'import os; os.system(\\\"rm -rf /\\\")'; cat /etc/pass[w]d\").is_ok());\n    }\n```\n\n### Impact\nUnauthorized command execution.\n\n### Credit\n[@zpbrent](https://github.com/zpbrent)","ecosystems":["crates.io"],"exploits":{"exploitdb":null,"first_seen":null,"github_poc":null,"max_poc_stars":null,"metasploit":null,"nuclei":null,"refs":[],"tier":null},"has_fix":true,"headline":"zeptoclaw has Shell allowlist-blocklist bypass via command/argument injection and file name wildcards","id":"GHSA-5wp8-q9mx-8jx8","indexable":true,"kev":null,"kind":"advisory","links":{"ecosystem":"crates.io","product":null,"products":[],"type":"command_injection","year":"2026"},"n_packages":2,"n_references":null,"packages":[{"ecosystem":"crates.io","fixed":["0.6.2"],"introduced":["0"],"last_affected":[],"package":"zeptoclaw","purl":null,"source":"GHSA-5wp8-q9mx-8jx8"},{"ecosystem":"crates.io","fixed":["0.6.2"],"introduced":["0"],"last_affected":[],"package":"zeptoclaw","purl":"pkg:cargo/zeptoclaw","source":"GHSA-5wp8-q9mx-8jx8"}],"products":null,"published":"2026-03-05","related":[],"sources":[{"class":"attribution","licence":"CC BY 4.0","name":"GitHub Advisory Database","prefix":"GHSA"}],"ssvc":{"automatable":null,"exploitation":null,"technical_impact":null},"state":null,"updated":null,"vendors":null},"summary":"Attackers can bypass shell command restrictions in zeptoclaw via injection techniques, leading to arbitrary code execution.","url":"https://insights.sbomify.com/GHSA-5wp8-q9mx-8jx8/"}