Mar 20, 2026·6 min read·48 visits
A path traversal vulnerability (CWE-22) in pydicom's FileSet parsing allows local arbitrary file operations via maliciously crafted DICOMDIR files. Update to version 3.0.2 or 2.4.5 to mitigate.
CVE-2026-32711 is a high-severity path traversal vulnerability in the pydicom Python library, affecting versions 2.0.0-rc.1 through 3.0.1. The flaw resides in the FileSet implementation, where insufficient validation of the ReferencedFileID attribute allows malicious DICOMDIR files to perform out-of-bounds file reads, copies, or deletions.
The pydicom Python library provides parsing and manipulation capabilities for DICOM files, a standard format in medical imaging. A core component of this standard is the DICOMDIR file, which acts as an index for a set of related DICOM files known as a File-set. The pydicom.fileset.FileSet class implements the logic for loading, modifying, and exporting these collections.
CVE-2026-32711 identifies a CWE-22 Path Traversal vulnerability within the FileSet parsing logic. The vulnerability specifically affects the handling of the ReferencedFileID attribute found in directory records. Insufficient sanitization of this attribute allows a malicious DICOMDIR file to reference arbitrary files outside the intended File-set root directory.
Exploitation requires a victim to process a weaponized DICOMDIR file using a vulnerable version of pydicom. Depending on the subsequent operations performed on the FileSet object, an attacker can achieve arbitrary file read, copy, or deletion on the victim's host filesystem. The impact is highly dependent on the privileges of the executing Python process.
The vulnerability originates from an unsafe interaction between user-supplied paths and Python's pathlib.Path module. When joining paths using the / operator, pathlib completely discards the left-hand operand if the right-hand operand evaluates to an absolute path. This behavior allows an attacker to bypass intended directory restrictions simply by supplying a path beginning with a root descriptor, such as / on Linux or C:\ on Windows.
In vulnerable versions of pydicom, the FileSet.load() method processes the ReferencedFileID to locate referenced files. The library invokes .resolve(strict=True) on the constructed path to verify that the target file exists on the filesystem. However, it fails to implement a containment check to verify that the resolved, absolute path remains a child of the designated File-set root directory.
Once the unvalidated path is loaded into the FileSet object, it becomes subject to standard operations. Methods such as FileSet.copy(), FileSet.write(), and FileSet.remove() utilize the stored path without further validation. If a victim script invokes FileSet.copy(), the library will read the file from the attacker-controlled absolute path and write it to the specified output destination, completing the data exfiltration chain.
The remediation for CVE-2026-32711 introduces explicit path validation to enforce directory containment. The patch, implemented in commit 6414f01a053dff925578799f5a7208d2ae585e82, deprecates the vulnerable _file_id property. It replaces it with a dedicated file_id_path method that requires the root path as an argument for contextual validation.
def file_id_path(self, root_path: Path) -> Path | None:
# Attribute extraction logic omitted for brevity
path = Path(...)
if path is not None:
if path.anchor or not (
(root_path / path).resolve().is_relative_to(root_path)
):
raise PermissionError(
f"ReferencedFileID ('{path}') must be inside the DICOMDIR root path"
)
return pathThe patched logic implements two critical security checks. First, it evaluates path.anchor to explicitly reject any absolute paths, directly mitigating the pathlib joining behavior. Second, it resolves the combined path and uses is_relative_to(root_path) to ensure that relative traversals utilizing ../ sequences cannot escape the designated root directory. This comprehensive approach effectively eliminates the path traversal vector.
Exploiting CVE-2026-32711 requires the construction of a malicious DICOMDIR file. An attacker modifies a valid directory record, altering the ReferencedFileID attribute to point to a target file on the victim's system. The payload can be an absolute path, such as /etc/passwd, or a relative traversal path depending on the attacker's knowledge of the execution environment.
The attacker must then deliver the modified DICOMDIR file to the victim, typically bundled within a larger medical imaging dataset. The attack relies on social engineering or standard data ingestion workflows to prompt the victim to process the dataset. No specialized network access or authentication is required by the attacker, as the execution occurs entirely locally on the victim's machine.
from pydicom.fileset import FileSet
# Victim loads the malicious DICOMDIR
fs = FileSet("malicious_dicom_dir/DICOMDIR")
# The library reads from the traversal path and writes to the output
fs.copy("output_folder/")> [!NOTE]
> The specific operation invoked by the victim dictates the final impact. While copy() results in arbitrary file read, a combination of remove() and write(use_existing=True) can lead to arbitrary file deletion or modification outside the intended directory structure.
The NVD assigned a CVSS v3.1 base score of 7.8 to CVE-2026-32711, represented by the vector CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H. The Attack Vector is classified as Local because the exploit is delivered via a file rather than an active network connection. User Interaction is required, as the victim must actively invoke the pydicom parsing logic on the malicious file.
The impact metrics for Confidentiality, Integrity, and Availability are all rated High. An attacker can achieve complete compromise of files accessible to the Python process. Reading sensitive configuration files degrades confidentiality, while overwriting or deleting critical system files impacts integrity and availability.
The Exploit Prediction Scoring System (EPSS) assigns a probability score of 0.00016, placing the vulnerability in the 3.29th percentile. This low score indicates a minimal historical likelihood of exploitation in the wild for this specific class of vulnerability in a specialized Python library. The vulnerability is not currently listed in the CISA Known Exploited Vulnerabilities (KEV) catalog.
The maintainers of pydicom addressed the vulnerability in two separate release branches. Users operating on the modern 3.x branch must upgrade to version 3.0.2 to receive the security patch. For environments constrained to the 2.x branch, the fix was backported and released in version 2.4.5.
Organizations utilizing pydicom to process untrusted or externally sourced DICOM datasets should apply the updates immediately. In scenarios where immediate patching is prohibited by change management policies, defensive operations must be implemented. Processing untrusted datasets within tightly restricted sandbox environments or unprivileged containers reduces the impact of a successful path traversal.
System administrators should enforce the principle of least privilege on processes invoking pydicom. Ensuring the Python execution environment only possesses read and write access to dedicated processing directories prevents the traversal from reaching sensitive operating system files. Regular auditing of dependencies via software composition analysis tools will identify vulnerable instances of the library across the infrastructure.
CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
pydicom pydicom | >= 2.0.0-rc.1, <= 3.0.1 | 3.0.2 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-22 |
| Attack Vector | Local |
| CVSS Score | 7.8 |
| EPSS Score | 0.00016 |
| Impact | High (Confidentiality, Integrity, Availability) |
| Exploit Status | Proof of Concept |
| CISA KEV | False |
Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')
The @jhb.software/payload-cloudinary-plugin exposes an endpoint that performs unvalidated cryptographic signing of Cloudinary API parameters, allowing authenticated users with minimal privileges to forge valid signatures for arbitrary actions. This flaw allows attackers to overwrite remote storage assets, execute unauthorized file uploads, alter asset visibility parameters, trigger SSRF webhooks, and perform directory traversal within Cloudinary repositories.
A Server-Side Request Forgery (SSRF) and Bearer Token Exfiltration vulnerability exists in the @merill/lokka (Lokka) Model Context Protocol (MCP) server prior to version 2.1.2. The server constructed Azure Resource Manager request URLs by concatenating user-controlled path parameters directly into destination request strings. By injecting authority-redefinition characters, an attacker can manipulate URL parsing to execute a host-escape attack, forcing the server to send high-privilege Azure Resource Manager (ARM) Bearer tokens to an external attacker-controlled host. This allows complete administrative access to the associated Azure subscriptions.
A directory traversal and symlink following vulnerability exists in Pydantic Settings when using the NestedSecretsSettingsSource with nested subdirectory lookups enabled. An attacker capable of writing to the secrets directory can bypass size limitations, read arbitrary host files, or cause a denial-of-service condition via cyclic symlinks.
A Server-Side Request Forgery (SSRF) vulnerability exists in SurrealDB's Identity & Access Management (IAM) module prior to version 3.1.5. When configuring JSON Web Key Set (JWKS) URLs for token verification, the remote fetcher follows HTTP redirects by default without validating redirect targets against configured network capabilities. This allows high-privileged users to bypass network access limits and perform blind port scanning of internal network resources.
A local file disclosure vulnerability exists in SurrealDB's full-text search capabilities, allowing authenticated users with database EDITOR or OWNER roles to read arbitrary files from the host system filesystem. This occurs by abusing the mapper() filter inside a DEFINE ANALYZER statement to point to system files.
SurrealDB versions 3.0.0 through 3.1.4 contain an information exposure vulnerability (CWE-203) where the query planner optimizes sorted queries using indexes on fields with field-level SELECT restrictions. Because the query planner performs index-based sorting before enforcing permission-based redaction, unauthorized users can observe the physical order of returned rows to deduce the relative values of protected fields.