Skip to content

CVE-2026-28391 — OpenClaw versions prior to 2026.2.2 fail to properly validate Windows cmd.exe…

Key facts

CVE-2026-28391 is a Critical (9.8) vulnerability: OpenClaw versions prior to 2026.2.2 fail to properly validate Windows cmd.exe…. This entry ships ready-to-deploy detection and prevention rules (Snort, YARA, Nginx, Apache, Sigma) plus a detection-only PoC and a Docker test lab.

CVE CVE-2026-28391
Severity Critical (9.8)
Detection / prevention Snort, YARA, Nginx, Apache, Sigma
PoC poc.py
Source 2026/CVE-2026-28391/

Details

CVE-2026-28391 is a Critical (9.8) vulnerability: OpenClaw versions prior to 2026.2.2 fail to properly validate Windows cmd.exe…. This entry ships a detection-only proof-of-concept (PoC), a Docker test lab, and ready-to-deploy detection and prevention rules (Snort, YARA, Nginx, Apache) — see Detection and prevention below. Source: NVD record.

English | 한국어

Description

OpenClaw versions prior to 2026.2.2 fail to properly validate Windows cmd.exe metacharacters in allowlist-gated exec requests (non-default configuration), allowing attackers to bypass command approval restrictions. Remote attackers can craft command strings with shell metacharacters like & or %...% to execute unapproved commands beyond the allowlisted operations.

Vulnerability Details

Property Value
CVE ID CVE-2026-28391
Type RCE
CVSS Score 9.8

Proof of Concept

Download

# Download PoC script
curl -O https://raw.githubusercontent.com/fankh/vulnerability-poc/main/2026/CVE-2026-28391/poc.py

Usage

# Run PoC against target
python3 poc.py --target <TARGET_URL>

# With authentication
python3 poc.py --target <TARGET_URL> --username <USER> --password <PASS>

⚠️ Warning: This PoC is for authorized security testing only. It uses detection-only techniques and does not exploit or damage target systems.

Test Lab

This repository includes a Docker-based test environment with both vulnerable and patched applications.

Quick Start

# Clone and navigate to CVE directory
cd CVE-2026-28391

# Start both applications
docker-compose up -d

# Run tests
./run-tests.sh    # Linux/Mac
./run-tests.ps1   # Windows PowerShell

Application Endpoints

Application URL Status
Vulnerable App http://localhost:8080 Shows vulnerability
Patched App http://localhost:8081 Demonstrates fix

Directory Structure

├── README.md           # English documentation
├── README_KO.md        # Korean documentation
├── poc.py              # PoC detection script
├── docker-compose.yml  # Container orchestration
├── run-tests.sh        # Linux/Mac test runner
├── run-tests.ps1       # Windows test runner
├── vulnerable-app/     # Vulnerable version
│   ├── app.py
│   ├── Dockerfile
│   └── requirements.txt
└── patched-app/        # Fixed version
    ├── app.py
    ├── Dockerfile
    └── requirements.txt

References

  • https://github.com/openclaw/openclaw/commit/a7f4a53ce80c98ba1452eb90802d447fca9bf3d6
  • https://github.com/openclaw/openclaw/security/advisories/GHSA-qj77-c3c8-9c3q
  • https://www.vulncheck.com/advisories/openclaw-command-injection-via-cmdexe-parsing-bypass-in-allowlist-enforcement

Generated by PoC Generator on 2026-04-10T16:24:27.618530534

Detection and prevention

Ready-to-deploy defensive rules for CVE-2026-28391, for authorized testing and blue-team detection engineering:

References: NVD — CVE-2026-28391 · full write-up on the searchable site

Detection & prevention rules

alert tcp any any -> any any (msg:"CVE-2026-28391 OpenClaw RCE attempt - ampersand command chaining"; flow:established,to_server; content:"exec"; nocase; content:"&"; distance:0; classtype:attempted-admin; sid:1000000; rev:1; priority:1;)

alert tcp any any -> any any (msg:"CVE-2026-28391 OpenClaw RCE attempt - pipe command chaining"; flow:established,to_server; content:"exec"; nocase; content:"|"; distance:0; classtype:attempted-admin; sid:1000001; rev:1; priority:1;)

