Skip to content

Commit 7fa6707

Browse files
Merge pull request #5142 from rubygems/local_code_execution
Pass "--" to git commands to separate positional and optional args (cherry picked from commit 6a655a6)
1 parent 02f0d40 commit 7fa6707

File tree

2 files changed

+26
-6
lines changed

2 files changed

+26
-6
lines changed

bundler/lib/bundler/source/git/git_proxy.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,12 +95,12 @@ def checkout
9595
SharedHelpers.filesystem_access(path.dirname) do |p|
9696
FileUtils.mkdir_p(p)
9797
end
98-
git_retry "clone", configured_uri, path.to_s, "--bare", "--no-hardlinks", "--quiet"
98+
git_retry "clone", "--bare", "--no-hardlinks", "--quiet", "--", configured_uri, path.to_s
9999
return unless extra_ref
100100
end
101101

102102
with_path do
103-
git_retry(*["fetch", "--force", "--quiet", "--tags", configured_uri, "refs/heads/*:refs/heads/*", extra_ref].compact, :dir => path)
103+
git_retry(*["fetch", "--force", "--quiet", "--tags", "--", configured_uri, "refs/heads/*:refs/heads/*", extra_ref].compact, :dir => path)
104104
end
105105
end
106106

bundler/spec/bundler/source/git/git_proxy_spec.rb

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,21 @@
1111
context "with configured credentials" do
1212
it "adds username and password to URI" do
1313
Bundler.settings.temporary(uri => "u:p") do
14-
expect(subject).to receive(:git_retry).with("clone", "https://u:[email protected]/rubygems/rubygems.git", any_args)
14+
expect(subject).to receive(:git_retry).with("clone", "--bare", "--no-hardlinks", "--quiet", "--", "https://u:[email protected]/rubygems/rubygems.git", path.to_s)
1515
subject.checkout
1616
end
1717
end
1818

1919
it "adds username and password to URI for host" do
2020
Bundler.settings.temporary("github.com" => "u:p") do
21-
expect(subject).to receive(:git_retry).with("clone", "https://u:[email protected]/rubygems/rubygems.git", any_args)
21+
expect(subject).to receive(:git_retry).with("clone", "--bare", "--no-hardlinks", "--quiet", "--", "https://u:[email protected]/rubygems/rubygems.git", path.to_s)
2222
subject.checkout
2323
end
2424
end
2525

2626
it "does not add username and password to mismatched URI" do
2727
Bundler.settings.temporary("https://u:[email protected]/rubygems/rubygems-mismatch.git" => "u:p") do
28-
expect(subject).to receive(:git_retry).with("clone", uri, any_args)
28+
expect(subject).to receive(:git_retry).with("clone", "--bare", "--no-hardlinks", "--quiet", "--", uri, path.to_s)
2929
subject.checkout
3030
end
3131
end
@@ -34,7 +34,7 @@
3434
Bundler.settings.temporary("github.com" => "u:p") do
3535
original = "https://orig:[email protected]/rubygems/rubygems.git"
3636
subject = described_class.new(Pathname("path"), original, "HEAD")
37-
expect(subject).to receive(:git_retry).with("clone", original, any_args)
37+
expect(subject).to receive(:git_retry).with("clone", "--bare", "--no-hardlinks", "--quiet", "--", original, path.to_s)
3838
subject.checkout
3939
end
4040
end
@@ -148,4 +148,24 @@
148148
end
149149
end
150150
end
151+
152+
it "doesn't allow arbitrary code execution through Gemfile uris with a leading dash" do
153+
gemfile <<~G
154+
gem "poc", git: "-u./pay:load.sh"
155+
G
156+
157+
file = bundled_app("pay:load.sh")
158+
159+
create_file file, <<~RUBY
160+
#!/bin/sh
161+
162+
touch #{bundled_app("canary")}
163+
RUBY
164+
165+
FileUtils.chmod("+x", file)
166+
167+
bundle :lock, :raise_on_error => false
168+
169+
expect(Pathname.new(bundled_app("canary"))).not_to exist
170+
end
151171
end

0 commit comments

Comments
 (0)