Cloudanix VulnDB

CVE-2026-59890

Medium · 6.1

CVSS

6.1

EPSS

0.4%

Published

Jul 8, 2026

CISA due date

—

Cloudanix analysis

Next patch cycle SSVC: Track

Some Python package builds on Mac computers could accidentally include private files that the publisher meant to leave out.

Exploit Available Chainable
Exploitation
Requires User Interaction
Attacker needs
User Interaction
Complexity
Moderate
Impact
Data Exposure
Component
Library
Class
Improper Input Validation
Remediation
Upgrade
Effort
Medium
Patch risk
Low

What it actually does

In setuptools versions prior to 83.0.0, source distribution file selection can incorrectly apply MANIFEST.in exclusion rules on macOS APFS/HFS+ file systems because filenames are compared without Unicode normalization. If an exclusion rule is written using one Unicode form, such as NFC, but an on-disk filename exists in another equivalent form, such as NFD, directives including exclude, global-exclude, recursive-exclude, and prune may fail to match. As a result, files intended to be excluded from a Python source distribution can be packaged and distributed. The primary technical impact is unintended disclosure of files, including secrets, private source files, configuration files, test data, or internal artifacts. Integrity impact is limited to the contents of the generated package being different from the maintainer’s intent; availability is not directly affected.

Why it matters to the business

Organizations that build or publish Python packages from macOS systems using affected setuptools versions may accidentally ship files that were meant to stay private. This can expose credentials, proprietary code, internal configuration, customer-impacting test data, or other sensitive material through public or private package registries. The issue has a moderate CVSS score and low EPSS probability, and it is not in the CISA KEV catalog, but exploit maturity is listed as available and setuptools is widely used across the Python ecosystem, making package maintainers, CI/CD owners, and software supply chain teams the primary risk owners.

How an attack unfolds

An attacker needs a way to influence files in a Python project that will later be packaged with vulnerable setuptools on a macOS APFS or HFS+ system. This could be through a malicious pull request, compromised contributor account, poisoned source archive, or social engineering of a maintainer. The attacker creates a filename that is visually or semantically equivalent to a filename covered by a MANIFEST.in exclusion rule but encoded using a different Unicode normalization form. When the maintainer or build process creates a source distribution with setuptools before 83.0.0, FileList compares the compiled glob patterns against the raw on-disk filename and the exclusion rule does not match. The sensitive or attacker-chosen file is then included in the generated sdist. If the package is published to a registry or shared internally, anyone with access to that artifact can retrieve the unintended file contents.

How to fix it

Upgrade setuptools to version 83.0.0 or later everywhere source distributions are built, including developer workstations, release automation, CI/CD runners, container images, and build backends. Pin or constrain build dependencies so isolated PEP 517 builds do not silently use an affected setuptools release. Rebuild and republish affected packages after upgrading. Audit recently published source distributions that were built on macOS using setuptools versions before 83.0.0, especially packages with MANIFEST.in exclusion rules for secrets, private directories, credentials, generated artifacts, or internal files. If sensitive data was included in any released artifact, remove or yank the artifact where feasible, rotate exposed credentials, invalidate tokens, and treat the disclosure as a supply-chain incident. As defense in depth, avoid storing secrets in package source trees, add release artifact inspection before publication, and prefer CI builds on controlled, patched build images.

How to confirm the fix worked

Confirm all build environments report setuptools 83.0.0 or later using commands such as python -m pip show setuptools or python -c "import setuptools; print(setuptools.__version__)". Verify pyproject.toml, setup.cfg, requirements files, lockfiles, build container images, and CI configuration do not allow setuptools versions below 83.0.0 for release builds. Build a fresh source distribution and inspect its contents with tools such as tar -tf dist/*.tar.gz or python -m tarfile -l dist/*.tar.gz. Compare the artifact contents against MANIFEST.in expectations after normalizing filenames to NFC and NFD. Test representative exclusion rules containing Unicode-sensitive filenames or directories on macOS APFS/HFS+ to ensure excluded files are absent. For already published packages, download the exact released sdist from the package registry and inspect the archive contents rather than relying only on the source repository state.

Typical attack path

  1. Identify a Python project that builds source distributions with setuptools prior to 83.0.0, especially on macOS APFS or HFS+ systems.
  2. Review MANIFEST.in rules to find excluded paths, filenames, or patterns that protect sensitive or private files.
  3. Introduce or rename a file using a Unicode normalization form that differs from the exclusion rule but appears equivalent to reviewers or tooling.
  4. Cause a maintainer or automated process to build an sdist using the vulnerable setuptools version.
  5. Rely on the normalization mismatch so exclude, global-exclude, recursive-exclude, or prune does not remove the file.
  6. Obtain the published or shared source distribution and extract the unintentionally included file.

How to detect it

To determine whether this was already exploited or triggered accidentally, review Python package release history and build logs for source distributions created with setuptools prior to 83.0.0, especially from macOS APFS or HFS+ hosts. Inspect published sdists in public and private package registries by downloading the exact artifacts and listing archive contents. Compare each archive against MANIFEST.in exclusion rules while normalizing filenames to both NFC and NFD. Look for files that should have matched exclude, global-exclude, recursive-exclude, or prune directives but are present in the archive. Review source control history, pull requests, and file rename events for visually suspicious Unicode filenames, decomposed Unicode characters, or filenames that look identical to excluded paths. Search extracted artifacts for sensitive material such as private keys, tokens, .env files, credentials, internal configuration, proprietary data, or directories expected to be pruned. Relevant log sources include CI/CD build logs, package publishing logs, artifact repository audit logs, PyPI or private registry upload events, source control commit and pull request records, and endpoint file creation events on release workstations. There are no reliable network-level indicators for this vulnerability; detection is primarily artifact and build-process focused.

  • setuptools<83.0.0
  • setuptools 82.
  • setuptools 81.
  • setuptools 80.
  • MANIFEST.in
  • exclude
  • global-exclude
  • recursive-exclude
  • prune
  • .env
  • id_rsa
  • id_dsa
  • id_ecdsa
  • id_ed25519
  • .pypirc
  • credentials.json
  • service-account.json
  • *.pem
  • *.key
  • dist/*.tar.gz

What your security team should do

  • Inventory Python projects and release pipelines that use setuptools to build source distributions, prioritizing packages built or released from macOS systems.
  • Require setuptools 83.0.0 or later in build constraints, release images, and CI/CD dependency baselines.
  • Audit recent source distributions for unintended files, especially credentials, .env files, private keys, internal configs, unpublished source, and files covered by MANIFEST.in exclusions.
  • Add an automated release gate that lists archive contents and fails builds if sensitive patterns or excluded normalized paths appear in sdists or wheels.
  • If leaked data is found, rotate credentials immediately, revoke exposed tokens, remove affected artifacts where possible, and perform incident response scoping for downstream consumers.
  • Educate maintainers that MANIFEST.in exclusions are not a substitute for keeping secrets out of repositories and build directories.
  • Monitor package registries and internal artifact stores for old vulnerable releases that may still contain sensitive files.

The record

setuptools is a package that allows users to download, build, install, upgrade, and uninstall Python packages. Prior to 83.0.0, FileList applied MANIFEST.in exclude, global-exclude, recursive-exclude, and prune directives by matching compiled glob patterns against on-disk file names without Unicode normalization, so on macOS APFS or HFS+ an NFD file name could bypass an NFC exclusion rule and be packed into a source distribution. This issue is fixed in version 83.0.0.

Affected packages

Ecosystem Package Introduced Fixed

Related vulnerabilities