CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



GHSA-HHJV-JQ77-CMVX
High

GHSA-HHJV-JQ77-CMVX: Android Shell Blocklist Bypass in Zeptoclaw via Argument Permutation

Alon Barad
Alon Barad
Software Engineer

Mar 5, 2026·7 min read·2 visits

PoC Available

Executive Summary (TL;DR)

A blocklist bypass in zeptoclaw's Android shell tool allows execution of banned commands like 'rm -rf' via argument splitting (e.g., 'rm -r -f').

The `zeptoclaw` Rust framework contains a security bypass vulnerability in its Android device shell interface (`device_shell`). The vulnerability allows attackers to execute dangerous commands, specifically recursive file deletions (`rm -rf`), by circumventing a naive blocklist implementation. The original security control relied on literal substring matching, which fails to account for argument permutations, alternative flag syntax, or binary aliasing (e.g., `busybox rm`). This flaw permits malicious agents or attackers with access to the framework's shell tool to perform destructive actions on connected Android devices.

Vulnerability Overview

The zeptoclaw package functions as an AI agent framework, providing various tools for interacting with external systems. One such tool, device_shell, facilitates the execution of shell commands on connected Android devices via the Android Debug Bridge (ADB). To prevent accidental or malicious data loss, the developers implemented a blocklist intended to intercept and reject dangerous commands, most notably recursive force deletion (rm -rf).

The vulnerability resides in the implementation of this blocklist. Instead of parsing the command arguments to understand the intent, the system performed a simple literal string search. It checked if the command string contained specific banned substrings such as "rm -rf" or "rm -r". This approach is fundamentally flawed when applied to command-line interfaces, where the same operation can be invoked using a multitude of syntactically different but semantically equivalent command structures.

By crafting commands that avoid the exact blocked substrings while retaining the destructive flags, an attacker can bypass the filter entirely. This allows the execution of arbitrary removal commands on the target Android file system, potentially leading to critical data loss or device bricking.

Root Cause Analysis

The root cause of this vulnerability is an Incomplete List of Disallowed Inputs (CWE-184) combined with Improper Neutralization of Argument Delimiters (CWE-88). The security logic relied on a "deny-list" approach using naive string matching, which is insufficient for complex grammars like POSIX shell commands.

