mirror of
https://github.com/github/rails.git
synced 2026-01-09 14:48:01 -05:00
Merge branch '3-2-13' into 3-2-stable
* 3-2-13: bumping to 3.2.13 fix protocol checking in sanitization [CVE-2013-1857] JDOM XXE Protection [CVE-2013-1856] fix incorrect ^$ usage leading to XSS in sanitize_css [CVE-2013-1855] stop calling to_sym when building arel nodes [CVE-2013-1854] Merge pull request #9616 from exviva/multiple_select_name_double_square_brackets bumping to rc2 Revert "Merge pull request #8209 from senny/backport_8176" Freeze columns only once per Result Preparing for 3.2.13.rc1 release Update CHANGELOGs for 3.2.13 release. Conflicts: actionmailer/CHANGELOG.md actionpack/CHANGELOG.md activemodel/CHANGELOG.md activeresource/CHANGELOG.md activesupport/CHANGELOG.md railties/CHANGELOG.md
This commit is contained in:
@@ -1 +1 @@
|
||||
3.2.12
|
||||
3.2.13
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* No changes.
|
||||
|
||||
|
||||
## Rails 3.2.13.rc1 (Feb 17, 2013) ##
|
||||
## Rails 3.2.13 ##
|
||||
|
||||
* No changes.
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ module ActionMailer
|
||||
module VERSION #:nodoc:
|
||||
MAJOR = 3
|
||||
MINOR = 2
|
||||
TINY = 12
|
||||
TINY = 13
|
||||
PRE = nil
|
||||
|
||||
STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
|
||||
|
||||
@@ -4,6 +4,10 @@
|
||||
Fixes GH#3512.
|
||||
|
||||
*Juan Barreneche*
|
||||
* No changes.
|
||||
|
||||
|
||||
## Rails 3.2.13 ##
|
||||
|
||||
* Fix incorrectly appended square brackets to a multiple select box
|
||||
if an explicit name has been given and it already ends with "[]".
|
||||
@@ -22,6 +26,7 @@
|
||||
|
||||
*Olek Janiszewski*
|
||||
|
||||
<<<<<<< HEAD
|
||||
* Fix `ActionDispatch::Request#formats` when the Accept request-header is an
|
||||
empty string. Fix #7774 [Backport #8977, #9541]
|
||||
|
||||
@@ -29,6 +34,8 @@
|
||||
|
||||
## Rails 3.2.13.rc1 (Feb 17, 2013) ##
|
||||
|
||||
=======
|
||||
>>>>>>> 3-2-13
|
||||
* Determine the controller#action from only the matched path when using the
|
||||
shorthand syntax. Previously the complete path was used, which led
|
||||
to problems with nesting (scopes and namespaces).
|
||||
|
||||
@@ -66,7 +66,7 @@ module HTML
|
||||
|
||||
# A regular expression of the valid characters used to separate protocols like
|
||||
# the ':' in 'http://foo.com'
|
||||
self.protocol_separator = /:|(�*58)|(p)|(%|%)3A/
|
||||
self.protocol_separator = /:|(�*58)|(p)|(�*3a)|(%|%)3A/i
|
||||
|
||||
# Specifies a Set of HTML attributes that can have URIs.
|
||||
self.uri_attributes = Set.new(%w(href src cite action longdesc xlink:href lowsrc))
|
||||
@@ -110,8 +110,8 @@ module HTML
|
||||
style = style.to_s.gsub(/url\s*\(\s*[^\s)]+?\s*\)\s*/, ' ')
|
||||
|
||||
# gauntlet
|
||||
if style !~ /^([:,;#%.\sa-zA-Z0-9!]|\w-\w|\'[\s\w]+\'|\"[\s\w]+\"|\([\d,\s]+\))*$/ ||
|
||||
style !~ /^(\s*[-\w]+\s*:\s*[^:;]*(;|$)\s*)*$/
|
||||
if style !~ /\A([:,;#%.\sa-zA-Z0-9!]|\w-\w|\'[\s\w]+\'|\"[\s\w]+\"|\([\d,\s]+\))*\z/ ||
|
||||
style !~ /\A(\s*[-\w]+\s*:\s*[^:;]*(;|$)\s*)*\z/
|
||||
return ''
|
||||
end
|
||||
|
||||
@@ -122,7 +122,7 @@ module HTML
|
||||
elsif shorthand_css_properties.include?(prop.split('-')[0].downcase)
|
||||
unless val.split().any? do |keyword|
|
||||
!allowed_css_keywords.include?(keyword) &&
|
||||
keyword !~ /^(#[0-9a-f]+|rgb\(\d+%?,\d*%?,?\d*%?\)?|\d{0,2}\.?\d{0,2}(cm|em|ex|in|mm|pc|pt|px|%|,|\))?)$/
|
||||
keyword !~ /\A(#[0-9a-f]+|rgb\(\d+%?,\d*%?,?\d*%?\)?|\d{0,2}\.?\d{0,2}(cm|em|ex|in|mm|pc|pt|px|%|,|\))?)\z/
|
||||
end
|
||||
clean << prop + ': ' + val + ';'
|
||||
end
|
||||
@@ -171,7 +171,7 @@ module HTML
|
||||
|
||||
def contains_bad_protocols?(attr_name, value)
|
||||
uri_attributes.include?(attr_name) &&
|
||||
(value =~ /(^[^\/:]*):|(�*58)|(p)|(%|%)3A/ && !allowed_protocols.include?(value.split(protocol_separator).first.downcase))
|
||||
(value =~ /(^[^\/:]*):|(�*58)|(p)|(�*3a)|(%|%)3A/i && !allowed_protocols.include?(value.split(protocol_separator).first.downcase.strip))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -2,7 +2,7 @@ module ActionPack
|
||||
module VERSION #:nodoc:
|
||||
MAJOR = 3
|
||||
MINOR = 2
|
||||
TINY = 12
|
||||
TINY = 13
|
||||
PRE = nil
|
||||
|
||||
STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
|
||||
|
||||
@@ -176,6 +176,7 @@ class SanitizerTest < ActionController::TestCase
|
||||
%(<IMG SRC="jav
ascript:alert('XSS');">),
|
||||
%(<IMG SRC="jav
ascript:alert('XSS');">),
|
||||
%(<IMG SRC="  javascript:alert('XSS');">),
|
||||
%(<IMG SRC="javascript:alert('XSS');">),
|
||||
%(<IMG SRC=`javascript:alert("RSnake says, 'XSS'")`>)].each_with_index do |img_hack, i|
|
||||
define_method "test_should_not_fall_for_xss_image_hack_#{i+1}" do
|
||||
assert_sanitized img_hack, "<img>"
|
||||
@@ -256,6 +257,11 @@ class SanitizerTest < ActionController::TestCase
|
||||
assert_equal '', sanitize_css(raw)
|
||||
end
|
||||
|
||||
def test_should_sanitize_across_newlines
|
||||
raw = %(\nwidth:\nexpression(alert('XSS'));\n)
|
||||
assert_equal '', sanitize_css(raw)
|
||||
end
|
||||
|
||||
def test_should_sanitize_img_vbscript
|
||||
assert_sanitized %(<img src='vbscript:msgbox("XSS")' />), '<img />'
|
||||
end
|
||||
@@ -276,6 +282,15 @@ class SanitizerTest < ActionController::TestCase
|
||||
assert_sanitized "<span class=\"\\", "<span class=\"\\\">"
|
||||
end
|
||||
|
||||
def test_x03a
|
||||
assert_sanitized %(<a href="javascript:alert('XSS');">), "<a>"
|
||||
assert_sanitized %(<a href="javascript:alert('XSS');">), "<a>"
|
||||
assert_sanitized %(<a href="http://legit">), %(<a href="http://legit">)
|
||||
assert_sanitized %(<a href="javascript:alert('XSS');">), "<a>"
|
||||
assert_sanitized %(<a href="javascript:alert('XSS');">), "<a>"
|
||||
assert_sanitized %(<a href="http://legit">), %(<a href="http://legit">)
|
||||
end
|
||||
|
||||
protected
|
||||
def assert_sanitized(input, expected = nil)
|
||||
@sanitizer ||= HTML::WhiteListSanitizer.new
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* No changes.
|
||||
|
||||
|
||||
## Rails 3.2.13.rc1 (Feb 17, 2013) ##
|
||||
## Rails 3.2.13 ##
|
||||
|
||||
* Specify type of singular association during serialization *Steve Klabnik*
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ module ActiveModel
|
||||
module VERSION #:nodoc:
|
||||
MAJOR = 3
|
||||
MINOR = 2
|
||||
TINY = 12
|
||||
TINY = 13
|
||||
PRE = nil
|
||||
|
||||
STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
## unreleased ##
|
||||
## Rails 3.2.13 (Feb 17, 2013) ##
|
||||
|
||||
* Reload the association target if it's stale. `@stale_state` should be nil
|
||||
when a model isn't saved.
|
||||
@@ -238,16 +238,6 @@
|
||||
|
||||
*Victor Costan*
|
||||
|
||||
* `#pluck` can be used on a relation with `select` clause.
|
||||
Fixes #7551.
|
||||
Backport of #8176.
|
||||
|
||||
Example:
|
||||
|
||||
Topic.select([:approved, :id]).order(:id).pluck(:id)
|
||||
|
||||
*Yves Senn*
|
||||
|
||||
* Use `nil?` instead of `blank?` to check whether dynamic finder with a bang
|
||||
should raise RecordNotFound.
|
||||
Fixes #7238.
|
||||
|
||||
@@ -464,7 +464,7 @@ module ActiveRecord
|
||||
node.left.relation.name == table_name
|
||||
}
|
||||
|
||||
Hash[equalities.map { |where| [where.left.name, where.right] }]
|
||||
Hash[equalities.map { |where| [where.left.name, where.right] }].with_indifferent_access
|
||||
end
|
||||
|
||||
def scope_for_create
|
||||
|
||||
@@ -20,7 +20,7 @@ module ActiveRecord
|
||||
table = Arel::Table.new(table_name, engine)
|
||||
end
|
||||
|
||||
attribute = table[column.to_sym]
|
||||
attribute = table[column]
|
||||
|
||||
case value
|
||||
when ActiveRecord::Relation
|
||||
|
||||
@@ -2,7 +2,7 @@ module ActiveRecord
|
||||
module VERSION #:nodoc:
|
||||
MAJOR = 3
|
||||
MINOR = 2
|
||||
TINY = 12
|
||||
TINY = 13
|
||||
PRE = nil
|
||||
|
||||
STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
|
||||
|
||||
@@ -493,12 +493,6 @@ class CalculationsTest < ActiveRecord::TestCase
|
||||
assert_equal [1,2,3,4], Topic.order(:id).pluck("topics.id")
|
||||
end
|
||||
|
||||
def test_pluck_replaces_select_clause
|
||||
taks_relation = Topic.select([:approved, :id]).order(:id)
|
||||
assert_equal [1,2,3,4], taks_relation.pluck(:id)
|
||||
assert_equal [false, true, true, true], taks_relation.pluck(:approved)
|
||||
end
|
||||
|
||||
def test_pluck_auto_table_name_prefix
|
||||
c = Company.create!(:name => "test", :contracts => [Contract.new])
|
||||
assert_equal [c.id], Company.joins(:contracts).pluck(:id)
|
||||
|
||||
@@ -212,14 +212,14 @@ class MethodScopingTest < ActiveRecord::TestCase
|
||||
table = VerySpecialComment.arel_table
|
||||
relation = VerySpecialComment.scoped
|
||||
relation.where_values << table[:id].not_eq(1)
|
||||
assert_equal({:type => "VerySpecialComment"}, relation.send(:scope_for_create))
|
||||
assert_equal({'type' => "VerySpecialComment"}, relation.send(:scope_for_create))
|
||||
end
|
||||
|
||||
def test_scoped_create
|
||||
new_comment = nil
|
||||
|
||||
VerySpecialComment.send(:with_scope, :create => { :post_id => 1 }) do
|
||||
assert_equal({:post_id => 1, :type => 'VerySpecialComment' }, VerySpecialComment.scoped.send(:scope_for_create))
|
||||
assert_equal({'post_id' => 1, 'type' => 'VerySpecialComment' }, VerySpecialComment.scoped.send(:scope_for_create))
|
||||
new_comment = VerySpecialComment.create :body => "Wonderful world"
|
||||
end
|
||||
|
||||
@@ -228,7 +228,7 @@ class MethodScopingTest < ActiveRecord::TestCase
|
||||
|
||||
def test_scoped_create_with_join_and_merge
|
||||
Comment.where(:body => "but Who's Buying?").joins(:post).merge(Post.where(:body => 'Peace Sells...')).with_scope do
|
||||
assert_equal({:body => "but Who's Buying?"}, Comment.scoped.scope_for_create)
|
||||
assert_equal({'body' => "but Who's Buying?"}, Comment.scoped.scope_for_create)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -441,7 +441,7 @@ class NestedScopingTest < ActiveRecord::TestCase
|
||||
comment = nil
|
||||
Comment.send(:with_scope, :create => { :post_id => 1}) do
|
||||
Comment.send(:with_scope, :create => { :post_id => 2}) do
|
||||
assert_equal({:post_id => 2}, Comment.scoped.send(:scope_for_create))
|
||||
assert_equal({'post_id' => 2}, Comment.scoped.send(:scope_for_create))
|
||||
comment = Comment.create :body => "Hey guys, nested scopes are broken. Please fix!"
|
||||
end
|
||||
end
|
||||
@@ -453,7 +453,7 @@ class NestedScopingTest < ActiveRecord::TestCase
|
||||
|
||||
Comment.send(:with_scope, :create => { :body => "Hey guys, nested scopes are broken. Please fix!" }) do
|
||||
Comment.send(:with_exclusive_scope, :create => { :post_id => 1 }) do
|
||||
assert_equal({:post_id => 1}, Comment.scoped.send(:scope_for_create))
|
||||
assert_equal({'post_id' => 1}, Comment.scoped.send(:scope_for_create))
|
||||
assert_blank Comment.new.body
|
||||
comment = Comment.create :body => "Hey guys"
|
||||
end
|
||||
|
||||
@@ -71,7 +71,7 @@ module ActiveRecord
|
||||
def test_has_values
|
||||
relation = Relation.new Post, Post.arel_table
|
||||
relation.where_values << relation.table[:id].eq(10)
|
||||
assert_equal({:id => 10}, relation.where_values_hash)
|
||||
assert_equal({'id' => 10}, relation.where_values_hash)
|
||||
end
|
||||
|
||||
def test_values_wrong_table
|
||||
@@ -101,7 +101,7 @@ module ActiveRecord
|
||||
|
||||
def test_create_with_value
|
||||
relation = Relation.new Post, Post.arel_table
|
||||
hash = { :hello => 'world' }
|
||||
hash = { 'hello' => 'world' }
|
||||
relation.create_with_value = hash
|
||||
assert_equal hash, relation.scope_for_create
|
||||
end
|
||||
@@ -110,7 +110,7 @@ module ActiveRecord
|
||||
relation = Relation.new Post, Post.arel_table
|
||||
relation.where_values << relation.table[:id].eq(10)
|
||||
relation.create_with_value = {:hello => 'world'}
|
||||
assert_equal({:hello => 'world', :id => 10}, relation.scope_for_create)
|
||||
assert_equal({'hello' => 'world', 'id' => 10}, relation.scope_for_create)
|
||||
end
|
||||
|
||||
# FIXME: is this really wanted or expected behavior?
|
||||
|
||||
@@ -3,11 +3,10 @@
|
||||
* No changes.
|
||||
|
||||
|
||||
## Rails 3.2.13.rc1 (Feb 17, 2013) ##
|
||||
## Rails 3.2.13 ##
|
||||
|
||||
* No changes.
|
||||
|
||||
|
||||
## Rails 3.2.12 (Feb 11, 2013) ##
|
||||
|
||||
* No changes.
|
||||
|
||||
@@ -2,7 +2,7 @@ module ActiveResource
|
||||
module VERSION #:nodoc:
|
||||
MAJOR = 3
|
||||
MINOR = 2
|
||||
TINY = 12
|
||||
TINY = 13
|
||||
PRE = nil
|
||||
|
||||
STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
*Andrew White*
|
||||
|
||||
|
||||
## Rails 3.2.13.rc1 (Feb 17, 2013) ##
|
||||
## Rails 3.2.13 (Feb 17, 2013) ##
|
||||
|
||||
|
||||
* Fix DateTime comparison with DateTime::Infinity object.
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ module ActiveSupport
|
||||
module VERSION #:nodoc:
|
||||
MAJOR = 3
|
||||
MINOR = 2
|
||||
TINY = 12
|
||||
TINY = 13
|
||||
PRE = nil
|
||||
|
||||
STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
|
||||
|
||||
@@ -38,6 +38,12 @@ module ActiveSupport
|
||||
{}
|
||||
else
|
||||
@dbf = DocumentBuilderFactory.new_instance
|
||||
# secure processing of java xml
|
||||
# http://www.ibm.com/developerworks/xml/library/x-tipcfsx/index.html
|
||||
@dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false)
|
||||
@dbf.setFeature("http://xml.org/sax/features/external-general-entities", false)
|
||||
@dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false)
|
||||
@dbf.setFeature(javax.xml.XMLConstants::FEATURE_SECURE_PROCESSING, true)
|
||||
xml_string_reader = StringReader.new(data)
|
||||
xml_input_source = InputSource.new(xml_string_reader)
|
||||
doc = @dbf.new_document_builder.parse(xml_input_source)
|
||||
|
||||
1
activesupport/test/fixtures/xml/jdom_doctype.dtd
vendored
Normal file
1
activesupport/test/fixtures/xml/jdom_doctype.dtd
vendored
Normal file
@@ -0,0 +1 @@
|
||||
<!ENTITY a "external entity">
|
||||
1
activesupport/test/fixtures/xml/jdom_entities.txt
vendored
Normal file
1
activesupport/test/fixtures/xml/jdom_entities.txt
vendored
Normal file
@@ -0,0 +1 @@
|
||||
<!ENTITY a "hello">
|
||||
1
activesupport/test/fixtures/xml/jdom_include.txt
vendored
Normal file
1
activesupport/test/fixtures/xml/jdom_include.txt
vendored
Normal file
@@ -0,0 +1 @@
|
||||
include me
|
||||
@@ -3,9 +3,11 @@ if RUBY_PLATFORM =~ /java/
|
||||
require 'active_support/xml_mini'
|
||||
require 'active_support/core_ext/hash/conversions'
|
||||
|
||||
class JDOMEngineTest < Test::Unit::TestCase
|
||||
class JDOMEngineTest < ActiveSupport::TestCase
|
||||
include ActiveSupport
|
||||
|
||||
FILES_DIR = File.dirname(__FILE__) + '/../fixtures/xml'
|
||||
|
||||
def setup
|
||||
@default_backend = XmlMini.backend
|
||||
XmlMini.backend = 'JDOM'
|
||||
@@ -30,10 +32,41 @@ if RUBY_PLATFORM =~ /java/
|
||||
assert_equal 'image/png', file.content_type
|
||||
end
|
||||
|
||||
def test_not_allowed_to_expand_entities_to_files
|
||||
attack_xml = <<-EOT
|
||||
<!DOCTYPE member [
|
||||
<!ENTITY a SYSTEM "file://#{FILES_DIR}/jdom_include.txt">
|
||||
]>
|
||||
<member>x&a;</member>
|
||||
EOT
|
||||
assert_equal 'x', Hash.from_xml(attack_xml)["member"]
|
||||
end
|
||||
|
||||
def test_not_allowed_to_expand_parameter_entities_to_files
|
||||
attack_xml = <<-EOT
|
||||
<!DOCTYPE member [
|
||||
<!ENTITY % b SYSTEM "file://#{FILES_DIR}/jdom_entities.txt">
|
||||
%b;
|
||||
]>
|
||||
<member>x&a;</member>
|
||||
EOT
|
||||
assert_raise Java::OrgXmlSax::SAXParseException do
|
||||
assert_equal 'x', Hash.from_xml(attack_xml)["member"]
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def test_not_allowed_to_load_external_doctypes
|
||||
attack_xml = <<-EOT
|
||||
<!DOCTYPE member SYSTEM "file://#{FILES_DIR}/jdom_doctype.dtd">
|
||||
<member>x&a;</member>
|
||||
EOT
|
||||
assert_equal 'x', Hash.from_xml(attack_xml)["member"]
|
||||
end
|
||||
|
||||
def test_exception_thrown_on_expansion_attack
|
||||
assert_raise NativeException do
|
||||
assert_raise Java::OrgXmlSax::SAXParseException do
|
||||
attack_xml = <<-EOT
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE member [
|
||||
<!ENTITY a "&b;&b;&b;&b;&b;&b;&b;&b;&b;&b;">
|
||||
<!ENTITY b "&c;&c;&c;&c;&c;&c;&c;&c;&c;&c;">
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* No changes.
|
||||
|
||||
|
||||
## Rails 3.2.13.rc1 (Feb 17, 2013) ##
|
||||
## Rails 3.2.13 ##
|
||||
|
||||
* No changes.
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ module Rails
|
||||
module VERSION #:nodoc:
|
||||
MAJOR = 3
|
||||
MINOR = 2
|
||||
TINY = 12
|
||||
TINY = 13
|
||||
PRE = nil
|
||||
|
||||
STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
|
||||
|
||||
@@ -2,7 +2,7 @@ module Rails
|
||||
module VERSION #:nodoc:
|
||||
MAJOR = 3
|
||||
MINOR = 2
|
||||
TINY = 12
|
||||
TINY = 13
|
||||
PRE = nil
|
||||
|
||||
STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
|
||||
|
||||
Reference in New Issue
Block a user