Skip to content

Commit 403d674

Browse files
junarugahsbt
authored andcommitted
Print a warning for a potential confusion from the indirect dependencies.
Print a warning when a confusion by the indirect dependencies may happen. See CVE-2020-36327 for the security risk.
1 parent a3ad90f commit 403d674

2 files changed

Lines changed: 76 additions & 1 deletion

File tree

bundler/lib/bundler/definition.rb

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -777,7 +777,27 @@ def start_resolution
777777
end
778778

779779
def precompute_source_requirements_for_indirect_dependencies?
780-
sources.non_global_rubygems_sources.all?(&:dependency_api_available?)
780+
return false unless @remote && !sources.aggregate_global_source?
781+
782+
if sources.non_global_rubygems_sources.all?(&:dependency_api_available?)
783+
true
784+
else
785+
non_dependency_api_warning
786+
false
787+
end
788+
end
789+
790+
def non_dependency_api_warning
791+
non_api_sources = sources.non_global_rubygems_sources.reject(&:dependency_api_available?)
792+
non_api_source_names = non_api_sources.map {|d| " * #{d}" }.join("\n")
793+
794+
msg = String.new
795+
msg << "Your Gemfile contains scoped sources that don't implement a dependency API, namely:\n\n"
796+
msg << non_api_source_names
797+
msg << "\n\nUsing the above gem servers may result in installing unexpected gems. " \
798+
"To resolve this warning, make sure you use gem servers that implement dependency APIs, " \
799+
"such as gemstash or geminabox gem servers."
800+
Bundler.ui.warn msg
781801
end
782802

783803
def current_platform_locked?

spec/bundler/definition_spec.rb

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,61 @@
289289
end
290290
end
291291

292+
describe "#precompute_source_requirements_for_indirect_dependencies?" do
293+
before do
294+
allow(Bundler::SharedHelpers).to receive(:find_gemfile) { Pathname.new("Gemfile") }
295+
end
296+
297+
let(:sources) { Bundler::SourceList.new }
298+
subject { Bundler::Definition.new(nil, [], sources, []) }
299+
300+
context "when remote and does not have multiple global sources" do
301+
before do
302+
subject.instance_variable_set(:@remote, true)
303+
allow(sources).to receive(:aggregate_global_source?).and_return(false)
304+
allow(sources).to receive(:non_global_rubygems_sources).and_return(non_global_rubygems_sources)
305+
end
306+
307+
context "when all the scoped sources contain a dependency API" do
308+
let(:non_global_rubygems_sources) do
309+
[
310+
double("non-global-source-0", :dependency_api_available? => true, :to_s => "a"),
311+
double("non-global-source-1", :dependency_api_available? => true, :to_s => "b"),
312+
]
313+
end
314+
315+
it "will not raise a warning" do
316+
expect(subject).not_to receive(:non_dependency_api_warning)
317+
318+
expect(subject.send(:precompute_source_requirements_for_indirect_dependencies?)).to be_truthy
319+
end
320+
end
321+
322+
context "when scoped sources do not contain a dependency API" do
323+
let(:non_global_rubygems_sources) do
324+
[
325+
double("non-global-source-0", :dependency_api_available? => true, :to_s => "a"),
326+
double("non-global-source-1", :dependency_api_available? => false, :to_s => "b"),
327+
double("non-global-source-2", :dependency_api_available? => false, :to_s => "c"),
328+
]
329+
end
330+
331+
it "will raise a warning" do
332+
expect(Bundler.ui).to receive(:warn).with(<<-W.strip)
333+
Your Gemfile contains scoped sources that don't implement a dependency API, namely:
334+
335+
* b
336+
* c
337+
338+
Using the above gem servers may result in installing unexpected gems. To resolve this warning, make sure you use gem servers that implement dependency APIs, such as gemstash or geminabox gem servers.
339+
W
340+
341+
expect(subject.send(:precompute_source_requirements_for_indirect_dependencies?)).to be_falsy
342+
end
343+
end
344+
end
345+
end
346+
292347
def mock_source_list
293348
Class.new do
294349
def all_sources

0 commit comments

Comments
 (0)