diff --git a/news/13079.bugfix.rst b/news/13079.bugfix.rst new file mode 100644 index 00000000000..5b297f5a12e --- /dev/null +++ b/news/13079.bugfix.rst @@ -0,0 +1 @@ +This change fixes a security bug allowing a wheel to execute code during installation. diff --git a/src/pip/_internal/commands/install.py b/src/pip/_internal/commands/install.py index ad45a2f2a57..70acf202be9 100644 --- a/src/pip/_internal/commands/install.py +++ b/src/pip/_internal/commands/install.py @@ -10,6 +10,13 @@ from pip._vendor.packaging.utils import canonicalize_name from pip._vendor.rich import print_json +# Eagerly import self_outdated_check to avoid crashes. Otherwise, +# this module would be imported *after* pip was replaced, resulting +# in crashes if the new self_outdated_check module was incompatible +# with the rest of pip that's already imported, or allowing a +# wheel to execute arbitrary code on install by replacing +# self_outdated_check. +import pip._internal.self_outdated_check # noqa: F401 from pip._internal.cache import WheelCache from pip._internal.cli import cmdoptions from pip._internal.cli.cmdoptions import make_target_python @@ -408,12 +415,6 @@ def run(self, options: Values, args: List[str]) -> int: # If we're not replacing an already installed pip, # we're not modifying it. modifying_pip = pip_req.satisfied_by is None - if modifying_pip: - # Eagerly import this module to avoid crashes. Otherwise, this - # module would be imported *after* pip was replaced, resulting in - # crashes if the new self_outdated_check module was incompatible - # with the rest of pip that's already imported. - import pip._internal.self_outdated_check # noqa: F401 protect_pip_from_modification_on_windows(modifying_pip=modifying_pip) reqs_to_build = [