sentry-sanitize 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f15481201515e0e87778ada1e44fd5851379d7ae4e8897a0b23a28892ac500ac
4
- data.tar.gz: 0f0af15d52b8894b5ba4ec9a37f3fd8134c721dab38009a888ce32a14d1c363f
3
+ metadata.gz: c334e976d9f260a013086dc61180d889e594d64cb32bebda6c5352610c3646fe
4
+ data.tar.gz: f763783ce3f4fdfc5d12cf126f487cb08d25108dd6bb84baf954b12a782d81f2
5
5
  SHA512:
6
- metadata.gz: f4c5f936a5e0e4d3a08461ba2ce0db9b56668266f850f541a6a6c769238a04382ce7f9bf2e4070874b1b9bb3374c3abeba393788e216788bc67662449ec352f3
7
- data.tar.gz: 911aa9c502d8fcef4fe2e9457ce1028148d282c3d99d514bffe8cd54c72ddf383a14cc9298a3029732e20b9566a2e6564365c389a6c5560bd1c8be55691dbd20
6
+ metadata.gz: 4f0390a5238cac85411e54293d6091e2b6c6ca1042c9cf701d27766afd8b77924ef4b7633aa71055a4fd236be797d2d489e1af8b575213e5962b029d6ada55f8
7
+ data.tar.gz: b282cc0b410b405a75765d1198ee2c0694e1834761a584f611fa5f215c4cd0d41a88a9fef1fe7967aba0d3e65ee9c053924202911e2d33e7383500b51dbec2f3
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- sentry-sanitize (0.3.0)
4
+ sentry-sanitize (0.4.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -5,11 +5,13 @@ require 'sentry/sanitize/processor/sanitize_data'
5
5
  require 'sentry/sanitize/processor/utf8conversion'
6
6
 
7
7
  module Sentry
8
- class Processor::CustomSanitizeData < Processor::SanitizeData
9
- def initialize(sanitize_fields)
10
- self.sanitize_fields = sanitize_fields
11
- self.sanitize_credit_cards = true
12
- self.sanitize_fields_excluded = []
8
+ module Sanitize
9
+ class Processor::CustomSanitizeData < Processor::SanitizeData
10
+ def initialize(sanitize_fields)
11
+ self.sanitize_fields = sanitize_fields
12
+ self.sanitize_credit_cards = true
13
+ self.sanitize_fields_excluded = []
14
+ end
13
15
  end
14
16
  end
15
17
  end
@@ -3,134 +3,136 @@
3
3
  require 'json'
4
4
 
5
5
  module Sentry
6
- class Processor::SanitizeData < Processor
7
- DEFAULT_FIELDS = %w(authorization password passwd secret ssn social(.*)?sec).freeze
8
- CREDIT_CARD_RE = /\b(?:3[47]\d|(?:4\d|5[1-5]|65)\d{2}|6011)\d{12}\b/.freeze
9
- QUERY_STRING = ['query_string', :query_string].freeze
10
- JSON_STARTS_WITH = ["[", "{"].freeze
11
-
12
- attr_accessor :sanitize_fields, :sanitize_credit_cards, :sanitize_fields_excluded
13
-
14
- def initialize(client)
15
- super
16
- self.sanitize_fields = client.configuration.sanitize_fields
17
- self.sanitize_credit_cards = client.configuration.sanitize_credit_cards
18
- self.sanitize_fields_excluded = client.configuration.sanitize_fields_excluded
19
- end
6
+ module Sanitize
7
+ class Processor::SanitizeData < Processor
8
+ DEFAULT_FIELDS = %w(authorization password passwd secret ssn social(.*)?sec).freeze
9
+ CREDIT_CARD_RE = /\b(?:3[47]\d|(?:4\d|5[1-5]|65)\d{2}|6011)\d{12}\b/.freeze
10
+ QUERY_STRING = ['query_string', :query_string].freeze
11
+ JSON_STARTS_WITH = ["[", "{"].freeze
12
+
13
+ attr_accessor :sanitize_fields, :sanitize_credit_cards, :sanitize_fields_excluded
14
+
15
+ def initialize(client)
16
+ super
17
+ self.sanitize_fields = client.configuration.sanitize_fields
18
+ self.sanitize_credit_cards = client.configuration.sanitize_credit_cards
19
+ self.sanitize_fields_excluded = client.configuration.sanitize_fields_excluded
20
+ end
20
21
 
21
- def process(value, key = nil)
22
- case value
23
- when Hash
24
- sanitize_hash_value(key, value)
25
- when Array
26
- sanitize_array_value(key, value)
27
- when Integer
28
- matches_regexes?(key, value.to_s) ? INT_MASK : value
29
- when String
30
- sanitize_string_value(key, value)
31
- else
32
- value
22
+ def process(value, key = nil)
23
+ case value
24
+ when Hash
25
+ sanitize_hash_value(key, value)
26
+ when Array
27
+ sanitize_array_value(key, value)
28
+ when Integer
29
+ matches_regexes?(key, value.to_s) ? INT_MASK : value
30
+ when String
31
+ sanitize_string_value(key, value)
32
+ else
33
+ value
34
+ end
33
35
  end
34
- end
35
36
 
36
- private
37
+ private
37
38
 
38
- # CGI.parse takes our nice UTF-8 strings and converts them back to ASCII,
39
- # so we have to convert them back, again.
40
- def utf8_processor
41
- @utf8_processor ||= Processor::UTF8Conversion.new
42
- end
39
+ # CGI.parse takes our nice UTF-8 strings and converts them back to ASCII,
40
+ # so we have to convert them back, again.
41
+ def utf8_processor
42
+ @utf8_processor ||= Processor::UTF8Conversion.new
43
+ end
43
44
 
44
- def sanitize_hash_value(key, value)
45
- if key =~ sensitive_fields
46
- STRING_MASK
47
- elsif value.frozen?
48
- value.merge(value) { |k, v| process v, k }
49
- else
50
- value.merge!(value) { |k, v| process v, k }
45
+ def sanitize_hash_value(key, value)
46
+ if key =~ sensitive_fields
47
+ STRING_MASK
48
+ elsif value.frozen?
49
+ value.merge(value) { |k, v| process v, k }
50
+ else
51
+ value.merge!(value) { |k, v| process v, k }
52
+ end
51
53
  end
52
- end
53
54
 
54
- def sanitize_array_value(key, value)
55
- if value.frozen?
56
- value.map { |v| process v, key }
57
- else
58
- value.map! { |v| process v, key }
55
+ def sanitize_array_value(key, value)
56
+ if value.frozen?
57
+ value.map { |v| process v, key }
58
+ else
59
+ value.map! { |v| process v, key }
60
+ end
59
61
  end
60
- end
61
62
 
62
- def sanitize_string_value(key, value)
63
- if value =~ sensitive_fields && (json = parse_json_or_nil(value))
64
- # if this string is actually a json obj, convert and sanitize
65
- process(json).to_json
66
- elsif matches_regexes?(key, value)
67
- STRING_MASK
68
- elsif QUERY_STRING.include?(key)
69
- sanitize_query_string(value)
70
- elsif value =~ sensitive_fields
71
- sanitize_sensitive_string_content(value)
72
- else
73
- value
63
+ def sanitize_string_value(key, value)
64
+ if value =~ sensitive_fields && (json = parse_json_or_nil(value))
65
+ # if this string is actually a json obj, convert and sanitize
66
+ process(json).to_json
67
+ elsif matches_regexes?(key, value)
68
+ STRING_MASK
69
+ elsif QUERY_STRING.include?(key)
70
+ sanitize_query_string(value)
71
+ elsif value =~ sensitive_fields
72
+ sanitize_sensitive_string_content(value)
73
+ else
74
+ value
75
+ end
74
76
  end
75
- end
76
77
 
77
- def sanitize_query_string(query_string)
78
- query_hash = CGI.parse(query_string)
79
- sanitized = utf8_processor.process(query_hash)
80
- processed_query_hash = process(sanitized)
81
- URI.encode_www_form(processed_query_hash)
82
- end
78
+ def sanitize_query_string(query_string)
79
+ query_hash = CGI.parse(query_string)
80
+ sanitized = utf8_processor.process(query_hash)
81
+ processed_query_hash = process(sanitized)
82
+ URI.encode_www_form(processed_query_hash)
83
+ end
83
84
 
84
- # this scrubs some sensitive info from the string content. for example:
85
- #
86
- # ```
87
- # unexpected token at '{
88
- # "role": "admin","password": "Abc@123","foo": "bar"
89
- # }'
90
- # ```
91
- #
92
- # will become
93
- #
94
- # ```
95
- # unexpected token at '{
96
- # "role": "admin","password": *******,"foo": "bar"
97
- # }'
98
- # ```
99
- #
100
- # it's particularly useful in hash or param-parsing related errors
101
- def sanitize_sensitive_string_content(value)
102
- value.gsub(/(#{sensitive_fields}['":]\s?(:|=>)?\s?)(".*?"|'.*?')/, '\1' + STRING_MASK)
103
- end
85
+ # this scrubs some sensitive info from the string content. for example:
86
+ #
87
+ # ```
88
+ # unexpected token at '{
89
+ # "role": "admin","password": "Abc@123","foo": "bar"
90
+ # }'
91
+ # ```
92
+ #
93
+ # will become
94
+ #
95
+ # ```
96
+ # unexpected token at '{
97
+ # "role": "admin","password": *******,"foo": "bar"
98
+ # }'
99
+ # ```
100
+ #
101
+ # it's particularly useful in hash or param-parsing related errors
102
+ def sanitize_sensitive_string_content(value)
103
+ value.gsub(/(#{sensitive_fields}['":]\s?(:|=>)?\s?)(".*?"|'.*?')/, '\1' + STRING_MASK)
104
+ end
104
105
 
105
- def matches_regexes?(k, v)
106
- (sanitize_credit_cards && v =~ CREDIT_CARD_RE) ||
107
- k =~ sensitive_fields
108
- end
106
+ def matches_regexes?(k, v)
107
+ (sanitize_credit_cards && v =~ CREDIT_CARD_RE) ||
108
+ k =~ sensitive_fields
109
+ end
109
110
 
110
- def sensitive_fields
111
- return @sensitive_fields if instance_variable_defined?(:@sensitive_fields)
111
+ def sensitive_fields
112
+ return @sensitive_fields if instance_variable_defined?(:@sensitive_fields)
112
113
 
113
- fields = DEFAULT_FIELDS | sanitize_fields
114
- fields -= sanitize_fields_excluded
115
- @sensitive_fields = /#{fields.map do |f|
116
- use_boundary?(f) ? "\\b#{f}\\b" : f
117
- end.join("|")}/i
118
- end
114
+ fields = DEFAULT_FIELDS | sanitize_fields
115
+ fields -= sanitize_fields_excluded
116
+ @sensitive_fields = /#{fields.map do |f|
117
+ use_boundary?(f) ? "\\b#{f}\\b" : f
118
+ end.join("|")}/i
119
+ end
119
120
 
120
- def use_boundary?(string)
121
- !DEFAULT_FIELDS.include?(string) && !special_characters?(string)
122
- end
121
+ def use_boundary?(string)
122
+ !DEFAULT_FIELDS.include?(string) && !special_characters?(string)
123
+ end
123
124
 
124
- def special_characters?(string)
125
- REGEX_SPECIAL_CHARACTERS.select { |r| string.include?(r) }.any?
126
- end
125
+ def special_characters?(string)
126
+ REGEX_SPECIAL_CHARACTERS.select { |r| string.include?(r) }.any?
127
+ end
127
128
 
128
- def parse_json_or_nil(string)
129
- return unless string.start_with?(*JSON_STARTS_WITH)
129
+ def parse_json_or_nil(string)
130
+ return unless string.start_with?(*JSON_STARTS_WITH)
130
131
 
131
- JSON.parse(string)
132
- rescue JSON::ParserError, NoMethodError
133
- nil
132
+ JSON.parse(string)
133
+ rescue JSON::ParserError, NoMethodError
134
+ nil
135
+ end
134
136
  end
135
137
  end
136
138
  end
@@ -1,53 +1,55 @@
1
1
  module Sentry
2
- class Processor::UTF8Conversion < Processor
3
- # Slightly misnamed - actually just removes any bytes with invalid encoding
4
- # Previously, our JSON backend required UTF-8. Since we now use the built-in
5
- # JSON, we can use any encoding, but it must be valid anyway so we can do
6
- # things like call #match and #slice on strings
7
- REPLACE = "".freeze
2
+ module Sanitize
3
+ class Processor::UTF8Conversion < Processor
4
+ # Slightly misnamed - actually just removes any bytes with invalid encoding
5
+ # Previously, our JSON backend required UTF-8. Since we now use the built-in
6
+ # JSON, we can use any encoding, but it must be valid anyway so we can do
7
+ # things like call #match and #slice on strings
8
+ REPLACE = "".freeze
8
9
 
9
- def process(value)
10
- case value
11
- when Hash
12
- !value.frozen? ? value.merge!(value) { |_, v| process v } : value.merge(value) { |_, v| process v }
13
- when Array
14
- !value.frozen? ? value.map! { |v| process v } : value.map { |v| process v }
15
- when Exception
16
- return value if value.message.valid_encoding?
10
+ def process(value)
11
+ case value
12
+ when Hash
13
+ !value.frozen? ? value.merge!(value) { |_, v| process v } : value.merge(value) { |_, v| process v }
14
+ when Array
15
+ !value.frozen? ? value.map! { |v| process v } : value.map { |v| process v }
16
+ when Exception
17
+ return value if value.message.valid_encoding?
17
18
 
18
- clean_exc = value.class.new(remove_invalid_bytes(value.message))
19
- clean_exc.set_backtrace(value.backtrace)
20
- clean_exc
21
- when String
22
- # Encoding::BINARY / Encoding::ASCII_8BIT is a special binary encoding.
23
- # valid_encoding? will always return true because it contains all codepoints,
24
- # so instead we check if it only contains actual ASCII codepoints, and if
25
- # not we assume it's actually just UTF8 and scrub accordingly.
26
- if value.encoding == Encoding::BINARY && !value.ascii_only?
27
- value = value.dup
28
- value.force_encoding(Encoding::UTF_8)
29
- end
30
- return value if value.valid_encoding?
19
+ clean_exc = value.class.new(remove_invalid_bytes(value.message))
20
+ clean_exc.set_backtrace(value.backtrace)
21
+ clean_exc
22
+ when String
23
+ # Encoding::BINARY / Encoding::ASCII_8BIT is a special binary encoding.
24
+ # valid_encoding? will always return true because it contains all codepoints,
25
+ # so instead we check if it only contains actual ASCII codepoints, and if
26
+ # not we assume it's actually just UTF8 and scrub accordingly.
27
+ if value.encoding == Encoding::BINARY && !value.ascii_only?
28
+ value = value.dup
29
+ value.force_encoding(Encoding::UTF_8)
30
+ end
31
+ return value if value.valid_encoding?
31
32
 
32
- remove_invalid_bytes(value)
33
- else
34
- value
33
+ remove_invalid_bytes(value)
34
+ else
35
+ value
36
+ end
35
37
  end
36
- end
37
38
 
38
- private
39
+ private
39
40
 
40
- # Stolen from RSpec
41
- # https://github.com/rspec/rspec-support/blob/f0af3fd74a94ff7bb700f6ba06dbdc67bba17fbf/lib/rspec/support/encoded_string.rb#L120-L139
42
- if String.method_defined?(:scrub) # 2.1+
43
- def remove_invalid_bytes(string)
44
- string.scrub(REPLACE)
45
- end
46
- else
47
- def remove_invalid_bytes(string)
48
- string.chars.map do |char|
49
- char.valid_encoding? ? char : REPLACE
50
- end.join
41
+ # Stolen from RSpec
42
+ # https://github.com/rspec/rspec-support/blob/f0af3fd74a94ff7bb700f6ba06dbdc67bba17fbf/lib/rspec/support/encoded_string.rb#L120-L139
43
+ if String.method_defined?(:scrub) # 2.1+
44
+ def remove_invalid_bytes(string)
45
+ string.scrub(REPLACE)
46
+ end
47
+ else
48
+ def remove_invalid_bytes(string)
49
+ string.chars.map do |char|
50
+ char.valid_encoding? ? char : REPLACE
51
+ end.join
52
+ end
51
53
  end
52
54
  end
53
55
  end
@@ -1,15 +1,17 @@
1
- module Raven
2
- class Processor
3
- STRING_MASK = '********'.freeze
4
- INT_MASK = 0
5
- REGEX_SPECIAL_CHARACTERS = %w(. $ ^ { [ ( | ) * + ?).freeze
1
+ module Sentry
2
+ module Sanitize
3
+ class Processor
4
+ STRING_MASK = '********'.freeze
5
+ INT_MASK = 0
6
+ REGEX_SPECIAL_CHARACTERS = %w(. $ ^ { [ ( | ) * + ?).freeze
6
7
 
7
- def initialize(client = nil)
8
- @client = client
9
- end
8
+ def initialize(client = nil)
9
+ @client = client
10
+ end
10
11
 
11
- def process(_data)
12
- raise NotImplementedError
12
+ def process(_data)
13
+ raise NotImplementedError
14
+ end
13
15
  end
14
16
  end
15
17
  end
@@ -1,5 +1,5 @@
1
1
  module Sentry
2
2
  module Sanitize
3
- VERSION = "0.3.0"
3
+ VERSION = "0.4.0"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sentry-sanitize
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Niko Roberts