blouson 5.0.0 → 6.0.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.yml +2 -1
- data/CHANGELOG.md +5 -0
- data/README.md +3 -18
- data/blouson.gemspec +1 -2
- data/lib/blouson/sentry_parameter_filter.rb +34 -29
- data/lib/blouson/version.rb +1 -1
- metadata +4 -19
- data/lib/blouson/raven_parameter_filter_processor.rb +0 -88
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: adc6299d9334a783b803177c762f1263d3c1d405afac264dc9a411489d8c46ce
|
|
4
|
+
data.tar.gz: 50f19f86deb3f1c5b2e15d0e857f58505f50c0e5e84ecd855e10b1b018cfcfaf
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0edfa038be2f40514ea2056e3373c7e5203776a44e180bc7df113a4ea4cf7575aff72ca5dd777f6f1dfbde6b85015a2837a62537be1a9b6be1d37d91967bc885
|
|
7
|
+
data.tar.gz: d00e5fdb01fdcec9e6c46b6d5e079f826b6ae1b20ec2744f12cf5aa79833d933bced087196a4da7ce23f2198d8245ca10396b6f59cf858440b6d8250b155ee82
|
data/.github/workflows/ci.yml
CHANGED
|
@@ -15,6 +15,7 @@ jobs:
|
|
|
15
15
|
- '3.2'
|
|
16
16
|
- '3.3'
|
|
17
17
|
- '3.4'
|
|
18
|
+
- '4.0'
|
|
18
19
|
gemfile:
|
|
19
20
|
- rails_7.1
|
|
20
21
|
- rails_7.2
|
|
@@ -42,7 +43,7 @@ jobs:
|
|
|
42
43
|
env:
|
|
43
44
|
BUNDLE_GEMFILE: ${{ github.workspace }}/gemfiles/${{ matrix.gemfile }}.gemfile
|
|
44
45
|
steps:
|
|
45
|
-
- uses: actions/checkout@
|
|
46
|
+
- uses: actions/checkout@v6
|
|
46
47
|
- uses: ruby/setup-ruby@v1
|
|
47
48
|
with:
|
|
48
49
|
ruby-version: ${{ matrix.ruby }}
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
# 6.0.0 (2026-03-31)
|
|
2
|
+
- [Breaking change] Drop `to_hash` in SentryParameterFilter to support sentry-ruby v6. This change also drops support for sentry-ruby <= v5. Please upgrade the gem and update your Sentry initializer if it uses `filter.process(event.to_hash)`.
|
|
3
|
+
- [Breaking change] Remove sentry-raven support
|
|
4
|
+
- Add Ruby 4.0 to CI
|
|
5
|
+
|
|
1
6
|
# 5.0.0 (2026-01-23)
|
|
2
7
|
- [Breaking change] Drop support for Ruby 3.0
|
|
3
8
|
- [Breaking change] Drop support for Rails 7.0
|
data/README.md
CHANGED
|
@@ -7,7 +7,7 @@ Blouson is a filter tool for Rails to conceal sensitive data from various logs.
|
|
|
7
7
|
- HTTP Request parameters in Rails log
|
|
8
8
|
- SQL query in Rails log
|
|
9
9
|
- Exception messages in `ActiveRecord::StatementInvalid`
|
|
10
|
-
- Sentry
|
|
10
|
+
- Sentry parameters
|
|
11
11
|
- Mail parameters in Rails log
|
|
12
12
|
|
|
13
13
|
## Installation
|
|
@@ -81,28 +81,13 @@ Sentry.init do |config|
|
|
|
81
81
|
filter = Blouson::SentryParameterFilter.new(filter_pattern, secure_headers)
|
|
82
82
|
|
|
83
83
|
config.before_send = lambda do |event, _hint|
|
|
84
|
-
filter.process(event
|
|
84
|
+
filter.process(event)
|
|
85
85
|
end
|
|
86
86
|
end
|
|
87
87
|
|
|
88
88
|
```
|
|
89
89
|
|
|
90
|
-
|
|
91
|
-
Blouson provides an [Raven-Ruby](https://github.com/getsentry/raven-ruby) processor to conceal sensitive data from query string, request body, request headers and cookie values.
|
|
92
|
-
|
|
93
|
-
```ruby
|
|
94
|
-
require 'blouson/raven_parameter_filter_processor'
|
|
95
|
-
|
|
96
|
-
filter_pattern = Rails.application.config.filter_parameters
|
|
97
|
-
secure_headers = %w(secret_token)
|
|
98
|
-
|
|
99
|
-
Raven.configure do |config|
|
|
100
|
-
...
|
|
101
|
-
config.processors << Blouson::RavenParameterFilterProcessor.create(filter_pattern, secure_headers)
|
|
102
|
-
...
|
|
103
|
-
end
|
|
104
|
-
```
|
|
105
|
-
|
|
90
|
+
**Note:** Since sentry-ruby v6, `event.to_hash` is no longer available. Pass `event` directly to `filter.process` instead of `filter.process(event.to_hash)`.
|
|
106
91
|
|
|
107
92
|
### SensitiveMailLogFilter
|
|
108
93
|
ActionMailer outputs email address, all headers, and body text to the log when sending email.
|
data/blouson.gemspec
CHANGED
|
@@ -26,8 +26,7 @@ Gem::Specification.new do |spec|
|
|
|
26
26
|
spec.add_development_dependency 'arproxy', '>= 1.0.0'
|
|
27
27
|
spec.add_development_dependency 'mysql2'
|
|
28
28
|
spec.add_development_dependency 'pry'
|
|
29
|
-
spec.add_development_dependency 'sentry-
|
|
30
|
-
spec.add_development_dependency 'sentry-ruby'
|
|
29
|
+
spec.add_development_dependency 'sentry-ruby', '>= 6.0'
|
|
31
30
|
|
|
32
31
|
spec.add_development_dependency 'appraisal'
|
|
33
32
|
spec.add_development_dependency "bundler", ">= 1.14"
|
|
@@ -17,53 +17,58 @@ module Blouson
|
|
|
17
17
|
private
|
|
18
18
|
|
|
19
19
|
def process_request_body(event)
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
event[:request][:data] = @parameter_filter.filter(data)
|
|
20
|
+
req = event.request
|
|
21
|
+
return unless req && req.data.present?
|
|
22
|
+
|
|
23
|
+
data = req.data
|
|
24
|
+
if data.is_a?(String)
|
|
25
|
+
# Maybe JSON request
|
|
26
|
+
begin
|
|
27
|
+
data = JSON.parse(data)
|
|
28
|
+
req.data = JSON.dump(@parameter_filter.filter(data))
|
|
29
|
+
rescue JSON::ParserError => e
|
|
30
|
+
# Record parser error to extra field
|
|
31
|
+
event.extra['BlousonError'] = e.message
|
|
33
32
|
end
|
|
33
|
+
else
|
|
34
|
+
req.data = @parameter_filter.filter(data)
|
|
34
35
|
end
|
|
35
36
|
end
|
|
36
37
|
|
|
37
38
|
def process_query_string(event)
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
filtered = @parameter_filter.filter(query)
|
|
39
|
+
req = event.request
|
|
40
|
+
return unless req && req.query_string.present?
|
|
41
41
|
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
query = Rack::Utils.parse_query(req.query_string)
|
|
43
|
+
filtered = @parameter_filter.filter(query)
|
|
44
|
+
|
|
45
|
+
req.query_string = Rack::Utils.build_query(filtered)
|
|
44
46
|
end
|
|
45
47
|
|
|
46
48
|
def process_request_header(event)
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
49
|
+
req = event.request
|
|
50
|
+
return unless req && req.headers
|
|
51
|
+
|
|
52
|
+
req.headers.each_key do |k|
|
|
53
|
+
if @header_filters.include?(k.downcase)
|
|
54
|
+
req.headers[k] = 'FILTERED'
|
|
53
55
|
end
|
|
54
56
|
end
|
|
55
57
|
end
|
|
56
58
|
|
|
57
59
|
def process_cookie(event)
|
|
58
|
-
|
|
59
|
-
|
|
60
|
+
req = event.request
|
|
61
|
+
return unless req
|
|
62
|
+
|
|
63
|
+
if req.cookies
|
|
64
|
+
req.cookies = @parameter_filter.filter(req.cookies)
|
|
60
65
|
end
|
|
61
66
|
|
|
62
|
-
if
|
|
63
|
-
cookies = Hash[
|
|
67
|
+
if req.headers && req.headers['Cookie']
|
|
68
|
+
cookies = Hash[req.headers['Cookie'].split('; ').map { |pair| pair.split('=', 2) }]
|
|
64
69
|
filtered = @parameter_filter.filter(cookies)
|
|
65
70
|
|
|
66
|
-
|
|
71
|
+
req.headers['Cookie'] = filtered.map { |pair| pair.join('=') }.join('; ')
|
|
67
72
|
end
|
|
68
73
|
end
|
|
69
74
|
end
|
data/lib/blouson/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: blouson
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 6.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Cookpad Inc.
|
|
@@ -65,34 +65,20 @@ dependencies:
|
|
|
65
65
|
- - ">="
|
|
66
66
|
- !ruby/object:Gem::Version
|
|
67
67
|
version: '0'
|
|
68
|
-
- !ruby/object:Gem::Dependency
|
|
69
|
-
name: sentry-raven
|
|
70
|
-
requirement: !ruby/object:Gem::Requirement
|
|
71
|
-
requirements:
|
|
72
|
-
- - ">="
|
|
73
|
-
- !ruby/object:Gem::Version
|
|
74
|
-
version: '0'
|
|
75
|
-
type: :development
|
|
76
|
-
prerelease: false
|
|
77
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
78
|
-
requirements:
|
|
79
|
-
- - ">="
|
|
80
|
-
- !ruby/object:Gem::Version
|
|
81
|
-
version: '0'
|
|
82
68
|
- !ruby/object:Gem::Dependency
|
|
83
69
|
name: sentry-ruby
|
|
84
70
|
requirement: !ruby/object:Gem::Requirement
|
|
85
71
|
requirements:
|
|
86
72
|
- - ">="
|
|
87
73
|
- !ruby/object:Gem::Version
|
|
88
|
-
version: '0'
|
|
74
|
+
version: '6.0'
|
|
89
75
|
type: :development
|
|
90
76
|
prerelease: false
|
|
91
77
|
version_requirements: !ruby/object:Gem::Requirement
|
|
92
78
|
requirements:
|
|
93
79
|
- - ">="
|
|
94
80
|
- !ruby/object:Gem::Version
|
|
95
|
-
version: '0'
|
|
81
|
+
version: '6.0'
|
|
96
82
|
- !ruby/object:Gem::Dependency
|
|
97
83
|
name: appraisal
|
|
98
84
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -174,7 +160,6 @@ files:
|
|
|
174
160
|
- gemfiles/rails_8.1.gemfile
|
|
175
161
|
- lib/blouson.rb
|
|
176
162
|
- lib/blouson/engine.rb
|
|
177
|
-
- lib/blouson/raven_parameter_filter_processor.rb
|
|
178
163
|
- lib/blouson/sensitive_mail_log_filter.rb
|
|
179
164
|
- lib/blouson/sensitive_params_silencer.rb
|
|
180
165
|
- lib/blouson/sensitive_query_filter.rb
|
|
@@ -200,7 +185,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
200
185
|
- !ruby/object:Gem::Version
|
|
201
186
|
version: '0'
|
|
202
187
|
requirements: []
|
|
203
|
-
rubygems_version:
|
|
188
|
+
rubygems_version: 3.6.9
|
|
204
189
|
specification_version: 4
|
|
205
190
|
summary: Filter tools to mask sensitive data in various logs
|
|
206
191
|
test_files: []
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
module Blouson
|
|
2
|
-
class RavenParameterFilterProcessor
|
|
3
|
-
def self.create(filters, header_filters)
|
|
4
|
-
Class.new(Raven::Processor) do
|
|
5
|
-
@filters = filters
|
|
6
|
-
@header_filters = header_filters.map(&:downcase)
|
|
7
|
-
|
|
8
|
-
def self.filters
|
|
9
|
-
@filters
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
def self.header_filters
|
|
13
|
-
@header_filters
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def initialize(client = nil)
|
|
17
|
-
# ActionDispatch::Http::ParameterFilter is deprecated and will be removed from Rails 6.1.
|
|
18
|
-
parameter_filter_klass = if defined?(ActiveSupport::ParameterFilter)
|
|
19
|
-
ActiveSupport::ParameterFilter
|
|
20
|
-
else
|
|
21
|
-
ActionDispatch::Http::ParameterFilter
|
|
22
|
-
end
|
|
23
|
-
@parameter_filter = parameter_filter_klass.new(self.class.filters)
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
def process(value)
|
|
27
|
-
process_query_string(value)
|
|
28
|
-
process_request_body(value)
|
|
29
|
-
process_request_header(value)
|
|
30
|
-
process_cookie(value)
|
|
31
|
-
ensure
|
|
32
|
-
return value
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def process_request_body(value)
|
|
36
|
-
if value[:request] && value[:request][:data].present?
|
|
37
|
-
data = value[:request][:data]
|
|
38
|
-
if data.is_a?(String)
|
|
39
|
-
# Maybe JSON request
|
|
40
|
-
begin
|
|
41
|
-
data = JSON.parse(data)
|
|
42
|
-
value[:request][:data] = JSON.dump(@parameter_filter.filter(data))
|
|
43
|
-
rescue JSON::ParserError => e
|
|
44
|
-
# Record parser error to extra field
|
|
45
|
-
value[:extra]['BlousonError'] = e.message
|
|
46
|
-
end
|
|
47
|
-
else
|
|
48
|
-
value[:request][:data] = @parameter_filter.filter(data)
|
|
49
|
-
end
|
|
50
|
-
end
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
def process_query_string(value)
|
|
54
|
-
if value[:request] && value[:request][:query_string].present?
|
|
55
|
-
query = Rack::Utils.parse_query(value[:request][:query_string])
|
|
56
|
-
filtered = @parameter_filter.filter(query)
|
|
57
|
-
|
|
58
|
-
value[:request][:query_string] = Rack::Utils.build_query(filtered)
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
def process_request_header(value)
|
|
63
|
-
if value[:request] && value[:request][:headers]
|
|
64
|
-
headers = value[:request][:headers]
|
|
65
|
-
headers.each_key do |k|
|
|
66
|
-
if self.class.header_filters.include?(k.downcase)
|
|
67
|
-
headers[k] = 'FILTERED'
|
|
68
|
-
end
|
|
69
|
-
end
|
|
70
|
-
end
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
def process_cookie(value)
|
|
74
|
-
if (cookies = value.dig(:request, :cookies))
|
|
75
|
-
value[:request][:cookies] = @parameter_filter.filter(cookies)
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
if value[:request] && value[:request][:headers] && value[:request][:headers]['Cookie']
|
|
79
|
-
cookies = Hash[value[:request][:headers]['Cookie'].split('; ').map { |pair| pair.split('=', 2) }]
|
|
80
|
-
filtered = @parameter_filter.filter(cookies)
|
|
81
|
-
|
|
82
|
-
value[:request][:headers]['Cookie'] = filtered.map { |pair| pair.join('=') }.join('; ')
|
|
83
|
-
end
|
|
84
|
-
end
|
|
85
|
-
end
|
|
86
|
-
end
|
|
87
|
-
end
|
|
88
|
-
end
|