alert tcp any any -> any any (msg:"CVE-2026-28391 OpenClaw RCE attempt - semicolon command separator"; flow:established,to_server; content:"exec"; nocase; content:";"; distance:0; classtype:attempted-admin; sid:1000002; rev:1; priority:1;)

alert tcp any any -> any any (msg:"CVE-2026-28391 OpenClaw RCE attempt - Windows variable expansion"; flow:established,to_server; content:"exec"; nocase; pcre:"/exec.*%[^%]+%/i"; classtype:attempted-admin; sid:1000003; rev:1; priority:1;)

alert tcp any any -> any any (msg:"CVE-2026-28391 OpenClaw RCE attempt - cmd.exe execution"; flow:established,to_server; content:"exec"; nocase; content:"cmd.exe"; nocase; distance:0; classtype:attempted-admin; sid:1000004; rev:1; priority:1;)

alert tcp any any -> any any (msg:"CVE-2026-28391 OpenClaw RCE attempt - command substitution"; flow:established,to_server; content:"exec"; nocase; content:"$("; distance:0; classtype:attempted-admin; sid:1000005; rev:1; priority:1;)

alert tcp any any -> any any (msg:"CVE-2026-28391 OpenClaw RCE attempt - backtick command substitution"; flow:established,to_server; content:"exec"; nocase; content:"`"; distance:0; classtype:attempted-admin; sid:1000006; rev:1; priority:1;)

alert tcp any any -> any any (msg:"CVE-2026-28391 OpenClaw RCE attempt - double ampersand chaining"; flow:established,to_server; content:"exec"; nocase; content:"&&"; distance:0; classtype:attempted-admin; sid:1000007; rev:1; priority:1;)

:material-file-download: prevention/snort.rules

rule CVE_2026_28391_OpenClaw_Command_Injection_Patterns {
    meta:
        cve = "CVE-2026-28391"
        author = "Security Engineer"
        description = "Detects OpenClaw command injection exploitation attempts via Windows cmd.exe metacharacters"
        date = "2024-12-19"
        severity = "high"

    strings:
        $openclaw_binary = "openclaw" nocase
        $openclaw_service = "OpenClaw" nocase

        $metachar_ampersand = /[a-zA-Z0-9_\-\.\/\\]+\s*&\s*[a-zA-Z0-9_\-\.\/\\%]+/
        $metachar_pipe = /[a-zA-Z0-9_\-\.\/\\]+\s*\|\s*[a-zA-Z0-9_\-\.\/\\%]+/
        $metachar_semicolon = /[a-zA-Z0-9_\-\.\/\\]+\s*;\s*[a-zA-Z0-9_\-\.\/\\%]+/
        $metachar_double_pipe = /[a-zA-Z0-9_\-\.\/\\]+\s*\|\|\s*[a-zA-Z0-9_\-\.\/\\%]+/
        $metachar_double_ampersand = /[a-zA-Z0-9_\-\.\/\\]+\s*&&\s*[a-zA-Z0-9_\-\.\/\\%]+/

        $env_var_expansion = /%[a-zA-Z0-9_]+%/
        $cmd_redirection = />\s*[a-zA-Z0-9_\-\.\/\\%]+/
        $cmd_append = />>\s*[a-zA-Z0-9_\-\.\/\\%]+/

        $malicious_commands = /(?:cmd\.exe|powershell\.exe|net\.exe|sc\.exe|wmic\.exe|reg\.exe)/i
        $system_paths = /(?:system32|syswow64|windows\\temp)/i

    condition:
        (any of ($openclaw_*)) and 
        (2 of ($metachar_*) or 
         ($env_var_expansion and any of ($metachar_*)) or
         (any of ($malicious_commands) and any of ($metachar_*)) or
         (any of ($cmd_*) and any of ($metachar_*)))
}

