Circumvention of attr_protected
There is a vulnerability in the attr_protected method in ActiveRecord. This vulnerability has been assigned the CVE
identifier CVE-2013-0276.
Versions Affected: All.
Not affected: Applications using attr_accessible
Fixed Versions: 3.2.12, 3.1.11, 2.3.17
Impact
------
The attr_protected method allows developers to specify a blacklist of model attributes which users should not be
allowed to assign to. By using a specially crafted request, attackers could circumvent this protection and alter
values that were meant to be protected.
All users running an affected release should either upgrade or use one of the work arounds immediately. Users should
also consider switching from attr_protected to the whitelist method attr_accessible which is not vulnerable to this
attack.
Releases
--------
The 3.2.12, 3.1.11, and 2.3.17 releases are available at the normal locations.
Workarounds
-----------
The only feasible work around for this issue is to convert the application to use attr_accessible instead of
attr_protected.
Patches
-------
To aid users who aren't able to upgrade immediately we have provided patches for the two supported release series.
They are in git-am format and consist of a single changeset.
* 3-2-attr_protected.patch - Patch for 3.2 series
* 3-1-attr_protected.patch - Patch for 3.1 series
* 3-0-attr_protected.patch - Patch for 3.0 series
* 2-3-attr_protected.patch - Patch for 2.3 series
Please note that only the 3.1.x and 3.2.x series are supported at present. Users of earlier unsupported releases are
advised to upgrade as soon as possible as we cannot guarantee the continued availability of security fixes for
unsupported releases.
Credits
-------
Thanks to joernchen of Phenoelit and Ryan Koppenhaver of Matasano Security for reporting the vulnerability to us and
working closely with us on a fix.
--
Aaron Patterson
http://tenderlovemaking.com/
2-3-attr_protected.patch
Description:
From 9a48f4cf329f66682c34c86822d625d63dbb6919 Mon Sep 17 00:00:00 2001
From: Aaron Patterson <aaron.patterson () gmail com>
Date: Sat, 9 Feb 2013 16:31:04 -0800
Subject: [PATCH] fixing attr_protected CVE-2013-0276
---
activerecord/lib/active_record/attribute_methods.rb | 2 +-
activerecord/lib/active_record/base.rb | 6 +++---
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/activerecord/lib/active_record/attribute_methods.rb b/activerecord/lib/active_record/attribute_methods.rb
index 22630b3..5f0ca58 100644
--- a/activerecord/lib/active_record/attribute_methods.rb
+++ b/activerecord/lib/active_record/attribute_methods.rb
@@ -130,7 +130,7 @@ module ActiveRecord
# Suffixes a, ?, c become regexp /(a|\?|c)$/
def rebuild_attribute_method_regexp
suffixes = attribute_method_suffixes.map { |s| Regexp.escape(s) }
- @@attribute_method_regexp = /(#{suffixes.join('|')})$/.freeze
+ @@attribute_method_regexp = /(#{suffixes.join('|')})\z/.freeze
end
# Default to =, ?, _before_type_cast
diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb
index cfc6e86..c11b702 100755
--- a/activerecord/lib/active_record/base.rb
+++ b/activerecord/lib/active_record/base.rb
@@ -2998,11 +2998,11 @@ module ActiveRecord #:nodoc:
def remove_attributes_protected_from_mass_assignment(attributes)
safe_attributes =
if self.class.accessible_attributes.nil? && self.class.protected_attributes.nil?
- attributes.reject { |key, value| attributes_protected_by_default.include?(key.gsub(/\(.+/, "")) }
+ attributes.reject { |key, value| attributes_protected_by_default.include?(key.gsub(/\(.+/m, "")) }
elsif self.class.protected_attributes.nil?
- attributes.reject { |key, value| !self.class.accessible_attributes.include?(key.gsub(/\(.+/, "")) || attributes_protected_by_default.include?(key.gsub(/\(.+/, "")) }
+ attributes.reject { |key, value| !self.class.accessible_attributes.include?(key.gsub(/\(.+/m, "")) || attributes_protected_by_default.include?(key.gsub(/\(.+/m, "")) }
elsif self.class.accessible_attributes.nil?
- attributes.reject { |key, value| self.class.protected_attributes.include?(key.gsub(/\(.+/,"")) || attributes_protected_by_default.include?(key.gsub(/\(.+/, "")) }
+ attributes.reject { |key, value| self.class.protected_attributes.include?(key.gsub(/\(.+/m,"")) || attributes_protected_by_default.include?(key.gsub(/\(.+/m, "")) }
else
raise "Declare either attr_protected or attr_accessible for #{self.class}, but not both."
end
--
1.8.1.1
3-0-attr_protected.patch
Description:
From 2dfd51247fcbfa14eb99ce8fd5537230a36c11f8 Mon Sep 17 00:00:00 2001
From: joernchen of Phenoelit <joernchen () phenoelit de>
Date: Sat, 9 Feb 2013 15:46:44 -0800
Subject: [PATCH] Fix issue with attr_protected where malformed input could
circumvent protection
Fixes: CVE-2013-0276
Conflicts:
activemodel/lib/active_model/attribute_methods.rb
activerecord/test/cases/mass_assignment_security_test.rb
---
activemodel/lib/active_model/attribute_methods.rb | 2 +-
activemodel/lib/active_model/mass_assignment_security/permission_set.rb | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/activemodel/lib/active_model/attribute_methods.rb b/activemodel/lib/active_model/attribute_methods.rb
index ba1b3ba..af6d27c 100644
--- a/activemodel/lib/active_model/attribute_methods.rb
+++ b/activemodel/lib/active_model/attribute_methods.rb
@@ -347,7 +347,7 @@ module ActiveModel
def initialize(options = {})
options.symbolize_keys!
@prefix, @suffix = options[:prefix] || '', options[:suffix] || ''
- @regex = /^(#{Regexp.escape(@prefix)})(.+?)(#{Regexp.escape(@suffix)})$/
+ @regex = /\A(#{Regexp.escape(@prefix)})(.+?)(#{Regexp.escape(@suffix)})\z/
end
def match(method_name)
diff --git a/activemodel/lib/active_model/mass_assignment_security/permission_set.rb b/activemodel/lib/active_model/mass_assignment_security/permission_set.rb
index 9fcb94d..7c7e5df 100644
--- a/activemodel/lib/active_model/mass_assignment_security/permission_set.rb
+++ b/activemodel/lib/active_model/mass_assignment_security/permission_set.rb
@@ -17,7 +17,7 @@ module ActiveModel
protected
def remove_multiparameter_id(key)
- key.to_s.gsub(/\(.+/, '')
+ key.to_s.gsub(/\(.+/m, '')
end
end
--
1.8.1.1
3-1-attr_protected.patch
Description:
From 647afdb5d2fce6aff4e85cb092de774b448e37c1 Mon Sep 17 00:00:00 2001
From: joernchen of Phenoelit <joernchen () phenoelit de>
Date: Sat, 9 Feb 2013 15:46:44 -0800
Subject: [PATCH] Fix issue with attr_protected where malformed input could
circumvent protection
Fixes: CVE-2013-0276
---
activemodel/lib/active_model/attribute_methods.rb | 2 +-
activemodel/lib/active_model/mass_assignment_security/permission_set.rb | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/activemodel/lib/active_model/attribute_methods.rb b/activemodel/lib/active_model/attribute_methods.rb
index fba5508..d23b53a 100644
--- a/activemodel/lib/active_model/attribute_methods.rb
+++ b/activemodel/lib/active_model/attribute_methods.rb
@@ -346,7 +346,7 @@ module ActiveModel
def initialize(options = {})
options.symbolize_keys!
@prefix, @suffix = options[:prefix] || '', options[:suffix] || ''
- @regex = /^(#{Regexp.escape(@prefix)})(.+?)(#{Regexp.escape(@suffix)})$/
+ @regex = /\A(#{Regexp.escape(@prefix)})(.+?)(#{Regexp.escape(@suffix)})\z/
@method_missing_target = "#{ () prefix}attribute#{@suffix}"
@method_name = "#{prefix}%s#{suffix}"
end
diff --git a/activemodel/lib/active_model/mass_assignment_security/permission_set.rb b/activemodel/lib/active_model/mass_assignment_security/permission_set.rb
index 9fcb94d..7c7e5df 100644
--- a/activemodel/lib/active_model/mass_assignment_security/permission_set.rb
+++ b/activemodel/lib/active_model/mass_assignment_security/permission_set.rb
@@ -17,7 +17,7 @@ module ActiveModel
protected
def remove_multiparameter_id(key)
- key.to_s.gsub(/\(.+/, '')
+ key.to_s.gsub(/\(.+/m, '')
end
end
--
1.8.1.1
3-2-attr_protected.patch
Description:
From 060bb7250b963609a0d8a5d0559e36b99d2402c6 Mon Sep 17 00:00:00 2001
From: joernchen of Phenoelit <joernchen () phenoelit de>
Date: Sat, 9 Feb 2013 15:46:44 -0800
Subject: [PATCH] Fix issue with attr_protected where malformed input could
circumvent protection
Fixes: CVE-2013-0276
---
activemodel/lib/active_model/attribute_methods.rb | 2 +-
activemodel/lib/active_model/mass_assignment_security/permission_set.rb | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/activemodel/lib/active_model/attribute_methods.rb b/activemodel/lib/active_model/attribute_methods.rb
index f033a94..96f2c82 100644
--- a/activemodel/lib/active_model/attribute_methods.rb
+++ b/activemodel/lib/active_model/attribute_methods.rb
@@ -365,7 +365,7 @@ module ActiveModel
end
@prefix, @suffix = options[:prefix] || '', options[:suffix] || ''
- @regex = /^(#{Regexp.escape(@prefix)})(.+?)(#{Regexp.escape(@suffix)})$/
+ @regex = /\A(#{Regexp.escape(@prefix)})(.+?)(#{Regexp.escape(@suffix)})\z/
@method_missing_target = "#{ () prefix}attribute#{@suffix}"
@method_name = "#{prefix}%s#{suffix}"
end
diff --git a/activemodel/lib/active_model/mass_assignment_security/permission_set.rb b/activemodel/lib/active_model/mass_assignment_security/permission_set.rb
index a1fcdf1..10faa29 100644
--- a/activemodel/lib/active_model/mass_assignment_security/permission_set.rb
+++ b/activemodel/lib/active_model/mass_assignment_security/permission_set.rb
@@ -19,7 +19,7 @@ module ActiveModel
protected
def remove_multiparameter_id(key)
- key.to_s.gsub(/\(.+/, '')
+ key.to_s.gsub(/\(.+/m, '')
end
end
--
1.8.1.1