sqreen 1.18.3.beta1 → 1.18.3.beta2
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/CHANGELOG.md +0 -5
- data/lib/sqreen/actions.rb +11 -337
- data/lib/sqreen/actions/base.rb +110 -0
- data/lib/sqreen/actions/block_ip.rb +32 -0
- data/lib/sqreen/actions/block_user.rb +44 -0
- data/lib/sqreen/actions/ip_range_indexed_action_class.rb +36 -0
- data/lib/sqreen/actions/ip_ranges_index.rb +36 -0
- data/lib/sqreen/actions/redirect_ip.rb +40 -0
- data/lib/sqreen/actions/redirect_user.rb +45 -0
- data/lib/sqreen/actions/repository.rb +24 -0
- data/lib/sqreen/actions/unknown_action_type.rb +16 -0
- data/lib/sqreen/actions/user_action_class.rb +41 -0
- data/lib/sqreen/agent.rb +4 -1
- data/lib/sqreen/attack_blocked.rb +17 -0
- data/lib/sqreen/binding_accessor.rb +9 -102
- data/lib/sqreen/binding_accessor/path_elem.rb +8 -0
- data/lib/sqreen/binding_accessor/transforms.rb +107 -0
- data/lib/sqreen/capped_queue.rb +2 -0
- data/lib/sqreen/{callbacks.rb → cb.rb} +1 -53
- data/lib/sqreen/{callback_tree.rb → cb_tree.rb} +2 -2
- data/lib/sqreen/condition_evaluator.rb +22 -5
- data/lib/sqreen/configuration.rb +3 -0
- data/lib/sqreen/default_cb.rb +20 -0
- data/lib/sqreen/deferred_logger.rb +63 -0
- data/lib/sqreen/deliveries.rb +10 -0
- data/lib/sqreen/deliveries/batch.rb +7 -1
- data/lib/sqreen/deliveries/simple.rb +5 -0
- data/lib/sqreen/dependency/rails.rb +4 -0
- data/lib/sqreen/dependency/sinatra.rb +4 -0
- data/lib/sqreen/error_handling_middleware.rb +30 -0
- data/lib/sqreen/event.rb +2 -0
- data/lib/sqreen/events/attack.rb +2 -0
- data/lib/sqreen/events/request_record.rb +11 -56
- data/lib/sqreen/exception.rb +9 -40
- data/lib/sqreen/formatter_with_tid.rb +45 -0
- data/lib/sqreen/framework_cb.rb +28 -0
- data/lib/sqreen/frameworks.rb +7 -0
- data/lib/sqreen/frameworks/generic.rb +5 -1
- data/lib/sqreen/frameworks/rails.rb +2 -0
- data/lib/sqreen/frameworks/request_recorder.rb +3 -0
- data/lib/sqreen/frameworks/sinatra.rb +2 -0
- data/lib/sqreen/frameworks/sqreen_test.rb +2 -0
- data/lib/sqreen/instrumentation.rb +5 -5
- data/lib/sqreen/invalid_signature_exception.rb +8 -0
- data/lib/{sqreen-alt.rb → sqreen/js.rb} +6 -1
- data/lib/sqreen/js/call_context.rb +10 -0
- data/lib/sqreen/js/context_pool.rb +60 -0
- data/lib/sqreen/js/exec_js_runnable.rb +20 -0
- data/lib/sqreen/js/execjs_adapter.rb +6 -47
- data/lib/sqreen/js/executable_js.rb +12 -0
- data/lib/sqreen/js/js_service.rb +2 -22
- data/lib/sqreen/js/js_service_adapter.rb +18 -0
- data/lib/sqreen/js/mini_racer_adapter.rb +6 -180
- data/lib/sqreen/js/mini_racer_executable_js.rb +142 -0
- data/lib/sqreen/js/thread_local_exec_js_runnable.rb +47 -0
- data/lib/sqreen/log.rb +8 -188
- data/lib/sqreen/logger.rb +83 -0
- data/lib/sqreen/metrics_store.rb +3 -11
- data/lib/sqreen/metrics_store/already_registered_metric.rb +11 -0
- data/lib/sqreen/metrics_store/unknown_metric.rb +11 -0
- data/lib/sqreen/metrics_store/unregistered_metric.rb +11 -0
- data/lib/sqreen/middleware.rb +0 -44
- data/lib/sqreen/mono_time.rb +2 -0
- data/lib/sqreen/node.rb +44 -0
- data/lib/sqreen/not_implemented_yet.rb +8 -0
- data/lib/sqreen/null_logger.rb +24 -0
- data/lib/sqreen/payload_creator.rb +2 -19
- data/lib/sqreen/payload_creator/header_section.rb +28 -0
- data/lib/sqreen/prefix.rb +33 -0
- data/lib/sqreen/rails_middleware.rb +14 -0
- data/lib/sqreen/remote_command.rb +1 -8
- data/lib/sqreen/remote_command/failure_output.rb +11 -0
- data/lib/sqreen/rules.rb +32 -2
- data/lib/sqreen/{rule_attributes.rb → rules/attrs.rb} +0 -0
- data/lib/sqreen/{rules_callbacks/sdk_auth_track.rb → rules/auth_track_cb.rb} +2 -2
- data/lib/sqreen/{rules_callbacks/binding_accessor_matcher.rb → rules/binding_accessor_matcher_cb.rb} +4 -8
- data/lib/sqreen/{rules_callbacks → rules}/binding_accessor_metrics.rb +1 -1
- data/lib/sqreen/{rules_callbacks/blacklist_ips.rb → rules/blacklist_ips_cb.rb} +3 -2
- data/lib/sqreen/{rules_callbacks → rules}/count_http_codes.rb +2 -2
- data/lib/sqreen/{rules_callbacks/crawler_user_agent_matches.rb → rules/crawler_user_agent_matches_cb.rb} +1 -1
- data/lib/sqreen/{rules_callbacks/crawler_user_agent_matches_metrics.rb → rules/crawler_user_agent_matches_metrics_cb.rb} +1 -1
- data/lib/sqreen/{rules_callbacks/custom_error.rb → rules/custom_error_cb.rb} +1 -1
- data/lib/sqreen/{rules_callbacks/devise_auth_track.rb → rules/devise_auth_track_cb.rb} +2 -2
- data/lib/sqreen/{rules_callbacks/devise_signup_track.rb → rules/devise_signup_track_cb.rb} +2 -2
- data/lib/sqreen/{rules_callbacks/execjs.rb → rules/execjs_cb.rb} +49 -50
- data/lib/sqreen/{rules_callbacks/headers_insert.rb → rules/headers_insert_cb.rb} +1 -1
- data/lib/sqreen/{rules_callbacks → rules}/matcher_rule.rb +2 -2
- data/lib/sqreen/{rules_callbacks/not_found.rb → rules/not_found_cb.rb} +2 -2
- data/lib/sqreen/{rules_callbacks/rails_parameters.rb → rules/rails_parameters_cb.rb} +1 -1
- data/lib/sqreen/{rules_callbacks → rules}/record_request_context.rb +1 -1
- data/lib/sqreen/{rules_callbacks/regexp_rule.rb → rules/regexp_rule_cb.rb} +1 -1
- data/lib/sqreen/{rule_callback.rb → rules/rule_cb.rb} +2 -2
- data/lib/sqreen/{rules_callbacks → rules}/run_req_start_actions.rb +4 -2
- data/lib/sqreen/{rules_callbacks → rules}/run_user_actions.rb +1 -1
- data/lib/sqreen/{rules_callbacks/shell_env.rb → rules/shell_env_cb.rb} +1 -1
- data/lib/sqreen/{rules_callbacks/sdk_signup_track.rb → rules/signup_track_cb.rb} +2 -2
- data/lib/sqreen/{rules_callbacks → rules}/update_request_context.rb +1 -1
- data/lib/sqreen/{rules_callbacks/url_matches.rb → rules/url_matches_cb.rb} +1 -1
- data/lib/sqreen/{rules_callbacks/user_agent_matches.rb → rules/user_agent_matches_cb.rb} +1 -1
- data/lib/sqreen/{rules_callbacks/waf.rb → rules/waf_cb.rb} +7 -3
- data/lib/sqreen/{rules_callbacks/reflected_xss.rb → rules/xss_cb.rb} +10 -7
- data/lib/sqreen/run_when_called_cb.rb +21 -0
- data/lib/sqreen/sensitive_data_redactor.rb +111 -0
- data/lib/sqreen/signature_verifier.rb +20 -0
- data/lib/sqreen/sinatra_middleware.rb +14 -0
- data/lib/sqreen/{rules_signature.rb → sqreen_signed_verifier.rb} +5 -17
- data/lib/sqreen/token_invalid_exception.rb +8 -0
- data/lib/sqreen/token_not_found_exception.rb +9 -0
- data/lib/sqreen/trie.rb +3 -64
- data/lib/sqreen/unauthorized.rb +8 -0
- data/lib/sqreen/util.rb +2 -0
- data/lib/sqreen/util/capped_array.rb +30 -0
- data/lib/sqreen/util/capped_hash.rb +36 -0
- data/lib/sqreen/util/capped_string.rb +22 -0
- data/lib/sqreen/util/capper.rb +57 -0
- data/lib/sqreen/version.rb +1 -1
- data/lib/sqreen/waf_error.rb +18 -0
- metadata +85 -36
- data/lib/sqreen/rules_callbacks.rb +0 -36
- data/lib/sqreen/rules_callbacks/inspect_rule.rb +0 -25
@@ -1,7 +1,7 @@
|
|
1
1
|
# Copyright (c) 2015 Sqreen. All Rights Reserved.
|
2
2
|
# Please refer to our terms for more information: https://www.sqreen.com/terms.html
|
3
3
|
|
4
|
-
require 'sqreen/
|
4
|
+
require 'sqreen/rules/rule_cb'
|
5
5
|
|
6
6
|
module Sqreen
|
7
7
|
module Rules
|
@@ -13,7 +13,7 @@ module Sqreen
|
|
13
13
|
res |= Regexp::MULTILINE if options.include?('multiline')
|
14
14
|
res |= Regexp::IGNORECASE unless case_sensitive
|
15
15
|
r = Regexp.compile(value, res)
|
16
|
-
r
|
16
|
+
r =~ ''
|
17
17
|
r
|
18
18
|
end
|
19
19
|
|
@@ -1,11 +1,11 @@
|
|
1
1
|
# Copyright (c) 2015 Sqreen. All Rights Reserved.
|
2
2
|
# Please refer to our terms for more information: https://www.sqreen.com/terms.html
|
3
3
|
|
4
|
-
require 'sqreen/
|
4
|
+
require 'sqreen/framework_cb'
|
5
5
|
require 'sqreen/context'
|
6
6
|
require 'sqreen/conditionable'
|
7
7
|
require 'sqreen/call_countable'
|
8
|
-
require 'sqreen/
|
8
|
+
require 'sqreen/rules/attrs'
|
9
9
|
require 'sqreen/events/attack'
|
10
10
|
require 'sqreen/events/remote_exception'
|
11
11
|
require 'sqreen/payload_creator'
|
@@ -1,9 +1,11 @@
|
|
1
1
|
# Copyright (c) 2015 Sqreen. All Rights Reserved.
|
2
2
|
# Please refer to our terms for more information: https://www.sqreen.com/terms.html
|
3
3
|
|
4
|
-
require 'sqreen/
|
4
|
+
require 'sqreen/rules/rule_cb'
|
5
5
|
require 'sqreen/actions'
|
6
6
|
require 'sqreen/middleware'
|
7
|
+
require 'sqreen/rails_middleware'
|
8
|
+
require 'sqreen/sinatra_middleware'
|
7
9
|
|
8
10
|
module Sqreen
|
9
11
|
module Rules
|
@@ -14,7 +16,7 @@ module Sqreen
|
|
14
16
|
def initialize(framework)
|
15
17
|
if defined?(Sqreen::Frameworks::SinatraFramework) &&
|
16
18
|
framework.is_a?(Sqreen::Frameworks::SinatraFramework)
|
17
|
-
super(
|
19
|
+
super(Sqreen::SinatraMiddleware, :call)
|
18
20
|
elsif defined?(Sqreen::Frameworks::RailsFramework) &&
|
19
21
|
framework.is_a?(Sqreen::Frameworks::RailsFramework)
|
20
22
|
super(Sqreen::RailsMiddleware, :call)
|
@@ -1,8 +1,8 @@
|
|
1
1
|
# Copyright (c) 2015 Sqreen. All Rights Reserved.
|
2
2
|
# Please refer to our terms for more information: https://www.sqreen.com/terms.html
|
3
3
|
|
4
|
-
require 'sqreen/
|
5
|
-
require 'sqreen/
|
4
|
+
require 'sqreen/rules/attrs'
|
5
|
+
require 'sqreen/rules/rule_cb'
|
6
6
|
require 'sqreen/safe_json'
|
7
7
|
|
8
8
|
module Sqreen
|
@@ -2,11 +2,12 @@
|
|
2
2
|
# Please refer to our terms for more information: https://www.sqreen.com/terms.html
|
3
3
|
|
4
4
|
require 'securerandom'
|
5
|
-
require 'sqreen/
|
5
|
+
require 'sqreen/rules/attrs'
|
6
6
|
require 'sqreen/binding_accessor'
|
7
|
-
require 'sqreen/
|
7
|
+
require 'sqreen/rules/rule_cb'
|
8
8
|
require 'sqreen/safe_json'
|
9
9
|
require 'sqreen/exception'
|
10
|
+
require 'sqreen/util/capper'
|
10
11
|
|
11
12
|
module Sqreen
|
12
13
|
module Rules
|
@@ -72,7 +73,10 @@ module Sqreen
|
|
72
73
|
|
73
74
|
env = [binding, framework, instance, args]
|
74
75
|
|
75
|
-
|
76
|
+
capper = Sqreen::Util::Capper.new(string_size_cap: 4096, size_cap: 150, depth_cap: 10)
|
77
|
+
waf_args = binding_accessors.each_with_object({}) do |(e, b), h|
|
78
|
+
h[e] = capper.call(b.resolve(*env))
|
79
|
+
end
|
76
80
|
waf_args = Sqreen::EncodingSanitizer.sanitize(waf_args)
|
77
81
|
action, data = ::LibSqreen::WAF.run(waf_rule_name, waf_args, budget)
|
78
82
|
|
@@ -3,8 +3,8 @@
|
|
3
3
|
|
4
4
|
require 'cgi'
|
5
5
|
|
6
|
-
require 'sqreen/
|
7
|
-
require 'sqreen/
|
6
|
+
require 'sqreen/rules/rule_cb'
|
7
|
+
require 'sqreen/rules/regexp_rule_cb'
|
8
8
|
|
9
9
|
# Sqreen module
|
10
10
|
module Sqreen
|
@@ -21,6 +21,7 @@ module Sqreen
|
|
21
21
|
return nil unless framework
|
22
22
|
framework.xss_params(@union_pattern)
|
23
23
|
end
|
24
|
+
|
24
25
|
# The remaining code is only to find out if user entry was an attack,
|
25
26
|
# and record it. Since we don't rely on it to respond to user, it would
|
26
27
|
# be better to do it in background.
|
@@ -36,6 +37,7 @@ module Sqreen
|
|
36
37
|
true
|
37
38
|
end
|
38
39
|
end
|
40
|
+
|
39
41
|
class ReflectedUnsafeXSSCB < XSSCB
|
40
42
|
def pre(_inst, args, _budget = nil, &_block)
|
41
43
|
value = args[0]
|
@@ -52,13 +54,12 @@ module Sqreen
|
|
52
54
|
return unless report_dangerous_xss?(saved_value)
|
53
55
|
|
54
56
|
# potential XSS! let's escape
|
55
|
-
if block
|
56
|
-
args[0].replace(CGI.escape_html(value))
|
57
|
-
end
|
57
|
+
args[0].replace(CGI.escape_html(value)) if block
|
58
58
|
|
59
59
|
advise_action(nil)
|
60
60
|
end
|
61
61
|
end
|
62
|
+
|
62
63
|
# look for reflected XSS with erb template engine
|
63
64
|
class ReflectedXSSCB < XSSCB
|
64
65
|
def pre(_inst, args, _budget = nil, &_block)
|
@@ -84,6 +85,7 @@ module Sqreen
|
|
84
85
|
advise_action(nil)
|
85
86
|
end
|
86
87
|
end
|
88
|
+
|
87
89
|
# look for reflected XSS with haml template engine
|
88
90
|
# hook function arguments of
|
89
91
|
# Haml::Buffer.format_script(result, preserve_script, in_tag, preserve_tag,
|
@@ -145,7 +147,7 @@ module Sqreen
|
|
145
147
|
if tag.value[:escape_html] == false &&
|
146
148
|
tag.value[:value].respond_to?(:include?) &&
|
147
149
|
!tag.value[:value].include?('html_escape') &&
|
148
|
-
|
150
|
+
tag.value[:parse] == true
|
149
151
|
tag.value[:value] = "Sqreen.escape_haml((#{tag.value[:value]}))"
|
150
152
|
return { :status => :override, :new_return_value => tag }
|
151
153
|
end
|
@@ -172,7 +174,8 @@ module Sqreen
|
|
172
174
|
res << '#{'
|
173
175
|
else
|
174
176
|
# Use eval to get rid of string escapes
|
175
|
-
|
177
|
+
# TODO: look for eval removal
|
178
|
+
content = eval('"' + Haml::Util.balance(scan, '{', '}', 1)[0][0...-1] + '"') # rubocop:disable Security/Eval
|
176
179
|
content = "Haml::Helpers.html_escape((#{content}))" if escape_html
|
177
180
|
res << '#{Sqreen.escape_haml((' + content + '))}'
|
178
181
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# Copyright (c) 2015 Sqreen. All Rights Reserved.
|
2
|
+
# Please refer to our terms for more information: https://www.sqreen.com/terms.html
|
3
|
+
|
4
|
+
require 'sqreen/cb'
|
5
|
+
|
6
|
+
module Sqreen
|
7
|
+
class RunWhenCalledCB < CB
|
8
|
+
def initialize(klass, method, &block)
|
9
|
+
super(klass, method)
|
10
|
+
|
11
|
+
raise 'missing block' unless block_given?
|
12
|
+
@block = block
|
13
|
+
end
|
14
|
+
|
15
|
+
def pre(_inst, _args, _budget = nil, &_block)
|
16
|
+
# FIXME: implement this removal
|
17
|
+
@remove_me = true
|
18
|
+
@block.call
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
# Copyright (c) 2015 Sqreen. All Rights Reserved.
|
2
|
+
# Please refer to our terms for more information: https://www.sqreen.com/terms.html
|
3
|
+
|
4
|
+
# TODO: Sqreen.config_get
|
5
|
+
|
6
|
+
require 'json'
|
7
|
+
require 'sqreen/log'
|
8
|
+
|
9
|
+
module Sqreen
|
10
|
+
# For redacting sensitive data and avoid having it sent to our servers
|
11
|
+
class SensitiveDataRedactor
|
12
|
+
DEFAULT_SENSITIVE_KEYS = Set.new(%w[password secret passwd authorization api_key apikey access_token]).freeze
|
13
|
+
DEFAULT_REGEX = /\A(?:\d[ -]*?){13,16}\z/
|
14
|
+
MASK = '<Redacted by Sqreen>'.freeze
|
15
|
+
|
16
|
+
def self.from_config
|
17
|
+
keys = Sqreen.config_get(:strip_sensitive_keys)
|
18
|
+
keys = keys.split(',') if keys && keys.is_a?(String)
|
19
|
+
|
20
|
+
regex = Sqreen.config_get(:strip_sensitive_regex)
|
21
|
+
if regex && regex.is_a?(String)
|
22
|
+
begin
|
23
|
+
regex = Regexp.compile(regex)
|
24
|
+
rescue RegexpError
|
25
|
+
Sqreen.log.warn("Invalid regular expression given in strip_sensitive_regex: #{regex}")
|
26
|
+
regex = nil
|
27
|
+
end
|
28
|
+
else
|
29
|
+
regex = nil
|
30
|
+
end
|
31
|
+
|
32
|
+
new(keys: keys, regex: regex)
|
33
|
+
end
|
34
|
+
|
35
|
+
def initialize(params = {})
|
36
|
+
@regex = params[:regex] || DEFAULT_REGEX
|
37
|
+
@keys = (params[:keys] || DEFAULT_SENSITIVE_KEYS).map(&:downcase)
|
38
|
+
end
|
39
|
+
|
40
|
+
def redact(obj)
|
41
|
+
result = obj
|
42
|
+
redacted = []
|
43
|
+
|
44
|
+
case obj
|
45
|
+
when String
|
46
|
+
if obj =~ @regex
|
47
|
+
result = MASK
|
48
|
+
redacted << obj
|
49
|
+
end
|
50
|
+
when Array
|
51
|
+
result = []
|
52
|
+
obj.each do |e|
|
53
|
+
e, r = redact(e)
|
54
|
+
result << e
|
55
|
+
redacted += r
|
56
|
+
end
|
57
|
+
when Hash
|
58
|
+
result = {}
|
59
|
+
obj.each do |k, v|
|
60
|
+
ck = k.is_a?(String) ? k.downcase : k
|
61
|
+
if @keys.include?(ck)
|
62
|
+
redacted << v
|
63
|
+
v = MASK
|
64
|
+
else
|
65
|
+
v, r = redact(v)
|
66
|
+
redacted += r
|
67
|
+
end
|
68
|
+
result[k] = v
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
[result, redacted]
|
73
|
+
end
|
74
|
+
|
75
|
+
def redact_attacks!(attacks, values)
|
76
|
+
return attacks if values.empty?
|
77
|
+
|
78
|
+
values = values.map { |v| v.downcase if v.is_a?(String) }
|
79
|
+
|
80
|
+
attacks.each do |e|
|
81
|
+
next(e) unless e[:infos]
|
82
|
+
next(e) unless e[:infos][:waf_data]
|
83
|
+
|
84
|
+
parsed = JSON.parse(e[:infos][:waf_data])
|
85
|
+
redacted = parsed.each do |w|
|
86
|
+
next unless (filters = w['filter'])
|
87
|
+
|
88
|
+
filters.each do |f|
|
89
|
+
next unless (v = f['resolved_value'])
|
90
|
+
next unless values.include?(v.downcase)
|
91
|
+
|
92
|
+
f['match_status'] = MASK
|
93
|
+
f['resolved_value'] = MASK
|
94
|
+
end
|
95
|
+
end
|
96
|
+
e[:infos][:waf_data] = JSON.dump(redacted)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def redact_exceptions!(exceptions, values)
|
101
|
+
return exceptions if values.empty?
|
102
|
+
|
103
|
+
exceptions.each do |e|
|
104
|
+
next(e) unless e[:infos]
|
105
|
+
next(e) unless e[:infos][:waf]
|
106
|
+
|
107
|
+
e[:infos][:waf].delete(:args)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# Copyright (c) 2015 Sqreen. All Rights Reserved.
|
2
|
+
# Please refer to our terms for more information: https://www.sqreen.com/terms.html
|
3
|
+
|
4
|
+
require 'openssl'
|
5
|
+
|
6
|
+
## Rules signature
|
7
|
+
module Sqreen
|
8
|
+
# Perform an EC + digest verification of a message.
|
9
|
+
class SignatureVerifier
|
10
|
+
def initialize(key, digest)
|
11
|
+
@pub_key = OpenSSL::PKey.read(key)
|
12
|
+
@digest = digest
|
13
|
+
end
|
14
|
+
|
15
|
+
def verify(sig, val)
|
16
|
+
hashed_val = @digest.digest(val)
|
17
|
+
@pub_key.dsa_verify_asn1(hashed_val, sig)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# Copyright (c) 2015 Sqreen. All Rights Reserved.
|
2
|
+
# Please refer to our terms for more information: https://www.sqreen.com/terms.html
|
3
|
+
|
4
|
+
module Sqreen
|
5
|
+
class SinatraMiddleware
|
6
|
+
def initialize(app)
|
7
|
+
@app = app
|
8
|
+
end
|
9
|
+
|
10
|
+
def call(env)
|
11
|
+
@app.call(env)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -1,8 +1,6 @@
|
|
1
1
|
# Copyright (c) 2015 Sqreen. All Rights Reserved.
|
2
2
|
# Please refer to our terms for more information: https://www.sqreen.com/terms.html
|
3
3
|
|
4
|
-
require 'sqreen/exception'
|
5
|
-
|
6
4
|
require 'set'
|
7
5
|
require 'openssl'
|
8
6
|
require 'base64'
|
@@ -18,21 +16,11 @@ else
|
|
18
16
|
end
|
19
17
|
end
|
20
18
|
|
19
|
+
require 'sqreen/exception'
|
20
|
+
require 'sqreen/signature_verifier'
|
21
|
+
|
21
22
|
## Rules signature
|
22
23
|
module Sqreen
|
23
|
-
# Perform an EC + digest verification of a message.
|
24
|
-
class SignatureVerifier
|
25
|
-
def initialize(key, digest)
|
26
|
-
@pub_key = OpenSSL::PKey.read(key)
|
27
|
-
@digest = digest
|
28
|
-
end
|
29
|
-
|
30
|
-
def verify(sig, val)
|
31
|
-
hashed_val = @digest.digest(val)
|
32
|
-
@pub_key.dsa_verify_asn1(hashed_val, sig)
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
24
|
# Normalize and verify a rule
|
37
25
|
class SqreenSignedVerifier
|
38
26
|
REQUIRED_SIGNED_KEYS = %w[hookpoint name callbacks conditions].freeze
|
@@ -40,14 +28,14 @@ module Sqreen
|
|
40
28
|
SIGNATURE_VALUE_KEY = 'value'.freeze
|
41
29
|
SIGNED_KEYS_KEY = 'keys'.freeze
|
42
30
|
SIGNATURE_VERSION = 'v0_9'.freeze
|
43
|
-
PUBLIC_KEY = <<-
|
31
|
+
PUBLIC_KEY = <<-KEY.gsub(/^ */, '').freeze
|
44
32
|
-----BEGIN PUBLIC KEY-----
|
45
33
|
MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQA39oWMHR8sxb9LRaM5evZ7mw03iwJ
|
46
34
|
WNHuDeGqgPo1HmvuMfLnAyVLwaMXpGPuvbqhC1U65PG90bTJLpvNokQf0VMA5Tpi
|
47
35
|
m+NXwl7bjqa03vO/HErLbq3zBRysrZnC4OhJOF1jazkAg0psQOea2r5HcMcPHgMK
|
48
36
|
fnWXiKWnZX+uOWPuerE=
|
49
37
|
-----END PUBLIC KEY-----
|
50
|
-
|
38
|
+
KEY
|
51
39
|
|
52
40
|
attr_accessor :pub_key
|
53
41
|
attr_accessor :required_signed_keys
|