Skip to content

Validate VCS urls in hash-checking mode using their commit hashes#11968

Draft
sbidoul wants to merge 6 commits into
pypa:mainfrom
sbidoul:vcs-require-hashes
Draft

Validate VCS urls in hash-checking mode using their commit hashes#11968
sbidoul wants to merge 6 commits into
pypa:mainfrom
sbidoul:vcs-require-hashes

Conversation

@sbidoul

@sbidoul sbidoul commented Apr 16, 2023

Copy link
Copy Markdown
Member

closes #6469

The default is potentially dangerous.
@sbidoul sbidoul added the C: vcs pip's interaction with version control systems like git, svn and bzr label Apr 16, 2023
@sbidoul sbidoul added this to the 23.2 milestone Apr 16, 2023
raise DependencyVcsHashNotSupported()
return VcsHashes()
if req.link.is_existing_dir():
raise DirectoryUrlHashUnsupported()

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note to self: when req.is_wheel_from_cache is True, link is the cached wheel and not the link to the artifact that was downloaded to build the wheel. So this function may not necessarily do what one expects when reasoning on req.link.

@sbidoul sbidoul force-pushed the vcs-require-hashes branch from b5608e7 to a1cd61b Compare April 16, 2023 15:35
Comment on lines +597 to +599
elif isinstance(req.download_info.info, VcsInfo):
if not req.user_supplied:
raise DependencyVcsHashNotSupported()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if this would break anything. How can this branch be reached?

@sbidoul sbidoul Apr 17, 2023

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would raise in require-hashes mode only, if you have a dependency as a git direct URL that is obtained from cache.

I think these should not be considered hash-valid unless the commit hash has been provided by the user, either as a requirement file or a constraint.

This PR still needs work. Next step is adding a lot of test coverage. Then possibly some refactoring.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If an immutable VCS URL is both user-supplied and a dependency, would this cause the latter specifier break installation?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should not, because when the dependency is examined by the resolver it is "merged" with the user-supplied one? That's definitely a test case to consider.

Comment on lines +160 to +161

pass

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
pass

@sbidoul sbidoul removed this from the 23.2 milestone Jun 25, 2023
@sbidoul

sbidoul commented Jun 25, 2023

Copy link
Copy Markdown
Member Author

This is still on my list but unfortunately I won't have time to finish it in time for 23.2.

@pfmoore

pfmoore commented Jun 25, 2023

Copy link
Copy Markdown
Member

I removed #6469 from the 23.2 milestone for consistency.

@bcail

bcail commented Jul 13, 2023

Copy link
Copy Markdown

This PR seemed to work for me, for installing a package from a git repo.

@adamzap

adamzap commented Sep 5, 2023

Copy link
Copy Markdown

Is there anything we can do to move this forward? It seems to work. Thanks!

Comment thread src/pip/_internal/exceptions.py Outdated
Comment thread docs/html/topics/secure-installs.md Outdated
Comment thread src/pip/_internal/operations/prepare.py Outdated
sbidoul and others added 3 commits October 1, 2023 16:50
Co-authored-by: Ed Morley <501702+edmorley@users.noreply.github.com>
Co-authored-by: Ed Morley <501702+edmorley@users.noreply.github.com>
Co-authored-by: Ed Morley <501702+edmorley@users.noreply.github.com>
@sbidoul

sbidoul commented Oct 1, 2023

Copy link
Copy Markdown
Member Author

Tests to do

  • test git url + --hash errors out (with and without --require-hashes, with and without cache)
  • test git url + not commit hash errors out with --require-hashes
  • test git url + not commit hash don't error out without --require-hashes
  • test that an indirect dependency specified as a git url fails in hash-checking mode

@bcail

bcail commented Oct 30, 2023

Copy link
Copy Markdown

@sbidoul Here's a test for the second and third points you mentioned. Is that helpful? Should I work on expanding it more?

diff --git a/tests/unit/test_req.py b/tests/unit/test_req.py
index d70fa9da5..22cc7256c 100644
--- a/tests/unit/test_req.py
+++ b/tests/unit/test_req.py
@@ -241,6 +241,35 @@ class TestRequirementSet:
             ):
                 resolver.resolve(reqset.all_requirements, True)
 
+    def test_vcs_url_without_commit_hash(self, data: TestData) -> None:
+        """VCS URLs should raise errors when --require-hashes is on, if
+        they don't have a commit hash.
+        """
+        reqset = RequirementSet()
+        reqset.add_unnamed_requirement(
+            get_processed_req_from_line(
+                "git+https://github.com/pypa/pip-test-package",
+                lineno=1,
+            )
+        )
+
+        finder = make_test_finder(find_links=[data.find_links])
+
+        with self._basic_resolver(finder, require_hashes=True) as resolver:
+            with pytest.raises(
+                HashErrors,
+                match=(
+                    r"Can't verify hashes for these VCS requirements because their ref is "
+                    r"not immutable:\n"
+                    r"    git\+https://github\.com/pypa/pip-test-package \(from -r "
+                    r"file \(line 1\)\)"
+                ),
+            ):
+                resolver.resolve(reqset.all_requirements, True)
+
+        with self._basic_resolver(finder, require_hashes=False) as resolver:
+            resolver.resolve(reqset.all_requirements, True)
+

@FrancoisPerez

Copy link
Copy Markdown

Any way we can help this PR move forward @sbidoul ?

@ichard26

ichard26 commented Nov 6, 2025

Copy link
Copy Markdown
Member

@sbidoul do you wish to repick up this PR at some point?

@sbidoul

sbidoul commented Nov 6, 2025

Copy link
Copy Markdown
Member Author

Possibly. I'd need to delve into this again but I suspect it will be necessary in some form or another to support installation from pylock.

@sbidoul

sbidoul commented Mar 28, 2026

Copy link
Copy Markdown
Member Author

Finishing this is necessary to support pylock vcs entries.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bot:chronographer:provided C: vcs pip's interaction with version control systems like git, svn and bzr

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Validate VCS urls in hash-checking mode using their commit hashes

9 participants