Skip to content

Commit ed733bc

Browse files
committed
Fix CVE-2013-4287, remove regexp backtracking
The Gem::Version regexp used backtracking to validate gem versions. This could cause excessive CPU usage when creating Gem::Version objects including when packaging gems. See CVE-2013-4287.txt (in this commit) for details. Fixes #626
1 parent 05e9e55 commit ed733bc

File tree

5 files changed

+48
-2
lines changed

5 files changed

+48
-2
lines changed

CVE-2013-4287.txt

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
= Algorithmic complexity vulnerability in RubyGems 2.0.7 and older
2+
3+
RubyGems validates versions with a regular expression that is vulnerable to
4+
denial of service due to a backtracking regular expression. For specially
5+
crafted RubyGems versions attackers can cause denial of service through CPU
6+
consumption.
7+
8+
RubyGems versions 2.0.7 and older, 2.1.0.rc.1 and 2.1.0.rc.2 are vulnerable.
9+
10+
Ruby versions 1.9.0 through 2.0.0p247 are vulnerable as they contain embedded
11+
versions of RubyGems.
12+
13+
It does not appear to be possible to exploit this vulnerability by installing a
14+
gem for RubyGems 1.8.x or 2.0.x. Vulnerable uses of RubyGems API include
15+
packaging a gem (through `gem build`, Gem::Package or Gem::PackageTask),
16+
sending user input to Gem::Version.new, Gem::Version.correct? or use of the
17+
Gem::Version::VERSION_PATTERN or Gem::Version::ANCHORED_VERSION_PATTERN
18+
constants.
19+
20+
Notably, users of bundler that install gems from git are vulnerable if a
21+
malicious author changes the gemspec to an invalid version.
22+
23+
The vulnerability can be fixed by changing the first grouping to an atomic
24+
grouping in Gem::Version::VERSION_PATTERN in lib/rubygems/version.rb. For
25+
RubyGems 2.0.x:
26+
27+
- VERSION_PATTERN = '[0-9]+(\.[0-9a-zA-Z]+)*(-[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?' # :nodoc:
28+
+ VERSION_PATTERN = '[0-9]+(?>\.[0-9a-zA-Z]+)*(-[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?' # :nodoc:
29+
30+
For RubyGems 1.8.x:
31+
32+
- VERSION_PATTERN = '[0-9]+(\.[0-9a-zA-Z]+)*' # :nodoc:
33+
+ VERSION_PATTERN = '[0-9]+(?>\.[0-9a-zA-Z]+)*' # :nodoc:
34+
35+
This vulnerability was discovered by Damir Sharipov <dammer2k@gmail.com>
36+

History.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@
22

33
=== 1.8.26
44

5+
Security fixes:
6+
7+
* RubyGems 2.0.7 and earlier are vulnerable to excessive CPU usage due to a
8+
backtracking in Gem::Version validation. See CVE-2013-4287 for full details
9+
including vulnerable APIs. Fixed versions include 2.0.8, 1.8.26 and
10+
1.8.23.1 (for Ruby 1.9.3). Issue #626 by Damir Sharipov.
11+
512
Bug fixes:
613

714
* Fixed editing of a Makefile with 8-bit characters. Fixes #181

Manifest.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
.autotest
22
.document
3+
CVE-2013-4287.txt
34
History.txt
45
LICENSE.txt
56
MIT.txt

Rakefile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,9 @@ hoe = Hoe.spec 'rubygems-update' do
5353
extra_dev_deps << ['rcov', '~> 0.9.0']
5454
extra_dev_deps << ['ZenTest', '~> 4.5']
5555

56-
self.extra_rdoc_files = Dir["*.rdoc"]
56+
self.extra_rdoc_files = Dir["*.rdoc"] + %w[
57+
CVE-2013-4287.txt
58+
]
5759

5860
spec_extras['rdoc_options'] = proc do |rdoc_options|
5961
rdoc_options << "--title=RubyGems #{self.version} Documentation"

lib/rubygems/version.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ class Gem::Version
145145

146146
include Comparable
147147

148-
VERSION_PATTERN = '[0-9]+(\.[0-9a-zA-Z]+)*' # :nodoc:
148+
VERSION_PATTERN = '[0-9]+(?>\.[0-9a-zA-Z]+)*' # :nodoc:
149149
ANCHORED_VERSION_PATTERN = /\A\s*(#{VERSION_PATTERN})*\s*\z/ # :nodoc:
150150

151151
##

0 commit comments

Comments
 (0)