Openwall GNU/*/Linux - a small security-enhanced Linux distro for servers
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date: Mon, 9 Sep 2013 22:32:25 -0700
From: Eric Hodel <>
To: Operating system distro security contacts <>,
 "" <>
Subject: CVE-2013-4287 Algorithmic complexity vulnerability in RubyGems 2.0.7 and older

RubyGems validates versions with a regular expression that is vulnerable to
denial of service due to backtracking.  For specially crafted RubyGems
versions attackers can cause denial of service through CPU consumption.

RubyGems versions 2.0.7 and older, 2.1.0.rc.1 and 2.1.0.rc.2 are vulnerable.

Ruby versions 1.9.0 through 2.0.0p247 are vulnerable as they contain embedded
versions of RubyGems.

It does not appear to be possible to exploit this vulnerability by installing a
gem for RubyGems 1.8.x or 2.0.x.  Vulnerable uses of RubyGems API include
packaging a gem (through `gem build`, Gem::Package or Gem::PackageTask),
sending user input to, Gem::Version.correct? or use of the

Notably, users of bundler that install gems from git are vulnerable if a
malicious author changes the gemspec to an invalid version.

The vulnerability can be fixed by changing the first grouping to an atomic
grouping in Gem::Version::VERSION_PATTERN in lib/rubygems/version.rb.  For
RubyGems 2.0.x:

  -  VERSION_PATTERN = '[0-9]+(\.[0-9a-zA-Z]+)*(-[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?' # :nodoc:
  +  VERSION_PATTERN = '[0-9]+(?>\.[0-9a-zA-Z]+)*(-[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?' # :nodoc:

For RubyGems 1.8.x:

  -  VERSION_PATTERN = '[0-9]+(\.[0-9a-zA-Z]+)*' # :nodoc:
  +  VERSION_PATTERN = '[0-9]+(?>\.[0-9a-zA-Z]+)*' # :nodoc:

This vulnerability was discovered by Damir Sharipov <>

The above information is also posted at:

Patches were committed for:

RubyGems 2.1.0.rc.2, released as RubyGems 2.1.0:

RubyGems 2.0.7, released as RubyGems 2.0.8:

RubyGems 1.8.25, released as RubyGems 1.8.26:

RubyGems 1.8.23, released as RubyGems

The following program can be used to test if you are vulnerable to CVE-2013-4287:

require 'benchmark'
require 'rubygems'

valid = Benchmark.measure do '1.22.333.4444.55555.666666.7777777'

puts 'Valid version time:'
puts valid

invalid = Benchmark.measure do
  begin '1.22.333.4444.55555.666666.7777777.'

puts 'Invalid version time:'
puts invalid

n = (valid.real - invalid.real).abs

if 0.1 < n then
  puts 'You are vulnerable to CVE-2013-4287.'
  puts 'You are NOT vulnerable to CVE-2013-4287.'

Powered by blists - more mailing lists

Please check out the Open Source Software Security Wiki, which is counterpart to this mailing list.

Powered by Openwall GNU/*/Linux - Powered by OpenVZ