Last active
December 11, 2015 02:59
-
-
Save grosser/4534716 to your computer and use it in GitHub Desktop.
Rails 2.3 fix for https://github.com/rails/rails/issues/8832 / CVE-2013-0155
prevent nil insertion, do a deep_munge for all non-browser input methods (which cannot produce empty hash or array or nil) ActiveRecord does not need the empty hash patch since e.g. `User.find_by_name({})` is ok
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
if Rails::VERSION::MAJOR == 2 | |
ActionController::Base.class_eval do | |
def params_with_nil_fix | |
params = params_without_nil_fix | |
unless params.instance_variable_get(:@nil_fixed) | |
params.instance_variable_set(:@nil_fixed, true) | |
# normal form params cannot include nil/empty hash/empty array, just json/xml | |
deep_munge(params) unless ["application/x-www-form-urlencoded", "multipart/form-data", nil].include?(request.try(:content_type)) | |
end | |
params | |
end | |
alias_method_chain :params, :nil_fix | |
# copied from https://github.com/rails/rails/blob/d5cd97baa44fa66dc681041a213092b45c57c32f/actionpack/lib/action_dispatch/http/request.rb:250 | |
def deep_munge(hash) | |
hash.each do |k, v| | |
case v | |
when Array | |
v.grep(Hash) { |x| deep_munge(x) } | |
v.compact! | |
hash[k] = nil if v.empty? | |
when Hash | |
deep_munge(v) | |
end | |
end | |
hash | |
end unless defined?(deep_munge) | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require File.expand_path("../../../helpers/test_helper", File.dirname(__FILE__)) | |
# fixed in 3.2.11 via https://github.com/rails/rails/commit/d5cd97baa44fa66dc681041a213092b45c57c32 | |
class PreventNilValuesInParamsTest < ActionController::IntegrationTest | |
class TestController < ActionController::Base | |
def index | |
render :text => params.except(:action, :controller).inspect | |
end | |
end | |
context "prevent nil values in params" do | |
let(:xpath){ "/test_route/prevent_nil_values_in_params_test/" } | |
should "have normal params" do | |
get xpath, :id => ["a", {"b" => 1}] | |
assert_equal "{\"id\"=>[\"a\", {\"b\"=>\"1\"}]}", @response.body | |
end | |
# works in real server, not in integration test | |
should_eventually "have nil for weirdly nested params" do | |
get "#{xpath}?a[][]&b[][]=1" | |
assert_equal "{\"a\"=>nil,\"b\"=>nil}", @response.body | |
end | |
should "have empty strings" do | |
get xpath, :id => " " | |
assert_equal "{\"id\"=>\" \"}", @response.body | |
end | |
context "xml" do | |
should "remove nil in arrays" do | |
post xpath, "<id type=\"array\"><id>xxx</id><id nil=\"true\"/></id>", 'CONTENT_TYPE' => Mime::XML.to_s | |
assert_equal "{\"id\"=>[\"xxx\"]}", @response.body | |
end | |
should "not allow empty arrays" do | |
post xpath, "<hash><id type=\"array\"></id><foo></foo></hash>", 'CONTENT_TYPE' => Mime::XML.to_s | |
assert_equal "{\"hash\"=>{\"id\"=>nil, \"foo\"=>nil}}", @response.body | |
end | |
end | |
context "json" do | |
should "remove nil in arrays" do | |
post xpath, "{\"id\":[\"xxx\", null]}", 'CONTENT_TYPE' => Mime::JSON.to_s | |
assert_equal "{\"id\"=>[\"xxx\"]}", @response.body | |
end | |
should "not allow empty arrays" do | |
post xpath, "{\"id\":[],\"foo\":{}}", 'CONTENT_TYPE' => Mime::JSON.to_s | |
assert_equal "{\"id\"=>nil, \"foo\"=>{}}", @response.body | |
end | |
end | |
should "apply to funky shit" do | |
post xpath, "{\"id\":[\"xxx\", null]}", 'CONTENT_TYPE' => "image/jpeg" | |
assert_equal "{}", @response.body | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment