Guidance on wheel build numbers for external reference / security fixes

Wheel build numbers are defined in the binary distribution format spec as a part of the filename for wheels and a Build field in metadata. Wheel build numbers’ primary use-case is allowing partial rebuilds of binary artifacts for a given release without creating a new release which would require rebuilding all binary artifacts.

The problem with wheel build numbers is they’re not a part of the distribution’s version, they are something separate. This distinction sets them apart from Python post-release versions and similar concepts in redistribution ecosystems like apt/yum/apk (ie “openssl-dev@1.1.1k-12”) where the post-release number is a part of the installable package version. You can’t specify the build number of a package to pip without pointing at a specific URL for the wheel. This distinction also makes specifying a version range difficult in situations where that might be useful like a list of versions that are vulnerable to a CVE.

I propose that wheel build numbers should be discouraged from use in situations where the new distribution would need to be referenced externally, like in the case of making a release to fix a security vulnerability and that instead a new release or a post-release should be used in these situations.

If this proposal is accepted I would like suggestions on next steps in order to best ensure this guidance is followed (for example: updating specifications/documentation with disclaimers against use for security vulnerability fixes). This guidance isn’t likely to be strictly enforceable without deprecating/removing build numbers as a whole.

3 Likes

Logically, the only reason I can see to increment the build for a
“security fix” is if an external dependency changed in ways that
required a trivial rebuild of the exact same source version (sdist).
Is this what you’re referring to? And in that case, can you
elaborate on why that (incrementing just the build number when
rebuilding the binary artifacts without fudging a “fake” new source
version to represent the rebuild action) leads to problems for
downstream consumers? Or are you saying the build number is getting
abused for other more disruptive alterations of the package?

Logically, the only reason I can see to increment the build for a
“security fix” is if an external dependency changed in ways that
required a trivial rebuild of the exact same source version (sdist).
Is this what you’re referring to?

That is what I’m referring to.

And in that case, can you elaborate on why that leads to problems for downstream consumers?

If a package is vulnerable for v1.0.0 and fixes the vulnerability via incrementing the build number then there’s a situation where the vulnerable and fixed version are v1.0.0 according to pip and external tools/standards introspecting the Python ecosystem. This could cause confusion for affected users and potentially tools to not register an installed version as “vulnerable”.

I guess that makes sense for some projects. For the ones I’m
involved in, we would consider those vulnerabilities in an external
dependency since there’s no fix we can link to in our source
revision control (and we disclaim responsibility for built binary
artifacts on PyPI recommending against their use in production), but
I can certainly see how different communities may take other
stances.

Created a PR for warning about interoperability issues with build numbers: Add warning about reference interop for build numbers by sethmlarson · Pull Request #1277 · pypa/packaging.python.org · GitHub

1 Like