Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(npm): registry inferring should include the full registry path #7030

Merged
merged 1 commit into from
Apr 17, 2023

Conversation

yeikel
Copy link
Contributor

@yeikel yeikel commented Apr 10, 2023

Fixes #6804

@yeikel yeikel force-pushed the issue/6804 branch 3 times, most recently from 2543a29 to f3cab6c Compare April 10, 2023 04:40
@@ -1787,7 +1787,37 @@
expect(file_fetcher_instance.files.map(&:name)).
to eq(%w(package.json package-lock.json .npmrc))
expect(file_fetcher_instance.files.find { |f| f.name == ".npmrc" }.content).
to eq("registry=https://npm.fury.io")
to eq("registry=https://npm.fury.io/dependabot/")
Copy link
Contributor Author

@yeikel yeikel Apr 10, 2023

Choose a reason for hiding this comment

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

I believe that this test was incorrect

Copy link
Contributor Author

@yeikel yeikel Apr 10, 2023

Choose a reason for hiding this comment

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

I created a test org to double check this

image

Trying to pull any dependency from https://npm.fury.io/ would fail in this scenario

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks for trying this in real life! 💪

@yeikel yeikel marked this pull request as ready for review April 10, 2023 04:45
@yeikel yeikel requested a review from a team as a code owner April 10, 2023 04:45
@yeikel yeikel force-pushed the issue/6804 branch 2 times, most recently from a419b9d to a28f712 Compare April 10, 2023 04:54
@yeikel yeikel force-pushed the issue/6804 branch 5 times, most recently from c0ebbc0 to 807e2cd Compare April 11, 2023 19:18
Copy link
Contributor

@deivid-rodriguez deivid-rodriguez left a comment

Choose a reason for hiding this comment

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

Nice fix!

I do agree that the issue is probably not exploited, but I think we can probably keep the previous approach of properly parsing URIs to avoid it. I can suggest something tomorrow.

@@ -1787,7 +1787,37 @@
expect(file_fetcher_instance.files.map(&:name)).
to eq(%w(package.json package-lock.json .npmrc))
expect(file_fetcher_instance.files.find { |f| f.name == ".npmrc" }.content).
to eq("registry=https://npm.fury.io")
to eq("registry=https://npm.fury.io/dependabot/")
Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks for trying this in real life! 💪

@deivid-rodriguez deivid-rodriguez added T: bug 🐞 Something isn't working L: javascript:npm npm packages via npm F: private-registries 💂‍♂️ Issues about using private registries with Dependabot; may be paired with an R: label. labels Apr 11, 2023
@yeikel
Copy link
Contributor Author

yeikel commented Apr 12, 2023

I do agree that the issue is probably not exploited, but I think we can probably keep the previous approach of properly parsing URIs to avoid it. I can suggest something tomorrow.

I do not know what's best in Ruby as I am new to the language, but in the JVM and other languages like C#, this try/catch/recover pattern is not great as it is quite slow to unwind the stack. I expect a similar impact in Ruby but I do not know if it is a good practice or not

In the current code, we are running this logic for every single dependency declared and that can take a lot of time for a project with many dependencies(that is very common in the NPM world to begin with)

@yeikel yeikel force-pushed the issue/6804 branch 5 times, most recently from 4f85459 to b845856 Compare April 12, 2023 03:02
@deivid-rodriguez
Copy link
Contributor

I think it's fine in CRuby. But more importantly, I think it's best to focus on the bug fix rather than mixing in performance related patches. If the problem you mention is an issue, we could handle it separately.

Let me suggest this alternative patch that keeps the existing approach of parsing registries into well structured URIs:

diff --git a/npm_and_yarn/lib/dependabot/npm_and_yarn/file_fetcher.rb b/npm_and_yarn/lib/dependabot/npm_and_yarn/file_fetcher.rb
index 4ef88467c..10f75aa33 100644
--- a/npm_and_yarn/lib/dependabot/npm_and_yarn/file_fetcher.rb
+++ b/npm_and_yarn/lib/dependabot/npm_and_yarn/file_fetcher.rb
@@ -90,7 +90,7 @@ module Dependabot
         return @inferred_npmrc = nil unless npmrc.nil? && package_lock
 
         known_registries = []
-        JSON.parse(package_lock.content).fetch("dependencies", {}).each do |_name, details|
+        JSON.parse(package_lock.content).fetch("dependencies", {}).each do |dependency_name, details|
           resolved = details.fetch("resolved", "https://registry.npmjs.org")
           begin
             uri = URI.parse(resolved)
@@ -99,8 +99,24 @@ module Dependabot
             # This can happen if resolved is false, for instance.
             next
           end
+
+          next unless uri.scheme && uri.host
+
           # Check for scheme since path dependencies will not have one
-          known_registries << "#{uri.scheme}://#{uri.host}" if uri.scheme && uri.host
+          known_registry = "#{uri.scheme}://#{uri.host}"
+
+          path = uri.path
+          if path
+            index = path.index(dependency_name)
+
+            if index
+              registry_base_path = path[0...index].delete_suffix("/")
+
+              known_registry << registry_base_path
+            end
+          end
+
+          known_registries << known_registry
         end
 
         if known_registries.uniq.length == 1 && known_registries.first != "https://registry.npmjs.org"

Using this approach is how I discovered yesterday that the test lockfile was incorrect, because the tests you added do not pass with this patch due to the dependency name vs registry url discrepancy.

@yeikel yeikel force-pushed the issue/6804 branch 2 times, most recently from 44fd598 to 8a0b1ac Compare April 12, 2023 19:55
@yeikel yeikel force-pushed the issue/6804 branch 2 times, most recently from 3ab1058 to 9e2ad35 Compare April 13, 2023 01:22
@yeikel yeikel force-pushed the issue/6804 branch 5 times, most recently from 1754f2c to 74164ec Compare April 14, 2023 13:37
@yeikel yeikel requested a review from deivid-rodriguez April 14, 2023 18:26
@yeikel
Copy link
Contributor Author

yeikel commented Apr 14, 2023

@deivid-rodriguez Let me know if you have any additional feedback :)

Thanks again

@yeikel
Copy link
Contributor Author

yeikel commented Apr 16, 2023

@jeffwidman I would appreciate your input here as well

@deivid-rodriguez
Copy link
Contributor

Sorry for the delay @yeikel, this looks good to me, but I'd like to extract the malformed URI handling changes/discussion to a separate PR/issue if that's ok.

@yeikel yeikel force-pushed the issue/6804 branch 3 times, most recently from 33747af to 62d85c8 Compare April 17, 2023 13:48
@deivid-rodriguez
Copy link
Contributor

@yeikel This looks ready from my side and I'm pretty confident about it since you have taken the time to actually try this on a real registry, but I'm not super familiar with how private registries are setup in general, so let me ask for a second review here from another teammate just in case. Thanks!

Copy link
Contributor

@pavera pavera left a comment

Choose a reason for hiding this comment

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

LGTM

Co-authored-by: David Rodríguez <deivid.rodriguez@riseup.net>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
F: private-registries 💂‍♂️ Issues about using private registries with Dependabot; may be paired with an R: label. L: javascript:npm npm packages via npm L: javascript T: bug 🐞 Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[NPM] Registry inferring ignores the registry resource path
4 participants