p PatchFirst

GHSA-xmj3-9gf7-h52w

GHSA-xmj3-9gf7-h52w · setuptools: Windows path escape via namespace_packages.txt during legacy wheel installation Description

Здесь приведены факты из открытых источников об уязвимостях. Перед обновлением ознакомьтесь с исходным сообщением.

### 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.

CVSS 1.0 · Низкий · Есть исправление

Опубликовано
Обновлено

Стек: python

Затронутые продукты и версии

  • setuptools PyPI

    Версии
    • 38.2.3
    • 38.2.4
    • 38.2.5
    • 38.3.0
    • 38.4.0
    • 38.4.1
    • 38.5.0
    • 38.5.1
    • 38.5.2
    • 38.6.0
    • 38.6.1
    • 38.7.0
    • 39.0.0
    • 39.0.1
    • 39.1.0
    • 39.2.0
    • 40.0.0
    • 40.1.0
    • 40.1.1
    • 40.2.0
    • 40.3.0
    • 40.4.0
    • 40.4.1
    • 40.4.2
    • 40.4.3
    • 40.5.0
    • 40.6.0
    • 40.6.1
    • 40.6.2
    • 40.6.3
    • 40.7.0
    • 40.7.1
    • 40.7.2
    • 40.7.3
    • 40.8.0
    • 40.9.0
    • 41.0.0
    • 41.0.1
    • 41.1.0
    • 41.2.0
    • 41.3.0
    • 41.4.0
    • 41.5.0
    • 41.5.1
    • 41.6.0
    • 42.0.0
    • 42.0.1
    • 42.0.2
    • 43.0.0
    • 44.0.0
    • 44.1.0
    • 44.1.1
    • 45.0.0
    • 45.1.0
    • 45.2.0
    • 45.3.0
    • 46.0.0
    • 46.1.0
    • 46.1.1
    • 46.1.2
    • 46.1.3
    • 46.2.0
    • 46.3.0
    • 46.3.1
    • 46.4.0
    • 47.0.0
    • 47.1.0
    • 47.1.1
    • 47.2.0
    • 47.3.0
    • 47.3.1
    • 47.3.2
    • 48.0.0
    • 49.0.0
    • 49.0.1
    • 49.1.0
    • 49.1.1
    • 49.1.2
    • 49.1.3
    • 49.2.0
    • 49.2.1
    • 49.3.0
    • 49.3.1
    • 49.3.2
    • 49.4.0
    • 49.5.0
    • 49.6.0
    • 50.0.0
    • 50.0.1
    • 50.0.2
    • 50.0.3
    • 50.1.0
    • 50.2.0
    • 50.3.0
    • 50.3.1
    • 50.3.2
    • 51.0.0
    • 51.1.0
    • 51.1.0.post20201221
    • 51.1.1
    • 51.1.2
    • 51.2.0
    • 51.3.0
    • 51.3.1
    • 51.3.2
    • 51.3.3
    • 52.0.0
    • 53.0.0
    • 53.1.0
    • 54.0.0
    • 54.1.0
    • 54.1.1
    • 54.1.2
    • 54.1.3
    • 54.2.0
    • 56.0.0
    • 56.1.0
    • 56.2.0
    • 57.0.0
    • 57.1.0
    • 57.2.0
    • 57.3.0
    • 57.4.0
    • 57.5.0
    • 58.0.0
    • 58.0.1
    • 58.0.2
    • 58.0.3
    • 58.0.4
    • 58.1.0
    • 58.2.0
    • 58.3.0
    • 58.4.0
    • 58.5.0
    • 58.5.1
    • 58.5.2
    • 58.5.3
    • 59.0.1
    • 59.1.0
    • 59.1.1
    • 59.2.0
    • 59.3.0
    • 59.4.0
    • 59.5.0
    • 59.6.0
    • 59.7.0
    • 59.8.0
    • 60.0.0
    • 60.0.1
    • 60.0.2
    • 60.0.3
    • 60.0.4
    • 60.0.5
    • 60.1.0
    • 60.1.1
    • 60.10.0
    • 60.2.0
    • 60.3.0
    • 60.3.1
    • 60.4.0
    • 60.5.0
    • 60.6.0
    • 60.7.0
    • 60.7.1
    • 60.8.0
    • 60.8.1
    • 60.8.2
    • 60.9.0
    • 60.9.1
    • 60.9.2
    • 60.9.3
    • 61.0.0
    • 61.1.0
    • 61.1.1
    • 61.2.0
    • 61.3.0
    • 61.3.1
    • 62.0.0
    • 62.1.0
    • 62.2.0
    • 62.3.0
    • 62.3.1
    • 62.3.2
    • 62.3.3
    • 62.3.4
    • 62.4.0
    • 62.5.0
    • 62.6.0
    • 63.0.0
    • 63.0.0b1
    • 63.1.0
    • 63.2.0
    • 63.3.0
    • 63.4.0
    • 63.4.1
    • 63.4.2
    • 63.4.3
    • 64.0.0
    • 64.0.1
    • 64.0.2
    • 64.0.3
    • 65.0.0
    • 65.0.1
    • 65.0.2
    • 65.1.0
    • 65.1.1
    • 65.2.0
    • 65.3.0
    • 65.4.0
    • 65.4.1
    • 65.5.0
    • 65.5.1
    • 65.6.0
    • 65.6.1
    • 65.6.2
    • 65.6.3
    • 65.7.0
    • 66.0.0
    • 66.1.0
    • 66.1.1
    • 67.0.0
    • 67.1.0
    • 67.2.0
    • 67.3.1
    • 67.3.2
    • 67.3.3
    • 67.4.0
    • 67.5.0
    • 67.5.1
    • 67.6.0
    • 67.6.1
    • 67.7.0
    • 67.7.1
    • 67.7.2
    • 67.8.0
    • 68.0.0
    • 68.1.0
    • 68.1.2
    • 68.2.0
    • 68.2.1
    • 68.2.2
    • 69.0.0
    • 69.0.1
    • 69.0.2
    • 69.0.3
    • 69.1.0
    • 69.1.1
    • 69.2.0
    • 69.3.0
    • 69.3.1
    • 69.4.0
    • 69.4.1
    • 69.4.2
    • 69.5.0
    • 69.5.1
    • 70.0.0
    • 70.1.0
    • 70.1.1
    • 70.2.0
    • 70.3.0
    • 71.0.0
    • 71.0.1
    • 71.0.2
    • 71.0.3
    • 71.0.4
    • 71.1.0
    • 72.0.0
    • 72.1.0
    • 72.2.0
    • 73.0.0
    • 73.0.1
    • 74.0.0
    • 74.1.0
    • 74.1.1
    • 74.1.2
    • 74.1.3
    • 75.0.0
    • 75.1.0
    • 75.2.0
    • 75.3.0
    • 75.3.1
    • 75.3.2
    • 75.3.3
    • 75.3.4
    • 75.4.0
    • 75.5.0
    • 75.6.0
    • 75.7.0
    • 75.8.0
    • 75.8.1
    • 75.8.2
    • 75.9.0
    • 75.9.1
    • 76.0.0
    • 76.1.0
    • 77.0.1
    • 77.0.3
    • 78.0.1
    • 78.0.2
    • 78.1.0
    • 78.1.1
    • 79.0.0
    • 79.0.1
    • 80.0.0
    • 80.0.1
    • 80.1.0
    • 80.10.1
    • 80.10.2
    • 80.2.0
    • 80.3.0
    • 80.3.1
    • 80.4.0
    • 80.6.0
    • 80.7.0
    • 80.7.1
    • 80.8.0
    • 80.9.0
    • 81.0.0
    • 82.0.0
    • 82.0.1
    • 83.0.0
    • 84.0.0
    Затронутые диапазоны версий
    • ECOSYSTEM: ≥ 38.2.2, < 84.1.0

    Обновитесь до 84.1.0

Первоисточники

Проверьте свой сервер →