A vulnerability in setuptools on Windows allows a crafted wheel's namespace_packages.txt to cause creation of an __init__.py file outside the intended installation directory. This occurs during legacy wheel installation when an absolute Windows path is supplied in the namespace_packages.txt file. The created file contains fixed content and is placed with the permissions of the installing process. The parent directory must already exist for this to succeed.
A Unicode normalization mismatch in setuptools' handling of MANIFEST.in exclusions can cause files intended to be excluded from source distributions to be included instead on macOS APFS/HFS+ filesystems. This occurs because setuptools matches file names byte-for-byte without Unicode normalization, leading to exclusion bypass when file names differ only in Unicode normalization form (NFC vs NFD). This can result in unintended disclosure of files containing secrets or private data when publishing to PyPI.
A path traversal vulnerability in setuptools' PackageIndex.download function allows an attacker to write files to arbitrary filesystem locations. This flaw arises from insufficient sanitization of URL-derived filenames, enabling os.path.join to be bypassed. The vulnerability affects Python 3.11 versions from 3.11.0 up to but not including 3.11.12_1. A fix is available in version 3.11.12_1. Exploitation could lead to arbitrary file write with the permissions of the running process, potentially escalating to remote code execution depending on context.
A command injection vulnerability exists in the package_index module of pypa/setuptools versions up to 69.1.1, affecting Python 3.11 packages before 3.11.9_1. This flaw allows remote code execution via download functions that handle package URLs, which if user-controlled, can lead to arbitrary command execution. The issue is fixed in version 3.11.9_1.
PyMuPDF versions prior to 1.28.2 contain a path traversal and arbitrary file write vulnerability in the embedded get function within the _main_.py file. This flaw allows an attacker with local access to write files to arbitrary locations. The vulnerability has a CVSS 4.0 score of 6.9, indicating a medium severity. A fix is available in version 1.28.2.
A vulnerability in setuptools on Windows allows a crafted wheel's namespace_packages.txt to cause legacy wheel installation to create an __init__.py file outside the intended installation directory. The created file has fixed content and is placed at a filesystem path influenced by the wheel, with the permissions of the installing process. The parent directory must already exist for this to occur.
A vulnerability in setuptools on Windows allows a crafted wheel's namespace_packages.txt to cause legacy wheel installation to create an __init__.py file outside the intended installation directory. The attacker can control the destination path of this file but not its contents. This occurs because an absolute Windows path in namespace_packages.txt bypasses normal path restrictions during installation.
After completing a build with AWS Serverless Application Model Command Line Interface (SAM CLI) which include symlinks, the content of those symlinks are copied to the cache of the local workspace as regular files or directories. As a result, a user who does not have access to those symlinks outside of the Docker container would now have access via the local workspace.
Users should upgrade to version 1.134.0 and ensure any forked or derivative code is patched to incorporate the new fixes. After upgrading, users must re-build their applications using the sam build --use-container to update the symlinks.
When running the AWS Serverless Application Model Command Line Interface (SAM CLI) build process with Docker and symlinks are included in the build files, the container environment allows a user to access privileged files on the host by leveraging the elevated permissions granted to the tool. A user could leverage the elevated permissions to access restricted files via symlinks and copy them to a more permissive location on the container.
Users should upgrade to v1.133.0 or newer and ensure any forked or derivative code is patched to incorporate the new fixes.
### Summary
On Windows, attacker-controlled content in a wheel's
`.dist-info/namespace_packages.txt` can cause setuptools' legacy wheel
installation path to create an `__init__.py` outside the requested
`destination_eggdir`.
The attacker can influence the destination path, but not the contents of
the created file.
### Details
Tested setuptools commit:
`6ead555c5fb29bc57fe6105b1bffc163f56fd558`
Relevant source:
`setuptools/wheel.py`
SHA-256:
`359b7e0d5dd8c3135653abe08a8ed5dc0352eadfd7df22cb5e2b5303b7c3cafd`
The relevant call path is:
`Wheel(wheel_path).install_as_egg(destination)`
→ `_install_as_egg`
→ `_convert_metadata`
→ `_fix_namespace_packages`
A wheel can provide attacker-controlled content in:
`<distribution>.dist-info/namespace_packages.txt`
The namespace value is eventually used approximately as:
```python
mod_dir = os.path.join(destination_eggdir, *mod.split('.'))
mod_init = os.path.join(mod_dir, '__init__.py')
If mod is a Windows drive-qualified absolute path containing no dots,
mod.split('.') preserves it as a single component.
On Windows, os.path.join(destination_eggdir, absolute_component) discards
the original base directory and resolves to the attacker-supplied absolute
path.
The existing wheel filename and ZIP traversal checks do not validate this
metadata value before it is subsequently interpreted as a filesystem path.
```markdown
### PoC
The reproduction was performed entirely inside a disposable temporary
directory.
Layout:
```text
sandbox/
destination/
outside/
input/
canary.txt
```
A synthetic wheel was created containing:
`demo_pkg-1.0.dist-info/namespace_packages.txt`
whose content was the absolute path of:
`sandbox\outside`
The real acquired setuptools implementation was then invoked:
```python
setuptools.wheel.Wheel(synthetic_wheel).install_as_egg(
sandbox_destination
)
```
The operation completed without exception.
Expected metadata was created under:
`sandbox\destination\EGG-INFO`
but setuptools also created:
`sandbox\outside\__init__.py`
The file did not exist before execution.
Its contents were:
```python
__import__('pkg_resources').declare_namespace(__name__)
```
The unrelated canary remained byte-identical.
The sandbox was deleted after recording the evidence.
```
### Impact
A crafted wheel can cause setuptools to create a fixed-content
`__init__.py` outside the intended installation directory at a
filesystem path influenced by the wheel, with the permissions of the
process performing the installation.
The demonstrated reproduction required the target parent directory to
already exist.
The Include directive in `src/mistune/directives/include.py` does not validate that the resolved file path stays within the source directory, allowing path traversal via `../` sequences to read arbitrary files.
Additionally, error messages and included file contents are rendered without HTML escaping, leading to XSS even when `escape=True`.
Affected functions:
- Path resolution (lines 27-31)
- `block_error()` in html.py (line 140)
- `render_html_include()` (line 72)
The Include plugin must be explicitly enabled via the plugins parameter.
### Summary
On Windows, attacker-controlled content in a wheel's
`.dist-info/namespace_packages.txt` can cause setuptools' legacy wheel
installation path to create an `__init__.py` outside the requested
`destination_eggdir`.
The attacker can influence the destination path, but not the contents of
the created file.
### Details
Tested setuptools commit:
`6ead555c5fb29bc57fe6105b1bffc163f56fd558`
Relevant source:
`setuptools/wheel.py`
SHA-256:
`359b7e0d5dd8c3135653abe08a8ed5dc0352eadfd7df22cb5e2b5303b7c3cafd`
The relevant call path is:
`Wheel(wheel_path).install_as_egg(destination)`
→ `_install_as_egg`
→ `_convert_metadata`
→ `_fix_namespace_packages`
A wheel can provide attacker-controlled content in:
`<distribution>.dist-info/namespace_packages.txt`
The namespace value is eventually used approximately as:
```python
mod_dir = os.path.join(destination_eggdir, *mod.split('.'))
mod_init = os.path.join(mod_dir, '__init__.py')
If mod is a Windows drive-qualified absolute path containing no dots,
mod.split('.') preserves it as a single component.
On Windows, os.path.join(destination_eggdir, absolute_component) discards
the original base directory and resolves to the attacker-supplied absolute
path.
The existing wheel filename and ZIP traversal checks do not validate this
metadata value before it is subsequently interpreted as a filesystem path.
```markdown
### PoC
The reproduction was performed entirely inside a disposable temporary
directory.
Layout:
```text
sandbox/
destination/
outside/
input/
canary.txt
```
A synthetic wheel was created containing:
`demo_pkg-1.0.dist-info/namespace_packages.txt`
whose content was the absolute path of:
`sandbox\outside`
The real acquired setuptools implementation was then invoked:
```python
setuptools.wheel.Wheel(synthetic_wheel).install_as_egg(
sandbox_destination
)
```
The operation completed without exception.
Expected metadata was created under:
`sandbox\destination\EGG-INFO`
but setuptools also created:
`sandbox\outside\__init__.py`
The file did not exist before execution.
Its contents were:
```python
__import__('pkg_resources').declare_namespace(__name__)
```
The unrelated canary remained byte-identical.
The sandbox was deleted after recording the evidence.
```
### Impact
A crafted wheel can cause setuptools to create a fixed-content
`__init__.py` outside the intended installation directory at a
filesystem path influenced by the wheel, with the permissions of the
process performing the installation.
The demonstrated reproduction required the target parent directory to
already exist.