sensitive_data_filter 0.1.0 → 0.2.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/.rubocop.yml +3 -0
- data/CHANGELOG.md +15 -0
- data/README.md +38 -11
- data/gemfiles/Gemfile.ruby-2.1.rb +2 -0
- data/gemfiles/Gemfile.ruby-2.2.rb +2 -0
- data/lib/sensitive_data_filter/config.rb +5 -0
- data/lib/sensitive_data_filter/mask.rb +7 -3
- data/lib/sensitive_data_filter/middleware.rb +1 -1
- data/lib/sensitive_data_filter/middleware/env_filter.rb +10 -4
- data/lib/sensitive_data_filter/middleware/env_parser.rb +19 -6
- data/lib/sensitive_data_filter/middleware/occurrence.rb +22 -11
- data/lib/sensitive_data_filter/middleware/parameter_parser.rb +48 -0
- data/lib/sensitive_data_filter/scan.rb +22 -9
- data/lib/sensitive_data_filter/types/credit_card.rb +3 -35
- data/lib/sensitive_data_filter/version.rb +1 -1
- data/sensitive_data_filter.gemspec +1 -0
- metadata +17 -3
- data/lib/sensitive_data_filter/middleware/parameter_scanner.rb +0 -22
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 70cedcd682fd58e3d8682c603bc8326c36e7b8ec
|
4
|
+
data.tar.gz: aee8dcf45f48b651e85507a6d0e0b02fe8fbb071
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fc6618c4cdad98edb6899779d93b15a1cbfc5c8b650d2cce604f40b2c9178d24cf9000753ecf512ee82b99a17e580f8750cf3019ac6f0777532a417d32ffc8d9
|
7
|
+
data.tar.gz: 1f126f0eec67bc0c8bc74d7bb50e6121056a8113ce35454ba2fc7d1c36d6db74ede0736050515b96e53467d433844f6eef1a545554a01d58898fef0d117bf9eb
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -3,6 +3,21 @@ All notable changes to this project will be documented in this file.
|
|
3
3
|
This project adheres to [Semantic Versioning](http://semver.org/).
|
4
4
|
This changelog adheres to [Keep a CHANGELOG](http://keepachangelog.com/).
|
5
5
|
|
6
|
+
## [0.2.0] - 2016-12-13
|
7
|
+
### Added
|
8
|
+
- Occurrence exposes content type
|
9
|
+
- Support for different content types
|
10
|
+
- Native JSON parameter parsing
|
11
|
+
- Allows defining parameter parsers
|
12
|
+
- Scans and masks parameter keys
|
13
|
+
- Adds credit card brand validation
|
14
|
+
|
15
|
+
### Changed
|
16
|
+
- Occurrence now exposes query and body params separately
|
17
|
+
|
18
|
+
### Fixed
|
19
|
+
- Skips scanning of file uploads
|
20
|
+
|
6
21
|
## [0.1.0] - 2016-12-09
|
7
22
|
### Added
|
8
23
|
- Whitelisting of matches
|
data/README.md
CHANGED
@@ -44,24 +44,31 @@ SensitiveDataFilter.config do |config|
|
|
44
44
|
# Report occurrence
|
45
45
|
end
|
46
46
|
config.whitelist pattern1, pattern2 # Allows specifying patterns to whitelist matches
|
47
|
+
config.register_parser('yaml', -> params { YAML.load params }, -> params { YAML.dump params })
|
47
48
|
end
|
48
49
|
```
|
49
50
|
|
50
51
|
An occurrence object has the following properties:
|
51
52
|
|
52
|
-
* origin_ip:
|
53
|
-
* request_method:
|
54
|
-
* url:
|
55
|
-
*
|
56
|
-
*
|
57
|
-
*
|
58
|
-
*
|
59
|
-
*
|
53
|
+
* origin_ip: the IP address that originated the request
|
54
|
+
* request_method: the HTTP method for the request (GET, POST, etc.)
|
55
|
+
* url: the URL of the request
|
56
|
+
* content_type: the Content-Type of the request
|
57
|
+
* original_query_params: the query parameters sent with the request
|
58
|
+
* original_body_params: the body parameters sent with the request
|
59
|
+
* filtered_query_params: the query parameters sent with the request, with sensitive data filtered
|
60
|
+
* filtered_body_params: the body parameters sent with the request, with sensitive data filtered
|
61
|
+
* session: the session properties for the request
|
62
|
+
* matches: the matched sensitive data
|
63
|
+
* matches_count: the number of matches per data type, e.g. { 'CreditCard' => 1 }
|
60
64
|
|
61
65
|
It also exposes `to_h` and `to_s` methods for hash and string representation respectively.
|
62
|
-
Please note that these representations omit sensitive data,
|
66
|
+
Please note that these representations omit sensitive data,
|
67
|
+
i.e. `original_query_params`, `original_body_params` and `matches` are not included.
|
63
68
|
|
64
|
-
#### Important
|
69
|
+
#### Important Notes
|
70
|
+
|
71
|
+
Body parameters will not be parsed if a parser for the request's content type is not defined.
|
65
72
|
|
66
73
|
You might want to filter sensitive parameters (e.g: passwords).
|
67
74
|
In Rails you can do something like:
|
@@ -69,9 +76,29 @@ In Rails you can do something like:
|
|
69
76
|
```ruby
|
70
77
|
filters = Rails.application.config.filter_parameters
|
71
78
|
filter = ActionDispatch::Http::ParameterFilter.new filters
|
72
|
-
filter.filter @occurrence.
|
79
|
+
filtered_query_params = filter.filter @occurrence.filtered_query_params
|
80
|
+
filtered_body_params = if @occurrence.filtered_body_params.is_a? Hash
|
81
|
+
filter.filter @occurrence.filtered_body_params
|
82
|
+
else
|
83
|
+
@occurrence.filtered_body_params
|
84
|
+
end
|
73
85
|
```
|
74
86
|
|
87
|
+
#### Whitelisting
|
88
|
+
|
89
|
+
A list of whitelisting patterns can be passed to `config.whitelist`.
|
90
|
+
Any sensitive data match which also matches any of these patterns will be ignored.
|
91
|
+
|
92
|
+
#### Parameter Parsing
|
93
|
+
|
94
|
+
Parsers for parameters encoded for a specific content type can be defined.
|
95
|
+
The arguments for `config.register_parser` are:
|
96
|
+
* a pattern to match the content type
|
97
|
+
* a parser for the parameters
|
98
|
+
* an unparser to convert parameters back to the encoded format
|
99
|
+
|
100
|
+
The parser and unparser must be objects that respond to `call` and accept the parameters as an argument (e.g. procs or lambdas).
|
101
|
+
|
75
102
|
## Development
|
76
103
|
|
77
104
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
@@ -44,5 +44,10 @@ module SensitiveDataFilter
|
|
44
44
|
def whitelist_patterns
|
45
45
|
@whitelist_patterns ||= []
|
46
46
|
end
|
47
|
+
|
48
|
+
def register_parser(content_type, parser, unparser)
|
49
|
+
SensitiveDataFilter::Middleware::ParameterParser
|
50
|
+
.register_parser(content_type, parser, unparser)
|
51
|
+
end
|
47
52
|
end
|
48
53
|
end
|
@@ -2,13 +2,17 @@
|
|
2
2
|
module SensitiveDataFilter
|
3
3
|
module Mask
|
4
4
|
module_function def mask(value)
|
5
|
+
return mask_array(value) if value.is_a? Array
|
6
|
+
return mask_hash(value) if value.is_a? Hash
|
5
7
|
SensitiveDataFilter.enabled_types.inject(value) { |acc, elem| elem.mask acc }
|
6
8
|
end
|
7
9
|
|
10
|
+
module_function def mask_array(array)
|
11
|
+
array.map { |element| mask(element) }
|
12
|
+
end
|
13
|
+
|
8
14
|
module_function def mask_hash(hash)
|
9
|
-
hash.map
|
10
|
-
result[key] = mask(value)
|
11
|
-
}
|
15
|
+
hash.map { |key, value| [mask(key), mask(value)] }.to_h
|
12
16
|
end
|
13
17
|
end
|
14
18
|
end
|
@@ -4,8 +4,8 @@ module SensitiveDataFilter
|
|
4
4
|
end
|
5
5
|
end
|
6
6
|
|
7
|
+
require 'sensitive_data_filter/middleware/parameter_parser'
|
7
8
|
require 'sensitive_data_filter/middleware/env_parser'
|
8
|
-
require 'sensitive_data_filter/middleware/parameter_scanner'
|
9
9
|
require 'sensitive_data_filter/middleware/occurrence'
|
10
10
|
require 'sensitive_data_filter/middleware/env_filter'
|
11
11
|
require 'sensitive_data_filter/middleware/filter'
|
@@ -9,8 +9,8 @@ module SensitiveDataFilter
|
|
9
9
|
def initialize(env)
|
10
10
|
@original_env_parser = EnvParser.new(env)
|
11
11
|
@filtered_env_parser = @original_env_parser.copy
|
12
|
-
@
|
13
|
-
@filtered_env_parser.mask! if @
|
12
|
+
@scan = build_scan
|
13
|
+
@filtered_env_parser.mask! if @scan.matches?
|
14
14
|
@occurrence = build_occurrence
|
15
15
|
end
|
16
16
|
|
@@ -25,8 +25,14 @@ module SensitiveDataFilter
|
|
25
25
|
private
|
26
26
|
|
27
27
|
def build_occurrence
|
28
|
-
return nil unless @
|
29
|
-
Occurrence.new(@original_env_parser, @filtered_env_parser, @
|
28
|
+
return nil unless @scan.matches?
|
29
|
+
Occurrence.new(@original_env_parser, @filtered_env_parser, @scan.matches)
|
30
|
+
end
|
31
|
+
|
32
|
+
def build_scan
|
33
|
+
SensitiveDataFilter::Scan.new(
|
34
|
+
[@original_env_parser.query_params, @original_env_parser.body_params]
|
35
|
+
)
|
30
36
|
end
|
31
37
|
end
|
32
38
|
end
|
@@ -1,7 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
require 'forwardable'
|
3
|
+
|
2
4
|
module SensitiveDataFilter
|
3
5
|
module Middleware
|
4
6
|
class EnvParser
|
7
|
+
QUERY_STRING = 'QUERY_STRING'.freeze
|
8
|
+
RACK_INPUT = 'rack.input'.freeze
|
9
|
+
|
5
10
|
extend Forwardable
|
6
11
|
|
7
12
|
attr_reader :env
|
@@ -9,6 +14,7 @@ module SensitiveDataFilter
|
|
9
14
|
def initialize(env)
|
10
15
|
@env = env
|
11
16
|
@request = Rack::Request.new(@env)
|
17
|
+
@parameter_parser = ParameterParser.parser_for(@request.media_type)
|
12
18
|
end
|
13
19
|
|
14
20
|
def query_params
|
@@ -16,17 +22,18 @@ module SensitiveDataFilter
|
|
16
22
|
end
|
17
23
|
|
18
24
|
def body_params
|
25
|
+
return {} if file_upload?
|
19
26
|
body = @request.body.read
|
20
27
|
@request.body.rewind
|
21
|
-
|
28
|
+
@parameter_parser.parse(body)
|
22
29
|
end
|
23
30
|
|
24
31
|
def query_params=(new_params)
|
25
|
-
@env[
|
32
|
+
@env[QUERY_STRING] = Rack::Utils.build_query(new_params)
|
26
33
|
end
|
27
34
|
|
28
35
|
def body_params=(new_params)
|
29
|
-
@env[
|
36
|
+
@env[RACK_INPUT] = StringIO.new @parameter_parser.unparse(new_params)
|
30
37
|
end
|
31
38
|
|
32
39
|
def copy
|
@@ -34,11 +41,17 @@ module SensitiveDataFilter
|
|
34
41
|
end
|
35
42
|
|
36
43
|
def mask!
|
37
|
-
self.query_params = SensitiveDataFilter::Mask.
|
38
|
-
self.body_params = SensitiveDataFilter::Mask.
|
44
|
+
self.query_params = SensitiveDataFilter::Mask.mask(query_params)
|
45
|
+
self.body_params = SensitiveDataFilter::Mask.mask(body_params)
|
39
46
|
end
|
40
47
|
|
41
|
-
def_delegators :@request, :ip, :request_method, :url, :
|
48
|
+
def_delegators :@request, :ip, :request_method, :url, :content_type, :session
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def file_upload?
|
53
|
+
@request.media_type == 'multipart/form-data'
|
54
|
+
end
|
42
55
|
end
|
43
56
|
end
|
44
57
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
require 'forwardable'
|
2
3
|
require 'facets/string/titlecase'
|
3
4
|
|
4
5
|
module SensitiveDataFilter
|
@@ -18,15 +19,23 @@ module SensitiveDataFilter
|
|
18
19
|
@original_env_parser.ip
|
19
20
|
end
|
20
21
|
|
21
|
-
def
|
22
|
-
@original_env_parser.
|
22
|
+
def original_query_params
|
23
|
+
@original_env_parser.query_params
|
23
24
|
end
|
24
25
|
|
25
|
-
def
|
26
|
-
@
|
26
|
+
def original_body_params
|
27
|
+
@original_env_parser.body_params
|
27
28
|
end
|
28
29
|
|
29
|
-
|
30
|
+
def filtered_query_params
|
31
|
+
@filtered_env_parser.query_params
|
32
|
+
end
|
33
|
+
|
34
|
+
def filtered_body_params
|
35
|
+
@filtered_env_parser.body_params
|
36
|
+
end
|
37
|
+
|
38
|
+
def_delegators :@original_env_parser, :request_method, :url, :content_type, :session
|
30
39
|
|
31
40
|
def matches_count
|
32
41
|
@matches.map { |type, matches| [type, matches.count] }.to_h
|
@@ -34,12 +43,14 @@ module SensitiveDataFilter
|
|
34
43
|
|
35
44
|
def to_h
|
36
45
|
{
|
37
|
-
origin_ip:
|
38
|
-
request_method:
|
39
|
-
url:
|
40
|
-
|
41
|
-
|
42
|
-
|
46
|
+
origin_ip: origin_ip,
|
47
|
+
request_method: request_method,
|
48
|
+
url: url,
|
49
|
+
content_type: content_type,
|
50
|
+
filtered_query_params: filtered_query_params,
|
51
|
+
filtered_body_params: filtered_body_params,
|
52
|
+
session: session,
|
53
|
+
matches_count: matches_count
|
43
54
|
}
|
44
55
|
end
|
45
56
|
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SensitiveDataFilter
|
4
|
+
module Middleware
|
5
|
+
class ParameterParser
|
6
|
+
def self.register_parser(content_type, parse, unparse)
|
7
|
+
parsers.unshift new(content_type, parse, unparse)
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.parsers
|
11
|
+
@parsers ||= DEFAULT_PARSERS.dup
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.parser_for(content_type)
|
15
|
+
parsers.find { |parser| parser.can_parse? content_type } || NULL_PARSER
|
16
|
+
end
|
17
|
+
|
18
|
+
def initialize(content_type, parse, unparse)
|
19
|
+
@content_type = content_type
|
20
|
+
@parse = parse
|
21
|
+
@unparse = unparse
|
22
|
+
end
|
23
|
+
|
24
|
+
def can_parse?(content_type)
|
25
|
+
content_type.to_s.match @content_type
|
26
|
+
end
|
27
|
+
|
28
|
+
def parse(params)
|
29
|
+
@parse.call params
|
30
|
+
end
|
31
|
+
|
32
|
+
def unparse(params)
|
33
|
+
@unparse.call params
|
34
|
+
end
|
35
|
+
|
36
|
+
NULL_PARSER = new('', ->(params) { params }, ->(params) { params })
|
37
|
+
|
38
|
+
DEFAULT_PARSERS = [
|
39
|
+
new('urlencoded', # e.g.: 'application/x-www-form-urlencoded'
|
40
|
+
->(params) { Rack::Utils.parse_query(params) },
|
41
|
+
->(params) { Rack::Utils.build_query(params) }),
|
42
|
+
new('json', # e.g.: 'application/json'
|
43
|
+
->(params) { JSON.parse(params) },
|
44
|
+
->(params) { JSON.unparse(params) })
|
45
|
+
].freeze
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -1,26 +1,39 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
require 'facets/kernel/present'
|
3
|
+
require 'facets/hash/collate'
|
3
4
|
|
4
5
|
module SensitiveDataFilter
|
5
6
|
class Scan
|
7
|
+
def self.scan(value)
|
8
|
+
return scan_array(value) if value.is_a? Array
|
9
|
+
return scan_hash(value) if value.is_a? Hash
|
10
|
+
SensitiveDataFilter.enabled_types.map.with_object({}) { |scanner, matches|
|
11
|
+
matches[scanner.name.split('::').last] = whitelist(scanner.scan(value))
|
12
|
+
}
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.scan_array(array)
|
16
|
+
array.map { |element| scan(element) }.inject(:collate) || {}
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.scan_hash(hash)
|
20
|
+
hash.map { |key, value| scan(key).collate(scan(value)) }.inject(:collate) || {}
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.whitelist(matches)
|
24
|
+
matches.reject { |match| SensitiveDataFilter.whitelisted? match }
|
25
|
+
end
|
26
|
+
|
6
27
|
def initialize(value)
|
7
28
|
@value = value
|
8
29
|
end
|
9
30
|
|
10
31
|
def matches
|
11
|
-
@matches ||=
|
12
|
-
matches[scanner.name.split('::').last] = whitelist scanner.scan(@value)
|
13
|
-
}
|
32
|
+
@matches ||= self.class.scan(@value)
|
14
33
|
end
|
15
34
|
|
16
35
|
def matches?
|
17
36
|
matches.values.any?(&:present?)
|
18
37
|
end
|
19
|
-
|
20
|
-
private
|
21
|
-
|
22
|
-
def whitelist(matches)
|
23
|
-
matches.reject { |match| SensitiveDataFilter.whitelisted? match }
|
24
|
-
end
|
25
38
|
end
|
26
39
|
end
|
@@ -1,4 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
require 'credit_card_validations'
|
3
|
+
|
2
4
|
module SensitiveDataFilter
|
3
5
|
module Types
|
4
6
|
module CreditCard
|
@@ -21,7 +23,7 @@ module SensitiveDataFilter
|
|
21
23
|
module_function def valid?(number)
|
22
24
|
return false unless number.is_a? String
|
23
25
|
return false unless number.match CARD
|
24
|
-
|
26
|
+
CreditCardValidations::Detector.new(number.gsub(SEPARATORS, '')).brand.present?
|
25
27
|
end
|
26
28
|
|
27
29
|
module_function def scan(value)
|
@@ -33,40 +35,6 @@ module SensitiveDataFilter
|
|
33
35
|
return value unless value.is_a? String
|
34
36
|
scan(value).inject(value) { |acc, elem| acc.gsub(elem, FILTERED) }
|
35
37
|
end
|
36
|
-
|
37
|
-
# Adapted from https://github.com/rolfb/luhn-ruby/blob/master/lib/luhn.rb
|
38
|
-
class Luhn
|
39
|
-
def initialize(number)
|
40
|
-
@number = number
|
41
|
-
end
|
42
|
-
|
43
|
-
def valid?
|
44
|
-
numbers = split_digits(@number)
|
45
|
-
numbers.last == checksum(numbers[0..-2].join)
|
46
|
-
end
|
47
|
-
|
48
|
-
private
|
49
|
-
|
50
|
-
def checksum(number)
|
51
|
-
products = luhn_doubled(number)
|
52
|
-
sum = products.inject(0) { |acc, elem| acc + sum_of(elem) }
|
53
|
-
checksum = 10 - (sum % 10)
|
54
|
-
checksum == 10 ? 0 : checksum
|
55
|
-
end
|
56
|
-
|
57
|
-
def luhn_doubled(number)
|
58
|
-
numbers = split_digits(number).reverse
|
59
|
-
numbers.map.with_index { |n, i| i.even? ? n * 2 : n * 1 }.reverse
|
60
|
-
end
|
61
|
-
|
62
|
-
def sum_of(number)
|
63
|
-
split_digits(number).inject(:+)
|
64
|
-
end
|
65
|
-
|
66
|
-
def split_digits(number)
|
67
|
-
number.to_s.split(//).map(&:to_i)
|
68
|
-
end
|
69
|
-
end
|
70
38
|
end
|
71
39
|
end
|
72
40
|
end
|
@@ -25,6 +25,7 @@ Gem::Specification.new do |spec|
|
|
25
25
|
|
26
26
|
spec.add_dependency 'rack', '>= 1.4'
|
27
27
|
spec.add_dependency 'facets', '~> 3.1'
|
28
|
+
spec.add_dependency 'credit_card_validations', '~> 3.2'
|
28
29
|
|
29
30
|
spec.add_development_dependency 'bundler', '~> 1.13'
|
30
31
|
spec.add_development_dependency 'rake', '~> 10.0'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sensitive_data_filter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alessandro Berardi
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date: 2016-12-
|
12
|
+
date: 2016-12-13 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rack
|
@@ -39,6 +39,20 @@ dependencies:
|
|
39
39
|
- - "~>"
|
40
40
|
- !ruby/object:Gem::Version
|
41
41
|
version: '3.1'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: credit_card_validations
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - "~>"
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '3.2'
|
49
|
+
type: :runtime
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - "~>"
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '3.2'
|
42
56
|
- !ruby/object:Gem::Dependency
|
43
57
|
name: bundler
|
44
58
|
requirement: !ruby/object:Gem::Requirement
|
@@ -182,7 +196,7 @@ files:
|
|
182
196
|
- lib/sensitive_data_filter/middleware/env_parser.rb
|
183
197
|
- lib/sensitive_data_filter/middleware/filter.rb
|
184
198
|
- lib/sensitive_data_filter/middleware/occurrence.rb
|
185
|
-
- lib/sensitive_data_filter/middleware/
|
199
|
+
- lib/sensitive_data_filter/middleware/parameter_parser.rb
|
186
200
|
- lib/sensitive_data_filter/scan.rb
|
187
201
|
- lib/sensitive_data_filter/types.rb
|
188
202
|
- lib/sensitive_data_filter/types/credit_card.rb
|
@@ -1,22 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
require 'facets/hash/collate'
|
3
|
-
|
4
|
-
module SensitiveDataFilter
|
5
|
-
module Middleware
|
6
|
-
class ParameterScanner
|
7
|
-
def initialize(env_parser)
|
8
|
-
@env_parser = env_parser
|
9
|
-
@params = @env_parser.query_params.values + @env_parser.body_params.values
|
10
|
-
@scans = @params.map { |value| SensitiveDataFilter::Scan.new(value) }
|
11
|
-
end
|
12
|
-
|
13
|
-
def matches
|
14
|
-
@scans.map(&:matches).inject(:collate)
|
15
|
-
end
|
16
|
-
|
17
|
-
def sensitive_data?
|
18
|
-
@scans.any?(&:matches?)
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|