In standard Unix-like shells (including Android's mksh or toybox shell), command arguments are tokenized based on whitespace. Flags can often be combined (bundled), separated, or reordered without changing the program's behavior. For example, the rm binary accepts flags in any order relative to the target path. The vulnerable code in zeptoclaw failed to model this behavior.

Technical Flaws:

  1. Literal Matching: The code searched for the continuous string "rm -rf". It did not detect rm invoked with separated flags (e.g., rm -r -f).
  2. Ignored Aliases: The check did not account for multi-call binaries common in Android environments, such as busybox rm or toybox rm, which effectively execute the same logic but change the command string signature.
  3. Path Blindness: The check did not normalize binary paths. Invoking /system/bin/rm instead of just rm would bypass a filter looking for the latter if not anchored correctly.

Code Analysis

The following analysis compares the vulnerable implementation with the patched logic introduced in commit 68916c3e4f3af107f11940b27854fc7ef517058b. The original code relied on a simple iterator over a static array of banned strings.

Vulnerable Implementation (Pre-Patch):

// src/tools/android/actions.rs
// Naive check uses .contains() on the raw command string
let blocked = [
    "rm -rf",
    "rm -r",
    // ... other patterns
];
 
for pattern in &blocked {
    // If the command is "rm -r -f /", this check fails
    // because the string "rm -rf" is not present literally.
    if lower.contains(pattern) {
        return Err(ZeptoError::Tool(format!("Blocked dangerous command...")));
    }
}

Patched Implementation (Fixed):

The fix introduces a robust parsing strategy. It tokenizes the input string and inspects the arguments semantic meaning rather than their string representation. The new logic specifically looks for the rm binary (or its aliases) and then iterates through all arguments to detect if both recursive and force flags are present in any combination.

// src/tools/android/actions.rs
 
// 1. Tokenize the input command
let tokens: Vec<&str> = command.split_whitespace().collect();
 
// 2. Identify if the binary is 'rm', '/system/bin/rm', 'busybox rm', etc.
if let Some(rm_args) = rm_invocation_args(&tokens) {
    let mut has_r = false;
    let mut has_f = false;
 
    // 3. Iterate through all arguments to find dangerous flags
    for &tok in rm_args {
        if tok == "--recursive" { has_r = true; }
        else if tok == "--force" { has_f = true; }
        // Handle combined flags like '-rf', '-fr', '-vfr', etc.
        else if tok.starts_with('-') && !tok.starts_with("--") {
            let flags = &tok[1..];
            if flags.contains('r') { has_r = true; }
            if flags.contains('f') { has_f = true; }
        }
    }
 
    // 4. Block only if both flags are present
    if has_r && has_f {
        return Err(ZeptoError::Tool("Recursive force deletion is blocked".into()));
    }
}

This approach correctly identifies rm -r -f, rm -fr, and rm --recursive --force as semantically identical dangerous commands.

Exploitation Methodology

An attacker can exploit this vulnerability by submitting specific command strings to the device_shell tool. The goal is to construct a command that instructs the underlying shell to perform a recursive deletion while ensuring the command string does not strictly match the blocked patterns.

Bypass Vectors:

  1. Flag Splitting:

    • Blocked: rm -rf /sdcard
    • Bypass: rm -r -f /sdcard
    • Mechanism: The original check looks for the substring -rf. By separating the flags with a space, the substring check fails, but the rm binary still interprets both flags.
  2. Flag Reordering:

    • Bypass: rm -f -r /sdcard
    • Mechanism: Reversing the order of separated flags bypasses checks that might look for -r followed by -f.
  3. Long Flags:

    • Bypass: rm --recursive --force /sdcard
    • Mechanism: If the blocklist only contains short flags (-rf), the verbose GNU/POSIX standard flags will bypass detection.
  4. Binary Aliasing:

    • Bypass: busybox rm -rf /sdcard
    • Mechanism: If the blocklist expects the command to start with rm, invoking it via busybox (common on Android) changes the command signature, evading detection.

Proof of Concept:

The following Rust test case, adapted from the patch, demonstrates the successful detection of previously allowed commands:

#[tokio::test]
async fn test_bypass_permutations() {
    // These commands previously executed successfully
    let payloads = [
        "rm -r -f /sdcard",
        "rm --recursive --force /sdcard",
        "/system/bin/rm -fr /data/local/tmp",
        "busybox rm -rf /sdcard"
    ];
 
    for cmd in payloads {
        // In the patched version, these now return errors
        assert!(device_shell(&adb, cmd).await.is_err());
    }
}

Impact Assessment

The impact of this vulnerability is categorized as High. It allows for the circumvention of safety guardrails designed to prevent catastrophic data loss on connected hardware.

Operational Impact:

  • Data Destruction: An attacker can wipe the entire external storage (/sdcard) or, if the device is rooted, the system partition (/system, /data). This effectively factory resets or "bricks" the device, requiring manual recovery or reflashing.
  • Integrity Loss: Malicious agents could selectively delete configuration files or application data without triggering the crude blocklist, potentially disabling security tools or monitoring agents installed on the device.

Scope: This affects any deployment of the zeptoclaw framework where untrusted agents or users can supply commands to the device_shell interface. It is particularly critical for automated testing environments or agentic workflows where the AI might hallucinate or be tricked into generating destructive commands.

Mitigation & Remediation

The vulnerability is addressed in zeptoclaw by moving from string-matching to semantic argument parsing. Users and developers using this crate must upgrade to the patched version immediately.

Remediation Steps:

  1. Upgrade: Update zeptoclaw to the version containing commit 68916c3e4f3af107f11940b27854fc7ef517058b (typically v1.1.0 or later).
  2. Verify: Ensure that the device_shell implementation includes the is_rm_recursive_force check or equivalent token-based validation.

Defense-in-Depth: While the patch fixes the specific rm -rf bypass, developers should consider additional layers of security for shell execution:

  • Principle of Least Privilege: Ensure the ADB daemon or the user context executing the commands has the minimum necessary permissions. Avoid running as root unless strictly required.
  • Sandboxing: Where possible, restrict the agent's file system access to a specific working directory rather than the entire device root.
  • Allowlisting: Instead of a blocklist (which is prone to bypasses), implement an allowlist of permitted commands and arguments if the operational scope is narrow.

Official Patches

GitHubPatch Commit

Fix Analysis (1)

Technical Appendix

CVSS Score
High/ 10

Affected Systems

zeptoclaw (Rust Crate)Android devices connected via ADB to vulnerable zeptoclaw instances

Affected Versions Detail

Product
Affected Versions
Fixed Version
zeptoclaw
qhkm
< 1.1.01.1.0
AttributeDetail
CWE IDCWE-184 (Incomplete List of Disallowed Inputs)
Attack VectorLocal / Remote (via Agent Interface)
SeverityHigh
Exploit StatusFunctional PoC
Affected Componentdevice_shell() function
Patch Commit68916c3e4f3af107f11940b27854fc7ef517058b

MITRE ATT&CK Mapping

T1202Indirect Command Execution
Execution
T1059.004Command and Scripting Interpreter: Unix Shell
Execution
CWE-184
Incomplete List of Disallowed Inputs

Vulnerability Timeline

Vulnerability identified and patched
2026-03-04
GHSA-HHJV-JQ77-CMVX published
2026-03-04

References & Sources

  • [1]GHSA-HHJV-JQ77-CMVX Advisory
  • [2]Zeptoclaw Repository