VAITP Dataset

← Back to the dataset

CVE-2023-49797

PyInstaller < 5.13.1 privilege escalation via symlink attack in applications with matplotlib or win32com run as administrator with an unsecured temporary directory.

  • CVSS 7.8
  • CWE-732
  • Information Leakage
  • Remote

PyInstaller bundles a Python application and all its dependencies into a single package. A PyInstaller built application, elevated as a privileged process, may be tricked by an unprivileged attacker into deleting files the unprivileged user does not otherwise have access to. A user is affected if **all** the following are satisfied: 1. The user runs an application containing either `matplotlib` or `win32com`. 2. The application is ran as administrator (or at least a user with higher privileges than the attacker). 3. The user's temporary directory is not locked to that specific user (most likely due to `TMP`/`TEMP` environment variables pointing to an unprotected, arbitrary, non default location). Either: A. The attacker is able to very carefully time the replacement of a temporary file with a symlink. This switch must occur exactly between `shutil.rmtree()`'s builtin symlink check and the deletion itself B: The application was built with Python 3.7.x or earlier which has no protection against Directory Junctions links. The vulnerability has been addressed in PR #7827 which corresponds to `pyinstaller >= 5.13.1`. Users are advised to upgrade. There are no known workarounds for this vulnerability.

CVSS base score
7.8
Published
2023-12-09
OWASP
A08 Software and Data Integrity Failures
Orthogonal defect classification
Checking
Code defect classification
Extraneous Check
Category
Information Leakage
Subcategory
Insecure Handling of Sensitive Data
Accessibility scope
Remote
Impact
Privilege Escalation
Fixed by upgrading
Yes

Solution

Upgrade to PyInstaller version 5.13.1 or later

Vulnerable code sample

import os
import shutil
import tempfile

def rmtree(path):
    shutil.rmtree(path)

try:
    temp_dir = tempfile.gettempdir()
    os.mkdir(os.path.join(temp_dir, 'to_delete'))
    
    rmtree(os.path.join(temp_dir, 'to_delete'))
except Exception as e:
    print(f"Error: {e}")

Patched code sample

import os
import shutil
import tempfile

def rmtree(path):
    if os.path.commonpath([path, tempfile.gettempdir()]) == tempfile.gettempdir():
        raise PermissionError("Attempting to delete files outside of the user's temporary directory is not allowed.")
    
    shutil.rmtree(path)

try:
    temp_dir = tempfile.mkdtemp()
    os.mkdir(os.path.join(temp_dir, 'to_delete'))
    
    rmtree(os.path.join(temp_dir, 'to_delete'))
except Exception as e:
    print(f"Error: {e}")

Cite this entry

@misc{vaitp:cve202349797,
  title        = {{PyInstaller < 5.13.1 privilege escalation via symlink attack in applications with matplotlib or win32com run as administrator with an unsecured temporary directory.}},
  author       = {Bogaerts, Fr\'ed\'eric and Ivaki, Naghmeh and Fonseca, Jos\'e},
  year         = {2023},
  note         = {VAITP Python Vulnerability Dataset, entry CVE-2023-49797},
  howpublished = {\url{https://netpack.pt/vaitp/vulnerability/CVE-2023-49797/}}
}
Introducing the "VAITP dataset": a specialized repository of Python vulnerabilities and patches, meticulously compiled for the use of the security research community. As Python's prominence grows, understanding and addressing potential security vulnerabilities become crucial. Crafted by and for the cybersecurity community, this dataset offers a valuable resource for researchers, analysts, and developers to analyze and mitigate the security risks associated with Python. Through the comprehensive exploration of vulnerabilities and corresponding patches, the VAITP dataset fosters a safer and more resilient Python ecosystem, encouraging collaborative advancements in programming security.

The supreme art of war is to subdue the enemy without fighting.

Sun Tzu – “The Art of War”

:: Shaping the future through research and ingenuity ::