Package: release.debian.org User: release.debian....@packages.debian.org X-Debbugs-Cc: debian-r...@lists.debian.org Usertags: pu Tags: buster Severity: normal
Hello, ruby-mechanize was affected by CVE-2021-21289, where the package was vulnerable to command injection vulnerability. This has been fixed in sid, bullseye, and stretch. Here's the debdiff for buster-pu: 8<------8<------8<------8<------8<------8<------8<------8<------8<------8< diff -Nru ruby-mechanize-2.7.6/debian/changelog ruby-mechanize-2.7.6/debian/changelog --- ruby-mechanize-2.7.6/debian/changelog 2019-01-04 16:57:45.000000000 +0530 +++ ruby-mechanize-2.7.6/debian/changelog 2021-02-19 22:47:27.000000000 +0530 @@ -1,3 +1,10 @@ +ruby-mechanize (2.7.6-1+deb10u1) buster; urgency=medium + + * Team upload for buster-pu. + * Add patch to prevent OS command injection. (Fixes: CVE-2021-21289) + + -- Utkarsh Gupta <utka...@debian.org> Fri, 19 Feb 2021 22:47:27 +0530 + ruby-mechanize (2.7.6-1) unstable; urgency=medium * Team upload diff -Nru ruby-mechanize-2.7.6/debian/patches/CVE-2021-21289.patch ruby-mechanize-2.7.6/debian/patches/CVE-2021-21289.patch --- ruby-mechanize-2.7.6/debian/patches/CVE-2021-21289.patch 1970-01-01 05:30:00.000000000 +0530 +++ ruby-mechanize-2.7.6/debian/patches/CVE-2021-21289.patch 2021-02-19 22:46:52.000000000 +0530 @@ -0,0 +1,260 @@ +From aae0b13514a1a0caf93b1cf233733c50e679069a Mon Sep 17 00:00:00 2001 +From: Katsuhiko YOSHIDA <clad...@gmail.com> +Date: Sat, 20 Jul 2019 11:03:40 +0900 +Subject: [PATCH 1/7] fix(security): prevent command injection in CookieJar + +Related to https://github.com/sparklemotion/mechanize/security/advisories/GHSA-qrqm-fpv6-6r8g +--- + lib/mechanize/cookie_jar.rb | 4 ++-- + test/test_mechanize_cookie_jar.rb | 30 ++++++++++++++++++++++++++++++ + 2 files changed, 32 insertions(+), 2 deletions(-) + +--- a/lib/mechanize/cookie_jar.rb ++++ b/lib/mechanize/cookie_jar.rb +@@ -65,7 +65,7 @@ + class CookieJar < ::HTTP::CookieJar + def save(output, *options) + output.respond_to?(:write) or +- return open(output, 'w') { |io| save(io, *options) } ++ return ::File.open(output, 'w') { |io| save(io, *options) } + + opthash = { + :format => :yaml, +@@ -119,7 +119,7 @@ + + def load(input, *options) + input.respond_to?(:write) or +- return open(input, 'r') { |io| load(io, *options) } ++ return ::File.open(input, 'r') { |io| load(io, *options) } + + opthash = { + :format => :yaml, +--- a/test/test_mechanize_cookie_jar.rb ++++ b/test/test_mechanize_cookie_jar.rb +@@ -1,4 +1,5 @@ + require 'mechanize/test_case' ++require 'fileutils' + + class TestMechanizeCookieJar < Mechanize::TestCase + +@@ -500,6 +501,35 @@ + assert_equal(0, @jar.cookies(url).length) + end + ++ def test_prevent_command_injection_when_saving ++ url = URI 'http://rubygems.org/' ++ path = '| ruby -rfileutils -e \'FileUtils.touch("vul.txt")\'' ++ ++ @jar.add(url, Mechanize::Cookie.new(cookie_values)) ++ ++ in_tmpdir do ++ @jar.save_as(path, :cookiestxt) ++ assert_equal(false, File.exist?('vul.txt')) ++ end ++ end ++ ++ def test_prevent_command_injection_when_loading ++ url = URI 'http://rubygems.org/' ++ path = '| ruby -rfileutils -e \'FileUtils.touch("vul.txt")\'' ++ ++ @jar.add(url, Mechanize::Cookie.new(cookie_values)) ++ ++ in_tmpdir do ++ @jar.save_as("cookies.txt", :cookiestxt) ++ @jar.clear! ++ ++ assert_raises Errno::ENOENT do ++ @jar.load(path, :cookiestxt) ++ end ++ assert_equal(false, File.exist?('vul.txt')) ++ end ++ end ++ + def test_save_and_read_expired_cookies + url = URI 'http://rubyforge.org/' + +--- a/lib/mechanize.rb ++++ b/lib/mechanize.rb +@@ -396,7 +396,7 @@ + io = if io_or_filename.respond_to? :write then + io_or_filename + else +- open io_or_filename, 'wb' ++ ::File.open(io_or_filename, 'wb') + end + + case page +--- a/test/test_mechanize.rb ++++ b/test/test_mechanize.rb +@@ -345,6 +345,14 @@ + end + end + ++ def test_download_does_not_allow_command_injection ++ in_tmpdir do ++ @mech.download('http://example', '| ruby -rfileutils -e \'FileUtils.touch("vul.txt")\'') ++ ++ refute_operator(File, :exist?, "vul.txt") ++ end ++ end ++ + def test_get + uri = URI 'http://localhost' + +--- a/lib/mechanize/download.rb ++++ b/lib/mechanize/download.rb +@@ -71,7 +71,7 @@ + dirname = File.dirname filename + FileUtils.mkdir_p dirname + +- open filename, 'wb' do |io| ++ ::File.open(filename, 'wb')do |io| + until @body_io.eof? do + io.write @body_io.read 16384 + end +--- a/test/test_mechanize_download.rb ++++ b/test/test_mechanize_download.rb +@@ -46,6 +46,18 @@ + end + end + ++ def test_save_bang_does_not_allow_command_injection ++ uri = URI.parse 'http://example/foo.html' ++ body_io = StringIO.new '0123456789' ++ ++ download = @parser.new uri, nil, body_io ++ ++ in_tmpdir do ++ download.save!('| ruby -rfileutils -e \'FileUtils.touch("vul.txt")\'') ++ refute_operator(File, :exist?, "vul.txt") ++ end ++ end ++ + def test_save_tempfile + uri = URI.parse 'http://example/foo.html' + Tempfile.open @NAME do |body_io| +@@ -84,6 +96,5 @@ + + assert_equal "foo.html", download.filename + end +- + end + +--- a/lib/mechanize/file.rb ++++ b/lib/mechanize/file.rb +@@ -82,7 +82,7 @@ + dirname = File.dirname filename + FileUtils.mkdir_p dirname + +- open filename, 'wb' do |f| ++ ::File.open(filename, 'wb')do |f| + f.write body + end + +--- a/test/test_mechanize_file.rb ++++ b/test/test_mechanize_file.rb +@@ -103,5 +103,14 @@ + end + end + ++ def test_save_bang_does_not_allow_command_injection ++ uri = URI 'http://example/test.html' ++ page = Mechanize::File.new uri, nil, '' ++ ++ in_tmpdir do ++ page.save!('| ruby -rfileutils -e \'FileUtils.touch("vul.txt")\'') ++ refute_operator(File, :exist?, "vul.txt") ++ end ++ end + end + +--- a/lib/mechanize/file_response.rb ++++ b/lib/mechanize/file_response.rb +@@ -15,7 +15,7 @@ + if directory? + yield dir_body + else +- open @file_path, 'rb' do |io| ++ ::File.open(@file_path, 'rb') do |io| + yield io.read + end + end +--- a/test/test_mechanize_file_response.rb ++++ b/test/test_mechanize_file_response.rb +@@ -1,7 +1,6 @@ + require 'mechanize/test_case' + + class TestMechanizeFileResponse < Mechanize::TestCase +- + def test_content_type + Tempfile.open %w[pi .nothtml] do |tempfile| + res = Mechanize::FileResponse.new tempfile.path +@@ -19,5 +18,24 @@ + end + end + +-end ++ def test_read_body ++ Tempfile.open %w[pi .html] do |tempfile| ++ tempfile.write("asdfasdfasdf") ++ tempfile.close + ++ res = Mechanize::FileResponse.new(tempfile.path) ++ res.read_body do |input| ++ assert_equal("asdfasdfasdf", input) ++ end ++ end ++ end ++ ++ def test_read_body_does_not_allow_command_injection ++ in_tmpdir do ++ FileUtils.touch('| ruby -rfileutils -e \'FileUtils.touch("vul.txt")\'') ++ res = Mechanize::FileResponse.new('| ruby -rfileutils -e \'FileUtils.touch("vul.txt")\'') ++ res.read_body { |_| } ++ refute_operator(File, :exist?, "vul.txt") ++ end ++ end ++end +--- a/lib/mechanize/test_case.rb ++++ b/lib/mechanize/test_case.rb +@@ -235,9 +235,9 @@ + else + filename = "htdocs#{path.gsub(/[^\/\\.\w\s]/, '_')}" + unless PAGE_CACHE[filename] +- open("#{Mechanize::TestCase::TEST_DIR}/#{filename}", 'rb') { |io| ++ ::File.open("#{Mechanize::TestCase::TEST_DIR}/#{filename}", 'rb') do |io| + PAGE_CACHE[filename] = io.read +- } ++ end + end + + res.body = PAGE_CACHE[filename] +--- a/lib/mechanize/test_case/gzip_servlet.rb ++++ b/lib/mechanize/test_case/gzip_servlet.rb +@@ -15,7 +15,7 @@ + end + + if name = req.query['file'] then +- open "#{TEST_DIR}/htdocs/#{name}" do |io| ++ ::File.open("#{TEST_DIR}/htdocs/#{name}") do |io| + string = "" + zipped = StringIO.new string, 'w' + Zlib::GzipWriter.wrap zipped do |gz| +--- a/lib/mechanize/test_case/verb_servlet.rb ++++ b/lib/mechanize/test_case/verb_servlet.rb +@@ -1,11 +1,9 @@ + class VerbServlet < WEBrick::HTTPServlet::AbstractServlet + %w[HEAD GET POST PUT DELETE].each do |verb| +- eval <<-METHOD +- def do_#{verb}(req, res) +- res.header['X-Request-Method'] = #{verb.dump} +- res.body = #{verb.dump} +- end +- METHOD ++ define_method "do_#{verb}" do |req, res| ++ res.header['X-Request-Method'] = verb ++ res.body = verb ++ end + end + end + diff -Nru ruby-mechanize-2.7.6/debian/patches/series ruby-mechanize-2.7.6/debian/patches/series --- ruby-mechanize-2.7.6/debian/patches/series 2019-01-04 16:57:45.000000000 +0530 +++ ruby-mechanize-2.7.6/debian/patches/series 2021-02-19 22:46:49.000000000 +0530 @@ -1,3 +1,4 @@ dont_require_rubygems set_path_for_test 0003-Replace-dep-on-ntlm-http-by-rubyntlm.patch +CVE-2021-21289.patch 8<------8<------8<------8<------8<------8<------8<------8<------8<------8< - u