CVE-2017-0899: Improper Control of Generation of Code ('Code Injection') (CWE-94)
value: RubyGems version 2.6.12 and earlier is vulnerable to maliciously crafted gem specifications that include terminal escape characters. Printing the gem specification would execute terminal escape sequences.
CWE description: The product constructs all or part of a code segment using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the syntax or behavior of the intended code segment.
CVSS v3 base score: 9.8
Published: 2017-08-31T20:29Z
Repository: https://github.com/rubygems/rubygems
Language: Ruby
Files changed: lib/rubygems/text.rb, test/rubygems/test_gem_commands_query_command.rb, test/rubygems/test_gem_text.rb
Commit date: 2017-08-27 20:37:15 -0500
Commit message: Use a pattern that works on 1.8.7

Diff: diff --git a/lib/rubygems/text.rb b/lib/rubygems/text.rb
index edb76340a..19c78eff1 100644
--- a/lib/rubygems/text.rb
+++ b/lib/rubygems/text.rb
@@ -8,11 +8,11 @@ module Gem::Text
 
   ##
   # Remove any non-printable characters and make the text suitable for
   # printing.
   def clean_text(text)
-    text.gsub(/[\u0000-\u0008\u000b-\u000c\u000e-\u001F\u007f]/, ".".freeze)
+    text.gsub(/[\000-\b\v-\f\016-\037\177]/, ".".freeze)
   end
 
   ##
   # Wraps +text+ to +wrap+ characters and optionally indents by +indent+
   # characters
diff --git a/test/rubygems/test_gem_commands_query_command.rb b/test/rubygems/test_gem_commands_query_command.rb
index 2a87601cb..d55b56555 100644
--- a/test/rubygems/test_gem_commands_query_command.rb
+++ b/test/rubygems/test_gem_commands_query_command.rb
@@ -130,12 +130,12 @@ def test_execute_details
 
   def test_execute_details_cleans_text
     spec_fetcher do |fetcher|
       fetcher.spec 'a', 2 do |s|
         s.summary = 'This is a lot of text. ' * 4
-        s.authors = ["Abraham Lincoln \u0001", "\u0002 Hirohito"]
-        s.homepage = "http://a.example.com/\u0003"
+        s.authors = ["Abraham Lincoln \x01", "\x02 Hirohito"]
+        s.homepage = "http://a.example.com/\x03"
       end
 
       fetcher.legacy_platform
     end
 
diff --git a/test/rubygems/test_gem_text.rb b/test/rubygems/test_gem_text.rb
index 4875f37cf..4168931e0 100644
--- a/test/rubygems/test_gem_text.rb
+++ b/test/rubygems/test_gem_text.rb
@@ -35,11 +35,11 @@ def test_format_text_trailing # for two spaces after .
 
     assert_equal expected, format_text(text, 78)
   end
 
   def test_format_removes_nonprintable_characters
-    assert_equal "text with weird .. stuff", format_text("text with weird \u001b\u0002 stuff", 40)
+    assert_equal "text with weird .. stuff .", format_text("text with weird \x1b\x02 stuff \x7f", 40)
   end
 
   def test_min3
     assert_equal 1, min3(1, 1, 1)
     assert_equal 1, min3(1, 1, 2)

Vulnerable code:     text.gsub(/[\u0000-\u0008\u000b-\u000c\u000e-\u001F\u007f]/, ".".freeze)
        s.authors = ["Abraham Lincoln \u0001", "\u0002 Hirohito"]
        s.homepage = "http://a.example.com/\u0003"
    assert_equal "text with weird .. stuff", format_text("text with weird \u001b\u0002 stuff", 40)
Fixed code:     text.gsub(/[\000-\b\v-\f\016-\037\177]/, ".".freeze)
        s.authors = ["Abraham Lincoln \x01", "\x02 Hirohito"]
        s.homepage = "http://a.example.com/\x03"
    assert_equal "text with weird .. stuff .", format_text("text with weird \x1b\x02 stuff \x7f", 40)