rule CVE_2026_28391_OpenClaw_Exploit_Memory_Patterns {
    meta:
        cve = "CVE-2026-28391"
        author = "Security Engineer"
        description = "Detects OpenClaw RCE exploitation in memory via command injection patterns"
        date = "2024-12-19"
        severity = "high"

    strings:
        $exec_request = "exec" nocase
        $allowlist = "allowlist" nocase
        $whitelist = "whitelist" nocase

        $bypass_pattern1 = { 26 [1-10] 63 6D 64 }  // & ... cmd
        $bypass_pattern2 = { 7C [1-10] 63 6D 64 }  // | ... cmd
        $bypass_pattern3 = { 25 [1-20] 25 }         // %...%
        $bypass_pattern4 = { 3B [1-10] 63 6D 64 }  // ; ... cmd

        $http_request = /(?:POST|GET|PUT)\s+\/[^\s]*exec/i
        $json_payload = /"(?:command|cmd|exec)"\s*:\s*"[^"]*[&|;%][^"]*"/
        $xml_payload = /<(?:command|cmd|exec)>[^<]*[&|;%][^<]*<\/(?:command|cmd|exec)>/

    condition:
        (any of ($exec_request, $allowlist, $whitelist)) and
        (any of ($bypass_pattern*) or 
         $http_request or 
         $json_payload or 
         $xml_payload)
}

rule CVE_2026_28391_OpenClaw_Network_Exploit {
    meta:
        cve = "CVE-2026-28391"
        author = "Security Engineer"
        description = "Detects network-based OpenClaw command injection attempts"
        date = "2024-12-19"
        severity = "high"

    strings:
        $user_agent = "OpenClaw" nocase
        $api_endpoint = /\/api\/v[0-9]+\/exec/i

        $injection_payload1 = /approved_cmd\s*&\s*net\s+user/i
        $injection_payload2 = /dir\s*\|\s*findstr\s+password/i
        $injection_payload3 = /ping\s*;\s*whoami/i
        $injection_payload4 = /echo\s*&&\s*systeminfo/i

        $encoded_metachar1 = "%26"  // &
        $encoded_metachar2 = "%7C"  // |
        $encoded_metachar3 = "%3B"  // ;
        $encoded_metachar4 = "%25"  // %

        $powershell_bypass = /powershell\s+-[eE][nN][cC][oO][dD][eE][dD]/

    condition:
        ($user_agent or $api_endpoint) and
        (any of ($injection_payload*) or 
         2 of ($encoded_metachar*) or
         $powershell_bypass)
}

:material-file-download: prevention/yara.yar

# CVE-2026-28391 Protection: OpenClaw RCE via cmd.exe metacharacters
# Block requests containing Windows command metacharacters in exec endpoints

# Block requests to OpenClaw exec endpoints with dangerous metacharacters
location ~* ^/api/v[0-9]+/exec {
    # Block Windows cmd.exe metacharacters that can bypass allowlist restrictions
    if ($request_body ~* "(&|%[^%]*%|\|\||&&|;|\||\^|<|>|\$|\`)" ) {
        return 403;
    }

    if ($args ~* "(&|%[^%]*%|\|\||&&|;|\||\^|<|>|\$|\`)" ) {
        return 403;
    }

    # Block encoded versions of dangerous characters
    if ($request_body ~* "(%26|%7C|%3B|%3C|%3E|%24|%60)" ) {
        return 403;
    }

    if ($args ~* "(%26|%7C|%3B|%3C|%3E|%24|%60)" ) {
        return 403;
    }

    # Block double-encoded metacharacters
    if ($request_body ~* "(%25(26|7C|3B|3C|3E|24|60))" ) {
        return 403;
    }

    proxy_pass http://backend;
}

# Block requests to legacy exec paths
location ~* ^/(exec|command|run) {
    if ($request_body ~* "(&|%[^%]*%|\|\||&&|;|\||\^|<|>|\$|\`)" ) {
        return 403;
    }

    if ($args ~* "(&|%[^%]*%|\|\||&&|;|\||\^|<|>|\$|\`)" ) {
        return 403;
    }

    proxy_pass http://backend;
}

# Block dangerous command patterns in any POST/PUT request body
location / {
    # Block common Windows command injection patterns
    if ($request_body ~* "(cmd\.exe|powershell|net\s+user|whoami|dir\s+/|type\s+)" ) {
        return 403;
    }

    # Block command chaining attempts
    if ($request_body ~* "(\s*&\s*|;\s*|\|\|\s*|&&\s*)" ) {
        return 403;
    }

    # Block environment variable expansion attempts
    if ($request_body ~* "%[A-Za-z_][A-Za-z0-9_]*%" ) {
        return 403;
    }

    # Add security headers
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;

    proxy_pass http://backend;
}

