sentry-sanitizer 0.8.2 → 0.9.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 +4 -4
- data/.github/workflows/ci-linux.yml +8 -7
- data/.github/workflows/ci-macos.yml +8 -8
- data/.rubocop.yml +6 -0
- data/CHANGELOG.md +13 -0
- data/Gemfile +13 -1
- data/Gemfile.lock +37 -5
- data/README.md +12 -7
- data/bin/bundle +13 -11
- data/lib/sentry/sanitizer/cleaner.rb +32 -63
- data/lib/sentry/sanitizer/configuration.rb +16 -1
- data/lib/sentry/sanitizer/configuration_mixin.rb +1 -1
- data/lib/sentry/sanitizer/filter.rb +53 -0
- data/lib/sentry/sanitizer/version.rb +1 -1
- data/sentry-sanitizer.gemspec +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ed85a8f652fb2b3b54796967d622c65699a630543a2911ccfdd1c30cf74704c7
|
|
4
|
+
data.tar.gz: 2cc6ea9f662817521cc22663734ae392a48ca6fbab77a785897e97d64766c70b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 727f6686da725234549fda38f2125e530ace8f641a9ea95469a692edf28f8a07863aeded84c4226ad7871c836ccbb6d6c504b671b97ed818fc02808b45e89e5c
|
|
7
|
+
data.tar.gz: 47da7c136e56db35e7435ae5d579ebc19f00bb2e0fb575c9e1b5e41e984a710d6804a815aa662428341b2a3d8b46254a392a529d015b93b06447c581ce8ade3e
|
|
@@ -10,13 +10,14 @@ jobs:
|
|
|
10
10
|
strategy:
|
|
11
11
|
matrix:
|
|
12
12
|
include:
|
|
13
|
-
- { ruby_version:
|
|
14
|
-
- { ruby_version: 3.0 }
|
|
15
|
-
- { ruby_version: 3.
|
|
16
|
-
- { ruby_version:
|
|
17
|
-
- { ruby_version:
|
|
18
|
-
- { ruby_version:
|
|
19
|
-
|
|
13
|
+
- { ruby_version: 3.3, sentry_version: "~> 6.0" }
|
|
14
|
+
- { ruby_version: 3.4, sentry_version: "~> 6.0" }
|
|
15
|
+
- { ruby_version: 3.4, sentry_version: "~> 7.0" }
|
|
16
|
+
- { ruby_version: 4.0, sentry_version: "~> 6.0" }
|
|
17
|
+
- { ruby_version: 4.0, sentry_version: "~> 7.0" }
|
|
18
|
+
- { ruby_version: jruby, sentry_version: "~> 6.0" }
|
|
19
|
+
env:
|
|
20
|
+
SENTRY_VERSION: ${{ matrix.sentry_version }}
|
|
20
21
|
steps:
|
|
21
22
|
- uses: actions/checkout@v1
|
|
22
23
|
|
|
@@ -10,13 +10,14 @@ jobs:
|
|
|
10
10
|
strategy:
|
|
11
11
|
matrix:
|
|
12
12
|
include:
|
|
13
|
-
- { ruby_version:
|
|
14
|
-
- { ruby_version: 3.0 }
|
|
15
|
-
- { ruby_version: 3.
|
|
16
|
-
- { ruby_version:
|
|
17
|
-
- { ruby_version:
|
|
18
|
-
- { ruby_version:
|
|
19
|
-
|
|
13
|
+
- { ruby_version: 3.3, sentry_version: "~> 6.0" }
|
|
14
|
+
- { ruby_version: 3.4, sentry_version: "~> 6.0" }
|
|
15
|
+
- { ruby_version: 3.4, sentry_version: "~> 7.0" }
|
|
16
|
+
- { ruby_version: 4.0, sentry_version: "~> 6.0" }
|
|
17
|
+
- { ruby_version: 4.0, sentry_version: "~> 7.0" }
|
|
18
|
+
- { ruby_version: jruby, sentry_version: "~> 6.0" }
|
|
19
|
+
env:
|
|
20
|
+
SENTRY_VERSION: ${{ matrix.sentry_version }}
|
|
20
21
|
steps:
|
|
21
22
|
- uses: actions/checkout@v1
|
|
22
23
|
|
|
@@ -37,4 +38,3 @@ jobs:
|
|
|
37
38
|
with:
|
|
38
39
|
flag-name: ruby-${{ join(matrix.*, '-') }}
|
|
39
40
|
parallel: true
|
|
40
|
-
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.9.0
|
|
4
|
+
|
|
5
|
+
- Add `filter` option to pass a custom filter, e.g. `ActiveSupport::ParameterFilter` [#25](https://github.com/mrexox/sentry-sanitizer/pull/25)
|
|
6
|
+
- `filter` can't be combined with `fields` or `mask`
|
|
7
|
+
|
|
8
|
+
## 0.8.3
|
|
9
|
+
|
|
10
|
+
- Add Sentry 7 support [#24](https://github.com/mrexox/sentry-sanitizer/pull/24)
|
|
11
|
+
|
|
12
|
+
## 0.8.2
|
|
13
|
+
|
|
14
|
+
- Sanitize breadcrumb data only if it's a Hash [#22](https://github.com/mrexox/sentry-sanitizer/pull/22)
|
|
15
|
+
|
|
3
16
|
## 0.8.1
|
|
4
17
|
|
|
5
18
|
- Fix breadcrumb data[:body] == nil handling [#20](https://github.com/mrexox/sentry-sanitizer/pull/20)
|
data/Gemfile
CHANGED
|
@@ -7,11 +7,23 @@ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
|
|
|
7
7
|
# Specify your gem's dependencies in sentry-sanitizer.gemspec
|
|
8
8
|
gemspec
|
|
9
9
|
|
|
10
|
+
gem "sentry-ruby", ENV.fetch("SENTRY_VERSION", "~> 6.0")
|
|
11
|
+
# sentry-ruby requires "logger" internally but only declares it as a dependency
|
|
12
|
+
# itself from ~6.3.1/7.0 onwards; older sentry-ruby versions rely on it being a
|
|
13
|
+
# stdlib default gem, which Ruby 4.0 no longer bundles by default.
|
|
14
|
+
gem "logger"
|
|
15
|
+
|
|
10
16
|
gem "base64"
|
|
17
|
+
gem "cgi"
|
|
11
18
|
gem "rubocop", "~> 1.28.2"
|
|
12
|
-
gem "simplecov", require: false, group: :test
|
|
13
19
|
|
|
14
20
|
gem "bundler", ">= 2.3"
|
|
15
21
|
gem "rack"
|
|
16
22
|
gem "rake", "~> 12"
|
|
17
23
|
gem "rspec", "~> 3.0"
|
|
24
|
+
|
|
25
|
+
group :test do
|
|
26
|
+
gem "activesupport", "~> 8.0"
|
|
27
|
+
|
|
28
|
+
gem "simplecov", require: false
|
|
29
|
+
end
|
data/Gemfile.lock
CHANGED
|
@@ -1,18 +1,41 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
sentry-sanitizer (0.
|
|
5
|
-
sentry-ruby (>= 5.3, <
|
|
4
|
+
sentry-sanitizer (0.9.0)
|
|
5
|
+
sentry-ruby (>= 5.3, < 8.0.0)
|
|
6
6
|
|
|
7
7
|
GEM
|
|
8
8
|
remote: https://rubygems.org/
|
|
9
9
|
specs:
|
|
10
|
+
activesupport (8.1.4)
|
|
11
|
+
base64
|
|
12
|
+
bigdecimal
|
|
13
|
+
concurrent-ruby (~> 1.0, >= 1.3.1)
|
|
14
|
+
connection_pool (>= 2.2.5)
|
|
15
|
+
drb
|
|
16
|
+
i18n (>= 1.6, < 2)
|
|
17
|
+
json
|
|
18
|
+
logger (>= 1.4.2)
|
|
19
|
+
minitest (>= 5.1)
|
|
20
|
+
securerandom (>= 0.3)
|
|
21
|
+
tzinfo (~> 2.0, >= 2.0.5)
|
|
22
|
+
uri (>= 0.13.1)
|
|
10
23
|
ast (2.4.3)
|
|
11
24
|
base64 (0.3.0)
|
|
12
|
-
bigdecimal (
|
|
13
|
-
|
|
25
|
+
bigdecimal (4.1.3)
|
|
26
|
+
cgi (0.5.2)
|
|
27
|
+
concurrent-ruby (1.3.8)
|
|
28
|
+
connection_pool (3.0.2)
|
|
14
29
|
diff-lcs (1.5.0)
|
|
15
30
|
docile (1.4.0)
|
|
31
|
+
drb (2.2.3)
|
|
32
|
+
i18n (1.15.2)
|
|
33
|
+
concurrent-ruby (~> 1.0)
|
|
34
|
+
json (3.0.2)
|
|
35
|
+
logger (1.7.0)
|
|
36
|
+
minitest (6.0.6)
|
|
37
|
+
drb (~> 2.0)
|
|
38
|
+
prism (~> 1.5)
|
|
16
39
|
parallel (1.27.0)
|
|
17
40
|
parser (3.3.10.0)
|
|
18
41
|
ast (~> 2.4.1)
|
|
@@ -50,25 +73,34 @@ GEM
|
|
|
50
73
|
parser (>= 3.3.7.2)
|
|
51
74
|
prism (~> 1.4)
|
|
52
75
|
ruby-progressbar (1.13.0)
|
|
53
|
-
|
|
76
|
+
securerandom (0.4.1)
|
|
77
|
+
sentry-ruby (6.7.0)
|
|
54
78
|
bigdecimal
|
|
55
79
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
80
|
+
logger
|
|
56
81
|
simplecov (0.18.5)
|
|
57
82
|
docile (~> 1.1)
|
|
58
83
|
simplecov-html (~> 0.11)
|
|
59
84
|
simplecov-html (0.12.3)
|
|
85
|
+
tzinfo (2.0.6)
|
|
86
|
+
concurrent-ruby (~> 1.0)
|
|
60
87
|
unicode-display_width (2.6.0)
|
|
88
|
+
uri (1.1.2)
|
|
61
89
|
|
|
62
90
|
PLATFORMS
|
|
63
91
|
ruby
|
|
64
92
|
|
|
65
93
|
DEPENDENCIES
|
|
94
|
+
activesupport (~> 8.0)
|
|
66
95
|
base64
|
|
67
96
|
bundler (>= 2.3)
|
|
97
|
+
cgi
|
|
98
|
+
logger
|
|
68
99
|
rack
|
|
69
100
|
rake (~> 12)
|
|
70
101
|
rspec (~> 3.0)
|
|
71
102
|
rubocop (~> 1.28.2)
|
|
103
|
+
sentry-ruby (~> 6.0)
|
|
72
104
|
sentry-sanitizer!
|
|
73
105
|
simplecov
|
|
74
106
|
|
data/README.md
CHANGED
|
@@ -40,22 +40,27 @@ Add following lines to your Sentry configuration:
|
|
|
40
40
|
Sentry.init do |config|
|
|
41
41
|
# ... your configuration
|
|
42
42
|
|
|
43
|
-
#
|
|
43
|
+
# Mask same fields as Rails does
|
|
44
44
|
config.sanitize.fields = Rails.application.config.filter_parameters
|
|
45
|
-
|
|
46
|
-
# You can also pass custom array
|
|
45
|
+
# Or pass custom fields
|
|
47
46
|
config.sanitize.fields = %w[password super_secret_token]
|
|
48
47
|
|
|
48
|
+
# Use custom filter (e.g. from activesupport).
|
|
49
|
+
# Must implement #filter(array_or_hash) and #filter_param(key, value)
|
|
50
|
+
# Don't set 'config.sanitize.fields' if using this.
|
|
51
|
+
config.sanitize.filter = ActiveSupport::ParameterFilter.new(
|
|
52
|
+
Rails.application.config.filter_parameters, mask: "[FILTERED]"
|
|
53
|
+
)
|
|
54
|
+
|
|
49
55
|
# HTTP headers can be sanitized too (it is case insensitive)
|
|
50
56
|
config.sanitize.http_headers = %w[Authorization X-Xsrf-Token]
|
|
51
|
-
|
|
52
|
-
# You can sanitize all HTTP headers with setting `true` value
|
|
57
|
+
# Mask all headers
|
|
53
58
|
config.sanitize.http_headers = true
|
|
54
59
|
|
|
55
|
-
#
|
|
60
|
+
# Mask all cookies
|
|
56
61
|
config.sanitize.cookies = true
|
|
57
62
|
|
|
58
|
-
#
|
|
63
|
+
# Parse and sanitize request query string
|
|
59
64
|
config.sanitize.query_string = true
|
|
60
65
|
|
|
61
66
|
# Sanitize breadcrumbs data[:body] payload (Setry::Net:HTTP)
|
data/bin/bundle
CHANGED
|
@@ -14,31 +14,31 @@ m = Module.new do
|
|
|
14
14
|
module_function
|
|
15
15
|
|
|
16
16
|
def invoked_as_script?
|
|
17
|
-
File.expand_path($
|
|
17
|
+
File.expand_path($PROGRAM_NAME) == File.expand_path(__FILE__)
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
def env_var_version
|
|
21
|
-
ENV
|
|
21
|
+
ENV.fetch("BUNDLER_VERSION", nil)
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
def cli_arg_version
|
|
25
25
|
return unless invoked_as_script? # don't want to hijack other binstubs
|
|
26
26
|
return unless "update".start_with?(ARGV.first || " ") # must be running `bundle update`
|
|
27
|
+
|
|
27
28
|
bundler_version = nil
|
|
28
29
|
update_index = nil
|
|
29
30
|
ARGV.each_with_index do |a, i|
|
|
30
|
-
if update_index && update_index.succ == i && a =~ Gem::Version::ANCHORED_VERSION_PATTERN
|
|
31
|
-
bundler_version = a
|
|
32
|
-
end
|
|
31
|
+
bundler_version = a if update_index && update_index.succ == i && a =~ Gem::Version::ANCHORED_VERSION_PATTERN
|
|
33
32
|
next unless a =~ /\A--bundler(?:[= ](#{Gem::Version::VERSION_PATTERN}))?\z/
|
|
34
|
-
|
|
33
|
+
|
|
34
|
+
bundler_version = Regexp.last_match(1)
|
|
35
35
|
update_index = i
|
|
36
36
|
end
|
|
37
37
|
bundler_version
|
|
38
38
|
end
|
|
39
39
|
|
|
40
40
|
def gemfile
|
|
41
|
-
gemfile = ENV
|
|
41
|
+
gemfile = ENV.fetch("BUNDLE_GEMFILE", nil)
|
|
42
42
|
return gemfile if gemfile && !gemfile.empty?
|
|
43
43
|
|
|
44
44
|
File.expand_path("../Gemfile", __dir__)
|
|
@@ -55,15 +55,17 @@ m = Module.new do
|
|
|
55
55
|
|
|
56
56
|
def lockfile_version
|
|
57
57
|
return unless File.file?(lockfile)
|
|
58
|
+
|
|
58
59
|
lockfile_contents = File.read(lockfile)
|
|
59
60
|
return unless lockfile_contents =~ /\n\nBUNDLED WITH\n\s{2,}(#{Gem::Version::VERSION_PATTERN})\n/
|
|
61
|
+
|
|
60
62
|
Regexp.last_match(1)
|
|
61
63
|
end
|
|
62
64
|
|
|
63
65
|
def bundler_requirement
|
|
64
66
|
@bundler_requirement ||=
|
|
65
67
|
env_var_version || cli_arg_version ||
|
|
66
|
-
|
|
68
|
+
bundler_requirement_for(lockfile_version)
|
|
67
69
|
end
|
|
68
70
|
|
|
69
71
|
def bundler_requirement_for(version)
|
|
@@ -91,10 +93,12 @@ m = Module.new do
|
|
|
91
93
|
gem "bundler", bundler_requirement
|
|
92
94
|
end
|
|
93
95
|
return if gem_error.nil?
|
|
96
|
+
|
|
94
97
|
require_error = activation_error_handling do
|
|
95
98
|
require "bundler/version"
|
|
96
99
|
end
|
|
97
100
|
return if require_error.nil? && Gem::Requirement.new(bundler_requirement).satisfied_by?(Gem::Version.new(Bundler::VERSION))
|
|
101
|
+
|
|
98
102
|
warn "Activating bundler (#{bundler_requirement}) failed:\n#{gem_error.message}\n\nTo install the version of bundler this project requires, run `gem install bundler -v '#{bundler_requirement}'`"
|
|
99
103
|
exit 42
|
|
100
104
|
end
|
|
@@ -109,6 +113,4 @@ end
|
|
|
109
113
|
|
|
110
114
|
m.load_bundler!
|
|
111
115
|
|
|
112
|
-
if m.invoked_as_script?
|
|
113
|
-
load Gem.bin_path("bundler", "bundle")
|
|
114
|
-
end
|
|
116
|
+
load Gem.bin_path("bundler", "bundle") if m.invoked_as_script?
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "json"
|
|
4
|
+
require "sentry/sanitizer/filter"
|
|
4
5
|
|
|
5
6
|
module Sentry
|
|
6
7
|
module Sanitizer
|
|
7
8
|
class Cleaner
|
|
8
|
-
DEFAULT_MASK = "[FILTERED]"
|
|
9
9
|
DEFAULT_SENSITIVE_HEADERS = %w[
|
|
10
10
|
Authorization
|
|
11
11
|
X-Xsrf-Token
|
|
@@ -14,11 +14,16 @@ module Sentry
|
|
|
14
14
|
private_constant :DEFAULT_SENSITIVE_HEADERS
|
|
15
15
|
|
|
16
16
|
def initialize(config)
|
|
17
|
-
@
|
|
17
|
+
@filter = config.filter || Filter.new(config.fields, mask: config.mask)
|
|
18
|
+
|
|
18
19
|
@http_headers = config.http_headers || DEFAULT_SENSITIVE_HEADERS
|
|
20
|
+
@headers_filter = Filter.new(@http_headers, mask: config.mask) if @http_headers.is_a?(Array)
|
|
21
|
+
|
|
19
22
|
@do_cookies = config.cookies || false
|
|
20
23
|
@do_query_string = config.query_string || false
|
|
21
|
-
|
|
24
|
+
|
|
25
|
+
@mask = config.mask || Filter::DEFAULT_MASK
|
|
26
|
+
|
|
22
27
|
@breadcrumbs_json_data_fields = config.breadcrumbs.json_data_fields || []
|
|
23
28
|
end
|
|
24
29
|
|
|
@@ -79,20 +84,23 @@ module Sentry
|
|
|
79
84
|
# ignore
|
|
80
85
|
end
|
|
81
86
|
|
|
82
|
-
def sanitize_data(
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
+
def sanitize_data(data)
|
|
88
|
+
case data
|
|
89
|
+
when Hash, Array
|
|
90
|
+
filter.filter(data)
|
|
91
|
+
else
|
|
92
|
+
data
|
|
93
|
+
end
|
|
87
94
|
end
|
|
88
95
|
|
|
89
96
|
private
|
|
90
97
|
|
|
91
|
-
attr_reader :
|
|
98
|
+
attr_reader :filter,
|
|
99
|
+
:headers_filter,
|
|
100
|
+
:mask,
|
|
92
101
|
:http_headers,
|
|
93
102
|
:do_cookies,
|
|
94
103
|
:do_query_string,
|
|
95
|
-
:mask,
|
|
96
104
|
:breadcrumbs_json_data_fields
|
|
97
105
|
|
|
98
106
|
# Sanitize specified headers
|
|
@@ -101,15 +109,7 @@ module Sentry
|
|
|
101
109
|
when TrueClass
|
|
102
110
|
headers.transform_values { mask }
|
|
103
111
|
when Array
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
http_headers_regex = sensitive_regexp(http_headers)
|
|
107
|
-
|
|
108
|
-
headers.keys.select { |key| key.match?(http_headers_regex) }.each do |key|
|
|
109
|
-
headers[key] = mask
|
|
110
|
-
end
|
|
111
|
-
|
|
112
|
-
headers
|
|
112
|
+
headers_filter.filter(headers)
|
|
113
113
|
else
|
|
114
114
|
headers
|
|
115
115
|
end
|
|
@@ -125,59 +125,28 @@ module Sentry
|
|
|
125
125
|
|
|
126
126
|
def sanitize_query_string(query_string)
|
|
127
127
|
return query_string unless do_query_string
|
|
128
|
-
return query_string unless query_string.is_a? String
|
|
129
|
-
|
|
130
|
-
sanitized_array = query_string.split("&").map do |kv_pair|
|
|
131
|
-
k, v = kv_pair.split("=")
|
|
132
|
-
new_v = sanitize_string(k, v)
|
|
133
|
-
|
|
134
|
-
"#{k}=#{new_v}"
|
|
135
|
-
end
|
|
136
128
|
|
|
137
|
-
|
|
138
|
-
end
|
|
139
|
-
|
|
140
|
-
def sanitize_value(value, key)
|
|
141
|
-
case value
|
|
142
|
-
when Hash
|
|
143
|
-
sanitize_hash(key, value)
|
|
144
|
-
when Array
|
|
145
|
-
sanitize_array(key, value)
|
|
129
|
+
case query_string
|
|
146
130
|
when String
|
|
147
|
-
|
|
131
|
+
sanitize_query_string_from_string(query_string)
|
|
132
|
+
when Hash
|
|
133
|
+
sanitize_data(query_string)
|
|
148
134
|
else
|
|
149
|
-
|
|
135
|
+
query_string
|
|
150
136
|
end
|
|
151
137
|
end
|
|
152
138
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
value.merge!(value) { |k, v| sanitize_value(v, k) }
|
|
160
|
-
end
|
|
161
|
-
end
|
|
139
|
+
# sentry-ruby >= 7 populates Request#query_string as a Hash (from Rack's
|
|
140
|
+
# parsed request.GET) instead of the raw query string.
|
|
141
|
+
def sanitize_query_string_from_string(query_string)
|
|
142
|
+
sanitized_array = query_string.split("&").map do |kv_pair|
|
|
143
|
+
k, v = kv_pair.split("=")
|
|
144
|
+
new_v = filter.filter_param(k, v)
|
|
162
145
|
|
|
163
|
-
|
|
164
|
-
if value.frozen?
|
|
165
|
-
value.map { |val| sanitize_value(val, key) }
|
|
166
|
-
else
|
|
167
|
-
value.map! { |val| sanitize_value(val, key) }
|
|
146
|
+
"#{k}=#{new_v}"
|
|
168
147
|
end
|
|
169
|
-
end
|
|
170
148
|
|
|
171
|
-
|
|
172
|
-
key&.match?(sensitive_fields) ? mask : value
|
|
173
|
-
end
|
|
174
|
-
|
|
175
|
-
def sensitive_fields
|
|
176
|
-
@sensitive_fields ||= sensitive_regexp(fields)
|
|
177
|
-
end
|
|
178
|
-
|
|
179
|
-
def sensitive_regexp(fields)
|
|
180
|
-
Regexp.new(fields.map { |field| "\\b#{field}\\b" }.join("|"), "i")
|
|
149
|
+
sanitized_array.join("&")
|
|
181
150
|
end
|
|
182
151
|
end
|
|
183
152
|
end
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
require "sentry/configuration"
|
|
4
4
|
require "sentry/sanitizer/cleaner"
|
|
5
|
+
require "sentry/sanitizer/filter"
|
|
5
6
|
require "sentry/sanitizer/configuration_mixin"
|
|
6
7
|
|
|
7
8
|
module Sentry
|
|
@@ -43,6 +44,7 @@ module Sentry
|
|
|
43
44
|
end
|
|
44
45
|
|
|
45
46
|
attr_reader :fields,
|
|
47
|
+
:filter,
|
|
46
48
|
:http_headers,
|
|
47
49
|
:cookies,
|
|
48
50
|
:query_string,
|
|
@@ -51,6 +53,7 @@ module Sentry
|
|
|
51
53
|
def configured?
|
|
52
54
|
[
|
|
53
55
|
fields,
|
|
56
|
+
filter,
|
|
54
57
|
http_headers,
|
|
55
58
|
cookies,
|
|
56
59
|
query_string,
|
|
@@ -63,11 +66,22 @@ module Sentry
|
|
|
63
66
|
end
|
|
64
67
|
|
|
65
68
|
def fields=(fields)
|
|
66
|
-
raise ArgumentError, "
|
|
69
|
+
raise ArgumentError, "fields must be array" unless fields.is_a? Array
|
|
70
|
+
raise ArgumentError, "specify either 'fields' or 'filter'" if filter
|
|
67
71
|
|
|
68
72
|
@fields = fields
|
|
69
73
|
end
|
|
70
74
|
|
|
75
|
+
def filter=(filter)
|
|
76
|
+
methods = Sanitizer::Filter.instance_methods(false)
|
|
77
|
+
implements = methods.all? { |method| filter.respond_to?(method) }
|
|
78
|
+
raise ArgumentError, "specify either 'fields' or 'filter'" if fields
|
|
79
|
+
raise ArgumentError, "mask can't be used when 'filter' is set" if mask
|
|
80
|
+
raise ArgumentError, "filter must implement #{methods.join(', ')}" unless implements
|
|
81
|
+
|
|
82
|
+
@filter = filter
|
|
83
|
+
end
|
|
84
|
+
|
|
71
85
|
def http_headers=(headers)
|
|
72
86
|
raise ArgumentError, "sanitize_http_headers must be array" unless [Array, TrueClass, FalseClass].include?(headers.class)
|
|
73
87
|
|
|
@@ -88,6 +102,7 @@ module Sentry
|
|
|
88
102
|
|
|
89
103
|
def mask=(mask)
|
|
90
104
|
raise ArgumentError, "mask must be string" unless mask.is_a?(String)
|
|
105
|
+
raise ArgumentError, "mask can't be used when 'filter' is set" if filter
|
|
91
106
|
|
|
92
107
|
@mask = mask
|
|
93
108
|
end
|
|
@@ -28,7 +28,7 @@ module Sentry
|
|
|
28
28
|
#
|
|
29
29
|
# @param [nil, #call] value
|
|
30
30
|
#
|
|
31
|
-
def before_breadcrumb=(value)
|
|
31
|
+
def before_breadcrumb=(value)
|
|
32
32
|
raise ArgumentError, "before_breadcrumb must be callable (or nil to disable)" unless value.nil? || value == false || value.respond_to?(:call)
|
|
33
33
|
|
|
34
34
|
return unless value
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Sentry
|
|
4
|
+
module Sanitizer
|
|
5
|
+
class Filter
|
|
6
|
+
DEFAULT_MASK = "[FILTERED]"
|
|
7
|
+
|
|
8
|
+
def initialize(fields, mask: nil)
|
|
9
|
+
@filters = compile_filters(fields || [])
|
|
10
|
+
@mask = mask || DEFAULT_MASK
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def filter(params)
|
|
14
|
+
filters.nil? ? params : sanitize_value(nil, params)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def filter_param(key, value)
|
|
18
|
+
filters.nil? ? value : sanitize_value(key, value)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
attr_reader :mask, :filters
|
|
24
|
+
|
|
25
|
+
def compile_filters(fields)
|
|
26
|
+
return nil if fields.size.zero?
|
|
27
|
+
|
|
28
|
+
Regexp.new(fields.map { |field| "\\b#{field}\\b" }.join("|"), "i")
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def sanitize_value(key, value)
|
|
32
|
+
return mask if key&.match?(filters)
|
|
33
|
+
|
|
34
|
+
case value
|
|
35
|
+
when Hash
|
|
36
|
+
if value.frozen?
|
|
37
|
+
value.merge(value) { |k, v| sanitize_value(k, v) }
|
|
38
|
+
else
|
|
39
|
+
value.merge!(value) { |k, v| sanitize_value(k, v) }
|
|
40
|
+
end
|
|
41
|
+
when Array
|
|
42
|
+
if value.frozen?
|
|
43
|
+
value.map { |v| sanitize_value(key, v) }
|
|
44
|
+
else
|
|
45
|
+
value.map! { |v| sanitize_value(key, v) }
|
|
46
|
+
end
|
|
47
|
+
else
|
|
48
|
+
value
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
data/sentry-sanitizer.gemspec
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: sentry-sanitizer
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.9.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Valentine Kiselev
|
|
@@ -18,7 +18,7 @@ dependencies:
|
|
|
18
18
|
version: '5.3'
|
|
19
19
|
- - "<"
|
|
20
20
|
- !ruby/object:Gem::Version
|
|
21
|
-
version:
|
|
21
|
+
version: 8.0.0
|
|
22
22
|
type: :runtime
|
|
23
23
|
prerelease: false
|
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -28,7 +28,7 @@ dependencies:
|
|
|
28
28
|
version: '5.3'
|
|
29
29
|
- - "<"
|
|
30
30
|
- !ruby/object:Gem::Version
|
|
31
|
-
version:
|
|
31
|
+
version: 8.0.0
|
|
32
32
|
description: Add missing sanitizing support for sentry-ruby (previous sentry-raven)
|
|
33
33
|
email:
|
|
34
34
|
- mrexox@outlook.com
|
|
@@ -59,6 +59,7 @@ files:
|
|
|
59
59
|
- lib/sentry/sanitizer/cleaner.rb
|
|
60
60
|
- lib/sentry/sanitizer/configuration.rb
|
|
61
61
|
- lib/sentry/sanitizer/configuration_mixin.rb
|
|
62
|
+
- lib/sentry/sanitizer/filter.rb
|
|
62
63
|
- lib/sentry/sanitizer/version.rb
|
|
63
64
|
- sentry-sanitizer.gemspec
|
|
64
65
|
- tea.yml
|