From 7828e873e7c7a7604b02636ffd49593bd20a0da8 Mon Sep 17 00:00:00 2001 From: Nate Berkopec Date: Tue, 18 Nov 2014 19:00:52 -0500 Subject: [PATCH 1/2] Fix error in empty object sanitization +add one test for traversing arrays --- lib/raven/processor/sanitizedata.rb | 23 +++++++++---------- .../processors/sanitizedata_processor_spec.rb | 9 ++++++++ 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/lib/raven/processor/sanitizedata.rb b/lib/raven/processor/sanitizedata.rb index 3d742bd78..87d8b966a 100644 --- a/lib/raven/processor/sanitizedata.rb +++ b/lib/raven/processor/sanitizedata.rb @@ -8,32 +8,31 @@ class Processor::SanitizeData < Processor def process(value) fields_re = /(#{(DEFAULT_FIELDS + @sanitize_fields).join("|")})/i - value.inject(value) do |value,(k,v)| + value.inject(value) do |memo,(k,v)| v = k if v.nil? - if v.is_a?(Hash) || v.is_a?(Array) - process(v) + memo = if v.is_a?(Hash) || v.is_a?(Array) + modify_in_place(memo, k, process(v)) elsif v.is_a?(String) && (json = parse_json_or_nil(v)) #if this string is actually a json obj, convert and sanitize - value = modify_in_place(value, [k,v], process(json).to_json) + modify_in_place(memo, k, process(json).to_json) elsif v.is_a?(Integer) && (VALUES_RE.match(v.to_s) || fields_re.match(k.to_s)) - value = modify_in_place(value, [k,v], INT_MASK) + modify_in_place(memo, k, INT_MASK) elsif VALUES_RE.match(v.to_s) || fields_re.match(k.to_s) - value = modify_in_place(value, [k,v], STRING_MASK) + modify_in_place(memo, k, STRING_MASK) else - value + memo end end - value end private - def modify_in_place(original_parent, original_child, new_child) + def modify_in_place(original_parent, original_child, new_value) if original_parent.is_a?(Array) - index = original_parent.index(original_child[0]) - original_parent[index] = new_child + index = original_parent.index(original_child) + original_parent[index] = new_value elsif original_parent.is_a?(Hash) - original_parent[original_child[0]] = new_child + original_parent[original_child] = new_value end original_parent end diff --git a/spec/raven/processors/sanitizedata_processor_spec.rb b/spec/raven/processors/sanitizedata_processor_spec.rb index 36da0f91d..173e31c3f 100644 --- a/spec/raven/processors/sanitizedata_processor_spec.rb +++ b/spec/raven/processors/sanitizedata_processor_spec.rb @@ -87,11 +87,20 @@ data = { 'ccnumba' => '4242424242424242', 'ccnumba_int' => 4242424242424242, + 'ccnumba_in_array' => ['4242424242424242'] } result = @processor.process(data) expect(result["ccnumba"]).to eq(Raven::Processor::SanitizeData::STRING_MASK) expect(result["ccnumba_int"]).to eq(Raven::Processor::SanitizeData::INT_MASK) + expect(result["ccnumba_in_array"]).to eq([Raven::Processor::SanitizeData::STRING_MASK]) end + it 'does not raise errors on empty objects' do + data = { + "empty_array"=> [], + "empty_fake_json"=>"[]", + } + expect{@processor.process(data)}.to_not raise_error + end end From 004f0cdb1019ff616f4bbea62179e594d19db929 Mon Sep 17 00:00:00 2001 From: Nate Berkopec Date: Tue, 18 Nov 2014 19:35:29 -0500 Subject: [PATCH 2/2] Stop doing backflips to sanitize arrays --- lib/raven/processor.rb | 3 +- lib/raven/processor/sanitizedata.rb | 41 ++++++++----------- .../processors/sanitizedata_processor_spec.rb | 11 ++--- 3 files changed, 25 insertions(+), 30 deletions(-) diff --git a/lib/raven/processor.rb b/lib/raven/processor.rb index be6c9430d..ea4d1044b 100644 --- a/lib/raven/processor.rb +++ b/lib/raven/processor.rb @@ -17,8 +17,7 @@ def process(data) def parse_json_or_nil(string) begin - result = OkJson.decode(string) - result.is_a?(String) ? nil : result + OkJson.decode(string) rescue Raven::OkJson::Error nil end diff --git a/lib/raven/processor/sanitizedata.rb b/lib/raven/processor/sanitizedata.rb index 87d8b966a..3ccd30067 100644 --- a/lib/raven/processor/sanitizedata.rb +++ b/lib/raven/processor/sanitizedata.rb @@ -6,35 +6,30 @@ class Processor::SanitizeData < Processor VALUES_RE = /^\d{16}$/ def process(value) - fields_re = /(#{(DEFAULT_FIELDS + @sanitize_fields).join("|")})/i + value.inject(value) { |memo,(k,v)| memo[k] = sanitize(k,v); memo } + end - value.inject(value) do |memo,(k,v)| - v = k if v.nil? - memo = if v.is_a?(Hash) || v.is_a?(Array) - modify_in_place(memo, k, process(v)) - elsif v.is_a?(String) && (json = parse_json_or_nil(v)) - #if this string is actually a json obj, convert and sanitize - modify_in_place(memo, k, process(json).to_json) - elsif v.is_a?(Integer) && (VALUES_RE.match(v.to_s) || fields_re.match(k.to_s)) - modify_in_place(memo, k, INT_MASK) - elsif VALUES_RE.match(v.to_s) || fields_re.match(k.to_s) - modify_in_place(memo, k, STRING_MASK) - else - memo - end + def sanitize(k,v) + if v.is_a?(Hash) + process(v) + elsif v.is_a?(Array) + v.map{|a| sanitize(nil, a)} + elsif v.is_a?(String) && (json = parse_json_or_nil(v)) + #if this string is actually a json obj, convert and sanitize + json.is_a?(Hash) ? process(json).to_json : v + elsif v.is_a?(Integer) && (VALUES_RE.match(v.to_s) || fields_re.match(k.to_s)) + INT_MASK + elsif v.is_a?(String) && (VALUES_RE.match(v.to_s) || fields_re.match(k.to_s)) + STRING_MASK + else + v end end private - def modify_in_place(original_parent, original_child, new_value) - if original_parent.is_a?(Array) - index = original_parent.index(original_child) - original_parent[index] = new_value - elsif original_parent.is_a?(Hash) - original_parent[original_child] = new_value - end - original_parent + def fields_re + @fields_re ||= /(#{(DEFAULT_FIELDS + @sanitize_fields).join("|")})/i end end end diff --git a/spec/raven/processors/sanitizedata_processor_spec.rb b/spec/raven/processors/sanitizedata_processor_spec.rb index 173e31c3f..76a12b292 100644 --- a/spec/raven/processors/sanitizedata_processor_spec.rb +++ b/spec/raven/processors/sanitizedata_processor_spec.rb @@ -87,20 +87,21 @@ data = { 'ccnumba' => '4242424242424242', 'ccnumba_int' => 4242424242424242, - 'ccnumba_in_array' => ['4242424242424242'] } result = @processor.process(data) expect(result["ccnumba"]).to eq(Raven::Processor::SanitizeData::STRING_MASK) expect(result["ccnumba_int"]).to eq(Raven::Processor::SanitizeData::INT_MASK) - expect(result["ccnumba_in_array"]).to eq([Raven::Processor::SanitizeData::STRING_MASK]) end - it 'does not raise errors on empty objects' do + it 'sanitizes hashes nested in arrays' do data = { "empty_array"=> [], - "empty_fake_json"=>"[]", + "array"=>[{'password' => 'secret'}], } - expect{@processor.process(data)}.to_not raise_error + + result = @processor.process(data) + + expect(result["array"][0]['password']).to eq(Raven::Processor::SanitizeData::STRING_MASK) end end