
Cloud Vulnerability DB
A community-led vulnerabilities database
CVE-2026-49836 is a path traversal vulnerability in the Python library psd-tools that enables arbitrary file write and read via attacker-controlled smart-object filenames embedded in PSD files. It affects all releases of psd-tools exposing the SmartObject API through v1.17.0 (pip package). The vulnerability was reported on May 25, 2026, published by maintainer kyamagu on June 2, 2026, and added to the GitHub Advisory Database on July 9, 2026. It carries a CVSS v4.0 base score of 4.6 (Medium) (GitHub Advisory, psd-tools Advisory).
The root cause is improper limitation of a pathname to a restricted directory (CWE-22) combined with external control of file name or path (CWE-73). In SmartObject.save() (src/psd_tools/api/smart_object.py:170-179, tag v1.17.0), when no explicit filename is provided, the method uses self.filename verbatim — a value read directly from the PSD file's linked-layer block via read_unicode_string() with no sanitization, no os.path.basename() stripping, no absolute-path rejection, and no ../ filtering. This allows an attacker-crafted PSD to specify a filename like ../../PWNED.bin or /etc/cron.d/backdoor, causing the library to write attacker-controlled bytes to an arbitrary path. A secondary issue in SmartObject.open() for external-kind smart objects allows the fullPath descriptor embedded in the PSD to be used as an arbitrary file read source, enabling exfiltration of sensitive files (e.g., /etc/passwd) to the attacker-controlled write destination. A public proof-of-concept script is included in the advisory (GitHub Advisory, Fix PR #657).
Successful exploitation allows an attacker who can supply a malicious .psd file to write arbitrary bytes to any filesystem path writable by the process running psd-tools, including configuration files, cron jobs, or shell initialization scripts — potentially escalating to remote code execution. The secondary read-path issue additionally enables exfiltration of any file readable by the process (e.g., credentials, private keys, /etc/passwd) by embedding a malicious fullPath in an external-kind smart object. The severity is higher for services that automatically extract smart objects from user-uploaded PSD files without user interaction, as no authentication or special configuration is required for exploitation (GitHub Advisory, psd-tools Advisory).
A standalone proof-of-concept script is publicly documented in the advisory, demonstrating confirmed arbitrary file write outside the intended output directory using psd-tools==1.17.0. Exploitation requires no privileges and no special configuration — only that a victim application opens an attacker-supplied PSD and calls SmartObject.save(). There is no evidence of in-the-wild exploitation, no known threat actor attribution, and the CVE status remains "Reserved" as of the advisory publication date. No EPSS score or CISA KEV catalog entry is currently available for this CVE (GitHub Advisory, psd-tools Advisory).
src/psd_tools/psd/linked_layer.py:100) to a path-traversing value such as ../../PWNED.bin or an absolute path like /etc/cron.d/backdoor. The embedded data payload (attacker-controlled bytes) is set to the desired file content..psd file to a target application that processes untrusted PSD files — e.g., upload it to a web service that extracts smart objects, or send it to a user of a desktop tool.PSDImage.open() and iterates over layers, calling l.smart_object.save() for smart object layers — a common pattern for extracting embedded assets.SmartObject.save() uses self.filename verbatim with no path sanitization, the library writes the attacker-controlled bytes to the attacker-specified path (e.g., ../../PWNED.bin resolves outside the output directory). An absolute path like /home/user/.bashrc is honored identically.fullPath (e.g., /etc/passwd) in the PSD descriptor. When save() reads content via the data property, it calls open() with no external_dir constraint, reading the target file and writing its contents to the controlled output directory, enabling exfiltration (GitHub Advisory, psd-tools Advisory)./etc/, home directories, cron directories)./etc/passwd, SSH keys, application config files) appearing in the PSD output/extraction directory, indicating the read-path exploit was triggered.psd-tools processing of externally supplied .psd files followed by unexpected file creation events in parent directories or system paths.open() with wb mode) originating from a Python process running psd-tools, targeting paths outside the expected output directory — detectable via auditd or similar file integrity monitoring tools.Upgrade psd-tools to v1.17.1 or later, which fixes both the write and read path traversal issues via PR #657. The patch applies os.path.basename() to strip directory components from embedded filenames, enforces output containment using os.path.realpath() and os.path.commonpath(), adds an external_dir parameter to SmartObject.open() to constrain external-kind read sources, and explicitly rejects empty or dot basenames. No configuration-based workaround is available for v1.17.0 and earlier; the only safe remediation is upgrading. Applications that cannot upgrade immediately should avoid calling SmartObject.save() on PSD files from untrusted sources (psd-tools Release v1.17.1, Fix PR #657).
Fix availability across major Linux distributions and their releases.
Source: This report was generated using AI
Free Vulnerability Assessment
Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.
Get a personalized demo
"Best User Experience I have ever seen, provides full visibility to cloud workloads."
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
"We know that if Wiz identifies something as critical, it actually is."