:material-file-download: prevention/nginx.conf

# ModSecurity rules for CVE-2026-28391 - OpenClaw RCE via cmd.exe metacharacter bypass
# Protects against command injection through Windows shell metacharacters

# Rule 1000000: Block Windows cmd.exe metacharacters in request parameters
SecRule ARGS "@detectSQLi" \
    "id:1000000,\
    phase:2,\
    block,\
    severity:CRITICAL,\
    msg:'CVE-2026-28391: Windows cmd.exe metacharacter detected in parameters',\
    logdata:'Matched Data: %{MATCHED_VAR} found within %{MATCHED_VAR_NAME}',\
    t:none,\
    t:urlDecodeUni,\
    t:htmlEntityDecode,\
    ctl:auditLogParts=+E,\
    tag:'attack-injection',\
    tag:'CVE-2026-28391'"

# Rule 1000001: Block ampersand command chaining
SecRule ARGS "@rx (?i)[\s]*&[\s]*[a-z]" \
    "id:1000001,\
    phase:2,\
    block,\
    severity:CRITICAL,\
    msg:'CVE-2026-28391: Command chaining with ampersand detected',\
    logdata:'Matched Data: %{MATCHED_VAR} found within %{MATCHED_VAR_NAME}',\
    t:none,\
    t:urlDecodeUni,\
    t:htmlEntityDecode,\
    ctl:auditLogParts=+E,\
    tag:'attack-injection',\
    tag:'CVE-2026-28391'"

# Rule 1000002: Block Windows environment variable expansion patterns
SecRule ARGS "@rx (?i)%[a-z_][a-z0-9_]*%" \
    "id:1000002,\
    phase:2,\
    block,\
    severity:CRITICAL,\
    msg:'CVE-2026-28391: Windows environment variable expansion detected',\
    logdata:'Matched Data: %{MATCHED_VAR} found within %{MATCHED_VAR_NAME}',\
    t:none,\
    t:urlDecodeUni,\
    t:htmlEntityDecode,\
    ctl:auditLogParts=+E,\
    tag:'attack-injection',\
    tag:'CVE-2026-28391'"

# Rule 1000003: Block pipe operators for command chaining
SecRule ARGS "@rx (?i)[\s]*\|[\s]*[a-z]" \
    "id:1000003,\
    phase:2,\
    block,\
    severity:CRITICAL,\
    msg:'CVE-2026-28391: Pipe command chaining detected',\
    logdata:'Matched Data: %{MATCHED_VAR} found within %{MATCHED_VAR_NAME}',\
    t:none,\
    t:urlDecodeUni,\
    t:htmlEntityDecode,\
    ctl:auditLogParts=+E,\
    tag:'attack-injection',\
    tag:'CVE-2026-28391'"

# Rule 1000004: Block semicolon command separators
SecRule ARGS "@rx (?i)[\s]*;[\s]*[a-z]" \
    "id:1000004,\
    phase:2,\
    block,\
    severity:CRITICAL,\
    msg:'CVE-2026-28391: Semicolon command separator detected',\
    logdata:'Matched Data: %{MATCHED_VAR} found within %{MATCHED_VAR_NAME}',\
    t:none,\
    t:urlDecodeUni,\
    t:htmlEntityDecode,\
    ctl:auditLogParts=+E,\
    tag:'attack-injection',\
    tag:'CVE-2026-28391'"

# Rule 1000005: Block double ampersand conditional execution
SecRule ARGS "@rx (?i)[\s]*&&[\s]*[a-z]" \
    "id:1000005,\
    phase:2,\
    block,\
    severity:CRITICAL,\
    msg:'CVE-2026-28391: Conditional command execution with && detected',\
    logdata:'Matched Data: %{MATCHED_VAR} found within %{MATCHED_VAR_NAME}',\
    t:none,\
    t:urlDecodeUni,\
    t:htmlEntityDecode,\
    ctl:auditLogParts=+E,\
    tag:'attack-injection',\
    tag:'CVE-2026-28391'"

