Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Packages on PyPI are not secure by default

The Python Package Index (PyPI) is the primary public package repository for Python. It hosts a very large and continuously growing collection of third-party software packages.

A package being available on PyPI does not mean that the package has been security-audited or that its content can be trusted.

There is an important distinction between package availability, artifact integrity, artifact provenance, and software trustworthiness:

PyPI provides some minor mechanisms that improve integrity and provenance, but it cannot guarantee that a package is not malware, has severe weaknesses and should not be installed or used.

Source repository and the uploaded PyPI artifact

A common mistake is to assume that the source code visible in a public repository is necessarily identical to the code contained in the package installed from PyPI.

For example, a project may have a repository such as GitHub containing a particular commit or release tag. The maintainer may subsequently build a wheel or source distribution and upload that artifact to PyPI. The artifact is what pip installs; the repository is not consulted by pip during a normal installation.

Consequently, a compromised maintainer account, compromised build environment, malicious build process, or malicious release workflow could potentially result in an artifact containing code that is not present in the corresponding source repository.

This is one reason why reproducible builds and verifiable build provenance are important supply-chain security goals.

PyPI has introduced Trusted Publishing and attestations to improve this situation. Trusted Publishing uses OpenID Connect (OIDC) to allow configured CI/CD systems to publish using short-lived credentials rather than long-lived API tokens. PyPI attestations can provide cryptographically verifiable information about the identity used to publish an artifact. These mechanisms increase confidence in the provenance of an artifact, but they do not constitute a security audit of the package or guarantee that its code is benign.

Security Risk when installing a package

A Python package can contain arbitrary executable code. Depending on the package and the privileges of the process installing or importing it, malicious code could, for example:

These are not properties unique to PyPI. They are inherent consequences of installing and executing third-party software.

A package can also be unintentionally insecure without being malicious. It may contain a vulnerability, use an insecure dependency, expose sensitive information through logging, or make assumptions that are unsafe in a particular deployment environment.

Therefore, the appropriate security question is not:

“Is this package on PyPI?”

but rather:

“Do I have sufficient reason to trust this particular artifact and its provenance for this particular use?”


Security Measures on PyPI

The Python Package Index (PyPI) implements a range of controls designed to defend the registry, package publishers, and consumers against abuse. These measures form important layers of defence across the software supply chain, though they do not guarantee that individual packages are safe:

Distribution Hashes & HTTPS

PyPI delivers package downloads over HTTPS, using TLS to secure the connection and prevent network-level tampering. Additionally, PyPI publishes cryptographic hashes (preferring SHA-256 over MD5) to ensure file integrity.

However, integrity and transport security do not equal trustworthiness:

pip Hash-Checking Mode

pip supports strict verification via the --require-hashes flag. When enabled, every requirement and dependency must be pinned to a specific version or path and matched against an explicit, user-supplied hash:

SomePackage==1.2.3 \
    --hash=sha256:<expected-hash>

This prevents unexpected modification or substitution of distributions, making it ideal for reproducible deployments. Because normal pip install commands do not enforce hash checking by default, consumers must opt in explicitly. This mechanism addresses file substitution, but cannot determine if the expected artifact itself is malicious.

Provenance: Trusted Publishing & Attestations

Modern PyPI security focuses on bridging the gap between artifact integrity and supply-chain provenance:

While these tools prove where an artifact came from and how it was published, provenance is not an assertion of code quality. A compromised repository or build pipeline can still publish malicious artifacts using valid attestations. Provenance verifies origin, not trustworthiness.

Security challenges when using PyPI

The principal security challenges in the Python package ecosystem include:

These threats cannot be solved by a single control.

A mature Python software-supply-chain security strategy therefore combines several layers: carefully selecting dependencies, pinning versions where appropriate, reviewing important packages, keeping dependencies updated, using vulnerability information, protecting maintainer and CI/CD credentials, using Trusted Publishing where possible, verifying provenance and attestations where available, and using hash-locked installations for environments that require strict reproducibility.

Summary

PyPI provides a distribution mechanism and a number of important security controls; it is not a security certification authority for Python packages.

A PyPI package should therefore be treated as third-party software. The fact that a package is hosted on PyPI, is downloaded over HTTPS, has a SHA-256 hash, is downloaded millions of times per day, or even has a valid provenance attestation does not, by itself, establish that the package is secure, free from weaknesses, or free from vulnerabilities.

Remember: A weakness is a flaw, design issue, or insecure coding practice that may introduce a security risk; a vulnerability is a weakness that can be exploited to compromise the confidentiality, integrity, or availability of a system in a particular context.

Security depends on what property is being verified:

MechanismWhat it helps establishWhat it does not establish
HTTPSSecure communication with the PyPI infrastructureThat the package is trustworthy
PyPI file hashIdentity/integrity of a particular distributionThat the distribution is benign or built from a particular source revision
pip --require-hashesThat installed distributions match consumer-specified hashesThat the expected distributions are safe
Trusted PublishingWhich configured publishing identity was authorized to uploadThat the resulting code is safe
AttestationsCryptographically verifiable artifact provenanceThat the source code or artifact is free of vulnerabilities
Security/malware reportingDetection and response to known or reported abuseThat previously unreported packages are safe

The goal is therefore not to establish that “PyPI is safe”, but to build enough independent assurance around each dependency that its risk is acceptable for the intended environment.