Automated Threat Modeling

Brief Summary: Pallets Click CVE-2026-7246 Command Injection via click.edit() Unsanitized Filenames

A brief summary of CVE-2026-7246, a high-severity command injection vulnerability in the click.edit() function of the Pallets Click library. A crafted filename can make it execute arbitrary OS commands.

CVE Analysis

6 min read

ZeroPath CVE Analysis
ZeroPath CVE Analysis

2026-04-30

Brief Summary: Pallets Click CVE-2026-7246 Command Injection via click.edit() Unsanitized Filenames
Experimental AI-Generated Content

This CVE analysis is an experimental publication that is completely AI-generated. The content may contain errors or inaccuracies and is subject to change as more information becomes available. We are continuously refining our process.

If you have feedback, questions, or notice any errors, please reach out to us.

[email protected]

Introduction

A command injection vulnerability in one of Python's most popular CLI libraries turned every application using click.edit() into a potential shell execution vector. Pallets Click has over 17,400 GitHub stars and is deeply integrated across the Python ecosystem. Countless command line tools, developer utilities, and automation scripts are built on it, so CVE-2026-7246 has broad reach.

Click is the composable command line interface toolkit maintained by the Pallets Project, the open-source organization behind Flask. Developers use it to build CLI applications of every size, from small scripts to production tooling. A vulnerability in a core function like click.edit() can therefore affect a significant number of downstream projects and environments.

Technical information

Root cause

The flaw is in the edit_files() function in Click. The vulnerable code path wraps a user-supplied filename in double quotes and passes the resulting string directly to subprocess.Popen() with the shell=True parameter enabled. The quotes are the only protection. Click does not escape double quotes or any other shell metacharacters inside the filename, which is a classic CWE-77 (Command Injection) condition.

When an application constructs a command such as:

<editor> "user_supplied_filename"

the code assumes the double quotes will keep the filename together as a single argument. Because nothing inside the filename is escaped, an attacker can craft a value that breaks out of the quotes entirely.

Attack flow

An attacker exploiting this vulnerability would follow these steps:

  1. Identify an application or tool that passes externally influenced filenames to click.edit(). This could be a CLI tool that accepts a filename argument, a web application that triggers an editor session, or a developer tool that opens files from untrusted sources.

  2. Craft a malicious filename with shell metacharacters that escape the double quote wrapping. For example, a filename like:

legitimate"; <injected_command>; echo "
  1. When the application calls click.edit() with this filename, the edit_files() function builds a shell command string. The command passed to subprocess.Popen(shell=True) becomes something like:
editor "legitimate"; <injected_command>; echo ""
  1. The shell reads this as three separate statements: the editor command on the truncated filename, the injected command, which runs with the privileges of the running process, and a harmless echo statement.

  2. The injected command executes on the host system under the unprivileged account running the application.

The fix in version 8.3.3

The patch in version 8.3.3 changes how Click constructs these commands in two places:

ComponentPrevious Vulnerable BehaviorUpdated Secure Behavior
edit_filesUsed shell=True with quoted filenamesUses shlex.split to create an argv list and removes shell=True
pagerRelied on shell tokenizationUses shlex.split to split pager commands into argv lists

Click now uses shlex.split to tokenize the editor and pager command strings into proper argv lists for subprocess.Popen, and it no longer passes shell=True. Filenames are treated strictly as data arguments and never as executable shell code. This is the correct, well-established pattern for safe subprocess invocation in Python.

CVSS and severity context

The vulnerability has a CVSS v3.1 base score of 7.3 (7.2 in some sources), which is high severity. The score reflects a local attack vector, high complexity, and required user interaction. The attack vector is local rather than network-based, but the realistic attack scenarios (supply chain, developer tooling, CLI applications that process external input) still make this a meaningful risk in practice.

Affected systems and versions

Version RangeStatus
All versions of Pallets Click prior to 8.3.3 (including 8.3.2 and below)Vulnerable
Version 8.3.3 and laterFixed

Any application, tool, or library that depends on Click and passes externally influenced filenames to click.edit() is potentially exposed. That covers projects that depend on Click directly and projects where another package pulls Click in as a transitive dependency.

Vendor security history

The Pallets Project handled this vulnerability in a coordinated, responsible way. It coordinated disclosure with the CERT Coordination Center and shipped the fix in release 8.3.3 on April 22, 2026, ahead of the public advisory on April 30, 2026. That gave downstream consumers a window to patch before full details were published.

References

Detect & fix
what others miss

Works with
  • GitHub
  • GitLab
  • Bitbucket
  • Azure DevOps Services
  • Gerrit
  • CVS
  • Jira
  • Linear
  • Slack
  • Security Compass
Explore integrations
Security magnifying glass visualization