# Rule 1000006: Block double pipe conditional execution
SecRule ARGS "@rx (?i)[\s]*\|\|[\s]*[a-z]" \
    "id:1000006,\
    phase:2,\
    block,\
    severity:CRITICAL,\
    msg:'CVE-2026-28391: Conditional command execution with || detected',\
    logdata:'Matched Data: %{MATCHED_VAR} found within %{MATCHED_VAR_NAME}',\
    t:none,\
    t:urlDecodeUni,\
    t:htmlEntityDecode,\
    ctl:auditLogParts=+E,\
    tag:'attack-injection',\
    tag:'CVE-2026-28391'"

# Rule 1000007: Block command substitution with backticks
SecRule ARGS "@rx (?i)`[^`]+`" \
    "id:1000007,\
    phase:2,\
    block,\
    severity:CRITICAL,\
    msg:'CVE-2026-28391: Command substitution with backticks detected',\
    logdata:'Matched Data: %{MATCHED_VAR} found within %{MATCHED_VAR_NAME}',\
    t:none,\
    t:urlDecodeUni,\
    t:htmlEntityDecode,\
    ctl:auditLogParts=+E,\
    tag:'attack-injection',\
    tag:'CVE-2026-28391'"

# Rule 1000008: Block redirection operators
SecRule ARGS "@rx (?i)[\s]*[<>]+[\s]*[a-z0-9]" \
    "id:1000008,\
    phase:2,\
    block,\
    severity:HIGH,\
    msg:'CVE-2026-28391: Redirection operator detected',\
    logdata:'Matched Data: %{MATCHED_VAR} found within %{MATCHED_VAR_NAME}',\
    t:none,\
    t:urlDecodeUni,\
    t:htmlEntityDecode,\
    ctl:auditLogParts=+E,\
    tag:'attack-injection',\
    tag:'CVE-2026-28391'"

# Rule 1000009: Block requests to OpenClaw exec endpoints with metacharacters in POST body
SecRule REQUEST_BODY "@rx (?i)[\s]*[&|;%`<>]+[\s]*[a-z]" \
    "id:1000009,\
    phase:2,\
    block,\
    severity:CRITICAL,\
    msg:'CVE-2026-28391: Shell metacharacters in request body',\
    logdata:'Matched Data: %{MATCHED_VAR} found within %{MATCHED_VAR_NAME}',\
    t:none,\
    t:urlDecodeUni,\
    t:htmlEntityDecode,\
    ctl:auditLogParts=+E,\
    tag:'attack-injection',\
    tag:'CVE-2026-28391'"

# Rule 1000010: Block Windows-specific command execution patterns in URI
SecRule REQUEST_URI "@rx (?i)/exec|/command|/run" \
    "id:1000010,\
    phase:1,\
    pass,\
    severity:INFO,\
    msg:'CVE-2026-28391: Potential exec endpoint accessed',\
    logdata:'URI: %{REQUEST_URI}',\
    t:none,\
    t:urlDecodeUni,\
    ctl:auditLogParts=+E,\
    tag:'attack-injection',\
    tag:'CVE-2026-28391',\
    chain"
SecRule ARGS "@rx (?i)[\s]*[&|;%`<>]+[\s]*" \
    "t:none,\
    t:urlDecodeUni,\
    t:htmlEntityDecode"

:material-file-download: prevention/httpd.conf

Frequently asked questions

What is CVE-2026-28391?

CVE-2026-28391 is a Critical (9.8) vulnerability: OpenClaw versions prior to 2026.2.2 fail to properly validate Windows cmd.exe…. This entry ships ready-to-deploy detection and prevention rules (Snort, YARA, Nginx, Apache, Sigma) plus a detection-only PoC and a Docker test lab.

How do I detect CVE-2026-28391?

Deploy the Snort and YARA detection rule included with this entry (see Detection & prevention rules below), then validate it against the detection-only PoC in the Docker test lab.

How do I block or mitigate CVE-2026-28391?

Apply the Nginx and Apache mitigation config included with this entry, and upgrade to a fixed version per the vendor advisory (see the NVD record for affected versions).


For authorized security testing and research only. See the full source and NVD record.