Mar 12, 2026·7 min read·43 visits
Black versions prior to 26.3.1 fail to properly hash short user-controlled configurations, leading to a path traversal vulnerability. An attacker can use crafted parameters to write arbitrary cache files outside the designated cache directory.
A path traversal vulnerability (CWE-22) in the cache mechanism of the Black Python code formatter allows an attacker to write files to arbitrary locations on the filesystem. The vulnerability stems from improper sanitization of the `--python-cell-magics` parameter when constructing cache keys.
CVE-2026-32274 is a high-severity path traversal vulnerability (CWE-22) affecting Black, a widely adopted Python code formatting utility. The vulnerability specifically targets the caching subsystem responsible for storing formatting metadata and pickled Python objects. By design, Black utilizes this cache to optimize repeated executions across large codebases, significantly reducing formatting overhead.
The attack surface involves the --python-cell-magics command-line argument and its corresponding configuration directive in a project's pyproject.toml file. This parameter dictates how Black formats Python code embedded within specific Jupyter notebook cell magics. When an attacker provides a maliciously crafted string containing directory traversal sequences, the application incorporates the string directly into the filesystem path used for cache storage.
The companion daemon, blackd, significantly amplifies the exposure of this vulnerability. Because blackd runs as a background process listening for formatting requests, it parses incoming HTTP parameters directly into Black's core formatting logic. Prior to version 26.3.1, the daemon lacked Cross-Origin Resource Sharing (CORS) protections, exposing local developer environments to browser-based exploitation.
Successful exploitation results in an arbitrary file write condition operating under the privileges of the user executing Black or the blackd service. An attacker can write cache data to any directory accessible to the process, bypassing the intended ~/.cache/black/ restriction.
The root cause resides in the get_cache_key method located within the src/black/mode.py module. This function generates a unique filename for cache entries based on the specific configuration options provided during execution. The implementation concatenates various feature flags and magic configurations to form a base identifier string.
The vulnerability emerges from a conditional optimization intended to reduce CPU overhead. The application applies a SHA-256 hash to the configuration string only if the string's length exceeds _MAX_CACHE_KEY_PART_LENGTH, defined as 32 characters. If the concatenated string is 32 characters or shorter, the application bypasses the hashing routine entirely.
When the hashing routine is bypassed, the raw string acts directly as a component of the cache filename. The application lacks any subsequent sanitization or validation of the characters within this string. Consequently, special path characters such as slashes (/) and dot-dot sequences (../) are preserved in the final path calculation.
An attacker exploiting this logic supplies a payload that is both malicious and concise, ensuring the total length remains under the 32-character threshold. The application processes the short traversal string, bypasses the sanitization hash, and forces the underlying filesystem API to resolve the relative path outside the target cache directory.
The vulnerable implementation in src/black/mode.py concatenates the features and python_cell_magics variables. The resulting string is assigned to the features_and_magics variable. The subsequent conditional block checks the length of this string against _MAX_CACHE_KEY_PART_LENGTH.
# src/black/mode.py (Vulnerable Implementation)
def get_cache_key(self) -> str:
features_and_magics = (
",".join(sorted(self.features))
+ "@"
+ ",".join(sorted(self.python_cell_magics))
)
# The flaw exists in the following conditional check:
if len(features_and_magics) > _MAX_CACHE_KEY_PART_LENGTH:
features_and_magics = sha256(features_and_magics.encode()).hexdigest()[
:_MAX_CACHE_KEY_PART_LENGTH
]
# ... function continues to build the final pathThe fix, introduced in commit 4937fe6cf241139ddbfc16b0bdbb5b422798909d, removes the vulnerable length evaluation. The maintainers refactored the function to apply the SHA-256 hash unconditionally. By forcing every configuration string through a cryptographic hash function, the application guarantees that the filename component consists strictly of safe, hexadecimal characters.
# src/black/mode.py (Patched Implementation)
def get_cache_key(self) -> str:
features_and_magics = (
",".join(sorted(self.features))
+ "@"
+ ",".join(sorted(self.python_cell_magics))
)
# The patch applies the hash unconditionally, ensuring path safety.
features_and_magics = sha256(features_and_magics.encode()).hexdigest()[
:_MAX_CACHE_KEY_PART_LENGTH
]
# ... function continues to build the final pathThis remediation completely eliminates the path traversal vector at the source. Any malicious input supplied via the CLI or HTTP headers is irreversibly transformed into a benign 32-character hex string before interacting with the filesystem.
Exploitation occurs through one of three primary vectors: malicious repository configurations, direct command-line arguments, or daemon HTTP requests. An attacker controlling a codebase can embed the payload in the pyproject.toml file. When a victim executes Black against the compromised repository, the path traversal triggers automatically.
The command-line attack vector requires the attacker to append the payload directly to the execution string. A command such as black --python-cell-magics "../../../tmp/pwned" script.py generates a cache key containing the traversal characters. The application constructs the absolute path, escaping ~/.cache/black/ and writing the cache file to /tmp/pwned.
The blackd daemon vector presents a severe remote exploitation scenario for local developers. The daemon listens on TCP port 45484 by default. An attacker can construct a malicious website that issues an asynchronous POST request to http://localhost:45484 containing an X-Python-Cell-Magics header populated with the traversal payload.
The primary security impact is arbitrary file write, quantified by a CVSS 4.0 score of 8.7 and a High Integrity metric. An attacker dictates the exact destination path of the file write operation. The operation executes with the permissions of the user running the Black application, which commonly corresponds to an unprivileged developer account or a Continuous Integration service user.
The vulnerability is constrained by the application's control over the file content. The written file contains binary cache data or pickled Python objects generated by Black, rather than raw attacker-controlled text. This constraint complicates the immediate execution of arbitrary code, as the attacker cannot write pure scripts or typical shellcodes directly to the filesystem.
Despite the content constraint, the ability to write to arbitrary locations introduces significant secondary risks. An attacker can target critical system or application configurations, overwriting .bashrc, .ssh/authorized_keys, or legitimate Python modules in the execution path. Overwriting execution-critical files with corrupted or mismatched data results in localized denial of service or indirect code execution upon subsequent parsing.
The lack of prerequisite authentication or user interaction for the blackd attack vector exacerbates the severity. A victim merely navigating to an attacker-controlled webpage while running blackd locally is sufficient to trigger the arbitrary file write.
The definitive remediation strategy requires upgrading the psf/black package to version 26.3.1. This release contains the unconditional hashing mechanism that prevents the path traversal entirely. Security engineers must enforce this version requirement across all developer environments, automated testing pipelines, and container images.
The patch for version 26.3.1 implements substantial architectural hardening for the blackd daemon. The maintainers disabled cross-origin requests by default, neutralizing the browser-based attack vector. Administrators configuring blackd for cross-origin usage must now explicitly define trusted sources using the newly introduced --cors-allow-origin flag.
Further systemic protections added to blackd include strict request body size limits (--max-body-size) and concurrent execution semaphores. These mechanisms prevent CPU exhaustion and denial of service conditions that could be triggered by malformed formatting requests.
Organizations unable to deploy the patch immediately must implement interim mitigations. Administrators should restrict the use of the blackd daemon entirely on developer workstations. Security scanning pipelines should be configured to audit pyproject.toml files for suspicious python-cell-magics definitions containing path traversal sequences.
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N| Product | Affected Versions | Fixed Version |
|---|---|---|
psf/black Python Software Foundation | < 26.3.1 | 26.3.1 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-22 |
| Attack Vector | Network / Local Configuration |
| CVSS v4.0 | 8.7 |
| Impact | Arbitrary File Write |
| Exploit Status | Proof of Concept (PoC) |
| Fixed Version | 26.3.1 |
The software uses external input to construct a pathname that is intended to identify a file or directory that is located underneath a restricted parent directory, but the software does not properly neutralize special elements within the pathname that can cause the pathname to resolve to a location that is outside of the restricted directory.
CVE-2024-29203 identifies a cross-site scripting (XSS) vulnerability in the content ingestion and parsing mechanics of TinyMCE rich text editor. Due to a failure to enforce sandbox attributes on dynamic iframe elements and safely handle legacy embed objects, unauthenticated attackers can inject malicious elements that execute scripts within the context of the parent application session.
A technical breakdown of the OS command injection vulnerability in the shell-quote NPM package (CVE-2026-9277 / GHSA-w7jw-789q-3m8p). The bug resides in the character-by-character backslash-escaping logic applied to the .op field of object-tokens within the quote() function, which fails to match and escape line terminators due to a regex matching oversight in JavaScript. This allows unauthenticated remote attackers to execute arbitrary shell commands if they can control inputs processed by this library.
A high-severity memory corruption vulnerability exists in the V8 JavaScript engine of Google Chrome before versions 149.0.7827.102/103. The flaw arises from an incorrect bounds-check elimination during JIT compilation by the TurboFan optimizer, allowing remote attackers to achieve out-of-bounds read and write access inside the sandboxed renderer process.
An improper authentication vulnerability (CWE-287) exists in the legacy, deprecated Internet Key Exchange version 1 (IKEv1) key exchange protocol implementation in Check Point Security Gateways. The vulnerability is caused by a logic flow weakness during the certificate validation process for Remote Access VPN and Mobile Access (SSL VPN) connections. An unauthenticated remote attacker can exploit this weakness to bypass user authentication entirely, establishing a fully functional Remote Access VPN connection without a valid password.
GeoNode versions prior to 4.4.5 and 5.0.2 are vulnerable to Server-Side Request Forgery (SSRF) in the service registration endpoint. Authenticated attackers with low privileges can exploit insufficient input validation in the Web Map Service (WMS) registration module to force the application server to make outbound network queries to loopback addresses, private RFC1918 subnets, link-local scopes, and cloud metadata endpoints. This technical report details the mechanics of the vulnerability, the underlying architectural flaw, and how to effectively remediate and mitigate the associated security risks.
CVE-2022-0492 is a high-severity missing authorization vulnerability in the Linux kernel's Control Groups (cgroups) v1 implementation. The flaw resides within the cgroup_release_agent_write function in kernel/cgroup/cgroup-v1.c, where the kernel fails to validate if the process writing to the release_agent file possesses administrative capabilities in the initial user namespace. This allows a local attacker inside a container with root privileges (UID 0) to abuse user namespaces, mount a cgroups v1 directory, modify the release_agent parameter, and execute arbitrary commands on the host system as host root, effectively achieving a complete container escape.