sqreen 1.18.2-java → 1.19.0-java
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 +35 -0
- data/LICENSE +3 -0
- data/lib/sqreen.rb +2 -0
- data/lib/sqreen/actions.rb +13 -337
- data/lib/sqreen/actions/actions_index.rb +16 -0
- data/lib/sqreen/actions/base.rb +104 -0
- data/lib/sqreen/actions/block_ip.rb +34 -0
- data/lib/sqreen/actions/block_user.rb +46 -0
- data/lib/sqreen/actions/ip_range_indexed_action_class.rb +16 -0
- data/lib/sqreen/actions/ip_ranges_index.rb +57 -0
- data/lib/sqreen/actions/redirect_ip.rb +42 -0
- data/lib/sqreen/actions/redirect_user.rb +47 -0
- data/lib/sqreen/actions/repository.rb +43 -0
- data/lib/sqreen/actions/unknown_action_type.rb +20 -0
- data/lib/sqreen/actions/user_action_class.rb +16 -0
- data/lib/sqreen/actions/users_index.rb +35 -0
- data/lib/sqreen/agent.rb +6 -2
- data/lib/sqreen/attack_blocked.rb +19 -0
- data/lib/sqreen/backport.rb +2 -0
- data/lib/sqreen/backport/clock_gettime.rb +74 -0
- data/lib/sqreen/backport/original_name.rb +2 -0
- data/lib/sqreen/binding_accessor.rb +11 -102
- data/lib/sqreen/binding_accessor/path_elem.rb +10 -0
- data/lib/sqreen/binding_accessor/transforms.rb +114 -0
- data/lib/sqreen/call_countable.rb +2 -0
- data/lib/sqreen/capped_queue.rb +4 -0
- data/lib/sqreen/{callbacks.rb → cb.rb} +3 -53
- data/lib/sqreen/{callback_tree.rb → cb_tree.rb} +4 -2
- data/lib/sqreen/condition_evaluator.rb +24 -5
- data/lib/sqreen/conditionable.rb +2 -0
- data/lib/sqreen/configuration.rb +19 -0
- data/lib/sqreen/context.rb +2 -0
- data/lib/sqreen/default_cb.rb +22 -0
- data/lib/sqreen/deferred_logger.rb +65 -0
- data/lib/sqreen/deliveries.rb +12 -0
- data/lib/sqreen/deliveries/batch.rb +9 -1
- data/lib/sqreen/deliveries/simple.rb +7 -0
- data/lib/sqreen/dependency.rb +3 -1
- data/lib/sqreen/dependency/detector.rb +22 -14
- data/lib/sqreen/dependency/libsqreen.rb +32 -0
- data/lib/sqreen/dependency/new_relic.rb +2 -0
- data/lib/sqreen/dependency/rack.rb +10 -5
- data/lib/sqreen/dependency/rails.rb +8 -0
- data/lib/sqreen/dependency/sentry.rb +2 -0
- data/lib/sqreen/dependency/sinatra.rb +58 -14
- data/lib/sqreen/encoding_sanitizer.rb +2 -0
- data/lib/sqreen/error_handling_middleware.rb +32 -0
- data/lib/sqreen/event.rb +4 -0
- data/lib/sqreen/events/attack.rb +4 -0
- data/lib/sqreen/events/remote_exception.rb +2 -0
- data/lib/sqreen/events/request_record.rb +13 -56
- data/lib/sqreen/exception.rb +11 -40
- data/lib/sqreen/formatter_with_tid.rb +47 -0
- data/lib/sqreen/framework_cb.rb +30 -0
- data/lib/sqreen/frameworks.rb +9 -0
- data/lib/sqreen/frameworks/generic.rb +22 -2
- data/lib/sqreen/frameworks/rails.rb +3 -0
- data/lib/sqreen/frameworks/rails3.rb +2 -0
- data/lib/sqreen/frameworks/request_recorder.rb +5 -0
- data/lib/sqreen/frameworks/sinatra.rb +4 -0
- data/lib/sqreen/frameworks/sqreen_test.rb +4 -0
- data/lib/sqreen/graft.rb +12 -0
- data/lib/sqreen/graft/call.rb +150 -0
- data/lib/sqreen/{dependency → graft}/callback.rb +12 -4
- data/lib/sqreen/graft/hook.rb +316 -0
- data/lib/sqreen/{dependency → graft}/hook_point.rb +152 -33
- data/lib/sqreen/graft/hook_point_error.rb +10 -0
- data/lib/sqreen/invalid_signature_exception.rb +10 -0
- data/lib/sqreen/js.rb +11 -0
- data/lib/sqreen/js/call_context.rb +12 -0
- data/lib/sqreen/js/context_pool.rb +62 -0
- data/lib/sqreen/js/exec_js_runnable.rb +22 -0
- data/lib/sqreen/js/execjs_adapter.rb +8 -47
- data/lib/sqreen/js/executable_js.rb +14 -0
- data/lib/sqreen/js/js_service.rb +4 -22
- data/lib/sqreen/js/js_service_adapter.rb +20 -0
- data/lib/sqreen/js/mini_racer_adapter.rb +8 -180
- data/lib/sqreen/js/mini_racer_executable_js.rb +144 -0
- data/lib/sqreen/js/thread_local_exec_js_runnable.rb +49 -0
- data/lib/{sqreen-alt.rb → sqreen/legacy.rb} +5 -1
- data/lib/sqreen/{instrumentation.rb → legacy/instrumentation.rb} +44 -15
- data/lib/sqreen/log.rb +10 -188
- data/lib/sqreen/log/loggable.rb +28 -0
- data/lib/sqreen/logger.rb +85 -0
- data/lib/sqreen/metrics.rb +2 -0
- data/lib/sqreen/metrics/average.rb +2 -0
- data/lib/sqreen/metrics/base.rb +2 -0
- data/lib/sqreen/metrics/binning.rb +2 -0
- data/lib/sqreen/metrics/collect.rb +2 -0
- data/lib/sqreen/metrics/sum.rb +2 -0
- data/lib/sqreen/metrics_store.rb +5 -11
- data/lib/sqreen/metrics_store/already_registered_metric.rb +13 -0
- data/lib/sqreen/metrics_store/unknown_metric.rb +13 -0
- data/lib/sqreen/metrics_store/unregistered_metric.rb +13 -0
- data/lib/sqreen/middleware.rb +2 -34
- data/lib/sqreen/mono_time.rb +4 -0
- data/lib/sqreen/node.rb +46 -0
- data/lib/sqreen/not_implemented_yet.rb +10 -0
- data/lib/sqreen/null_logger.rb +26 -0
- data/lib/sqreen/payload_creator.rb +4 -19
- data/lib/sqreen/payload_creator/header_section.rb +30 -0
- data/lib/sqreen/performance_notifications.rb +2 -0
- data/lib/sqreen/performance_notifications/binned_metrics.rb +2 -0
- data/lib/sqreen/performance_notifications/log.rb +2 -0
- data/lib/sqreen/performance_notifications/log_performance.rb +2 -0
- data/lib/sqreen/performance_notifications/metrics.rb +2 -0
- data/lib/sqreen/performance_notifications/newrelic.rb +2 -0
- data/lib/sqreen/prefix.rb +35 -0
- data/lib/sqreen/rails_middleware.rb +16 -0
- data/lib/sqreen/remote_command.rb +3 -8
- data/lib/sqreen/remote_command/failure_output.rb +16 -0
- data/lib/sqreen/rules.rb +34 -2
- data/lib/sqreen/{rule_attributes.rb → rules/attrs.rb} +2 -0
- data/lib/sqreen/{rules_callbacks/sdk_auth_track.rb → rules/auth_track_cb.rb} +4 -2
- data/lib/sqreen/{rules_callbacks/binding_accessor_matcher.rb → rules/binding_accessor_matcher_cb.rb} +6 -8
- data/lib/sqreen/{rules_callbacks → rules}/binding_accessor_metrics.rb +3 -1
- data/lib/sqreen/{rules_callbacks/blacklist_ips.rb → rules/blacklist_ips_cb.rb} +5 -2
- data/lib/sqreen/{rules_callbacks → rules}/count_http_codes.rb +4 -2
- data/lib/sqreen/{rules_callbacks/crawler_user_agent_matches.rb → rules/crawler_user_agent_matches_cb.rb} +3 -1
- data/lib/sqreen/{rules_callbacks/crawler_user_agent_matches_metrics.rb → rules/crawler_user_agent_matches_metrics_cb.rb} +3 -1
- data/lib/sqreen/{rules_callbacks/custom_error.rb → rules/custom_error_cb.rb} +3 -1
- data/lib/sqreen/{rules_callbacks/devise_auth_track.rb → rules/devise_auth_track_cb.rb} +4 -2
- data/lib/sqreen/{rules_callbacks/devise_signup_track.rb → rules/devise_signup_track_cb.rb} +4 -2
- data/lib/sqreen/{rules_callbacks/execjs.rb → rules/execjs_cb.rb} +51 -50
- data/lib/sqreen/{rules_callbacks/headers_insert.rb → rules/headers_insert_cb.rb} +8 -1
- data/lib/sqreen/{rules_callbacks → rules}/matcher_rule.rb +4 -2
- data/lib/sqreen/{rules_callbacks/not_found.rb → rules/not_found_cb.rb} +7 -2
- data/lib/sqreen/{rules_callbacks/rails_parameters.rb → rules/rails_parameters_cb.rb} +3 -1
- data/lib/sqreen/{rules_callbacks → rules}/record_request_context.rb +3 -1
- data/lib/sqreen/{rules_callbacks/regexp_rule.rb → rules/regexp_rule_cb.rb} +3 -1
- data/lib/sqreen/{rule_callback.rb → rules/rule_cb.rb} +4 -2
- data/lib/sqreen/{rules_callbacks → rules}/run_req_start_actions.rb +7 -3
- data/lib/sqreen/{rules_callbacks → rules}/run_user_actions.rb +4 -2
- data/lib/sqreen/{rules_callbacks/shell_env.rb → rules/shell_env_cb.rb} +3 -1
- data/lib/sqreen/{rules_callbacks/sdk_signup_track.rb → rules/signup_track_cb.rb} +4 -2
- data/lib/sqreen/rules/update_request_context.rb +22 -0
- data/lib/sqreen/{rules_callbacks/url_matches.rb → rules/url_matches_cb.rb} +3 -1
- data/lib/sqreen/{rules_callbacks/user_agent_matches.rb → rules/user_agent_matches_cb.rb} +3 -1
- data/lib/sqreen/{rules_callbacks/waf.rb → rules/waf_cb.rb} +41 -21
- data/lib/sqreen/{rules_callbacks/reflected_xss.rb → rules/xss_cb.rb} +12 -7
- data/lib/sqreen/run_when_called_cb.rb +23 -0
- data/lib/sqreen/runner.rb +25 -7
- data/lib/sqreen/runtime_infos.rb +4 -9
- data/lib/sqreen/safe_json.rb +2 -0
- data/lib/sqreen/sdk.rb +4 -0
- data/lib/sqreen/sensitive_data_redactor.rb +113 -0
- data/lib/sqreen/serializer.rb +2 -0
- data/lib/sqreen/session.rb +2 -0
- data/lib/sqreen/shared_storage.rb +2 -0
- data/lib/sqreen/shared_storage23.rb +2 -0
- data/lib/sqreen/shrink_wrap.rb +16 -0
- data/lib/sqreen/signature_verifier.rb +22 -0
- data/lib/sqreen/sinatra_middleware.rb +16 -0
- data/lib/sqreen/{rules_signature.rb → sqreen_signed_verifier.rb} +7 -17
- data/lib/sqreen/token_invalid_exception.rb +10 -0
- data/lib/sqreen/token_not_found_exception.rb +11 -0
- data/lib/sqreen/trie.rb +5 -64
- data/lib/sqreen/unauthorized.rb +10 -0
- data/lib/sqreen/util.rb +7 -0
- data/lib/sqreen/util/capped_array.rb +35 -0
- data/lib/sqreen/util/capped_hash.rb +41 -0
- data/lib/sqreen/util/capped_string.rb +26 -0
- data/lib/sqreen/util/capper.rb +67 -0
- data/lib/sqreen/version.rb +3 -1
- data/lib/sqreen/waf_error.rb +20 -0
- data/lib/sqreen/weave.rb +12 -0
- data/lib/sqreen/weave/hardcoded.rb +19 -0
- data/lib/sqreen/weave/instrumentor.rb +48 -0
- data/lib/sqreen/weave/legacy.rb +12 -0
- data/lib/sqreen/weave/legacy/instrumentation.rb +406 -0
- data/lib/sqreen/web_server.rb +2 -0
- data/lib/sqreen/web_server/generic.rb +2 -0
- data/lib/sqreen/web_server/passenger.rb +2 -0
- data/lib/sqreen/web_server/puma.rb +2 -0
- data/lib/sqreen/web_server/rainbows.rb +2 -0
- data/lib/sqreen/web_server/thin.rb +2 -0
- data/lib/sqreen/web_server/unicorn.rb +2 -0
- data/lib/sqreen/web_server/webrick.rb +2 -0
- data/lib/sqreen/worker.rb +2 -0
- metadata +105 -39
- data/lib/sqreen/dependency/hook.rb +0 -102
- data/lib/sqreen/rules_callbacks.rb +0 -35
- data/lib/sqreen/rules_callbacks/inspect_rule.rb +0 -25
data/lib/sqreen/runner.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# typed: ignore
|
|
2
|
+
|
|
1
3
|
# Copyright (c) 2015 Sqreen. All Rights Reserved.
|
|
2
4
|
# Please refer to our terms for more information: https://www.sqreen.com/terms.html
|
|
3
5
|
|
|
@@ -18,8 +20,9 @@ require 'sqreen/deliveries/simple'
|
|
|
18
20
|
require 'sqreen/deliveries/batch'
|
|
19
21
|
require 'sqreen/performance_notifications/metrics'
|
|
20
22
|
require 'sqreen/performance_notifications/binned_metrics'
|
|
21
|
-
require 'sqreen/instrumentation'
|
|
23
|
+
require 'sqreen/legacy/instrumentation'
|
|
22
24
|
require 'sqreen/call_countable'
|
|
25
|
+
require 'sqreen/weave/legacy/instrumentation'
|
|
23
26
|
|
|
24
27
|
module Sqreen
|
|
25
28
|
@features = {}
|
|
@@ -117,7 +120,16 @@ module Sqreen
|
|
|
117
120
|
register_exit_cb if set_at_exit
|
|
118
121
|
|
|
119
122
|
self.metrics_engine = MetricsStore.new
|
|
120
|
-
|
|
123
|
+
|
|
124
|
+
needs_weave = proc do
|
|
125
|
+
Gem::Specification.select { |s| s.name == 'scout_apm' && Gem::Requirement.new('>= 2.5.2').satisfied_by?(Gem::Version.new(s.version)) }.any?
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
if @configuration.get(:weave) || needs_weave.call
|
|
129
|
+
@instrumenter = Sqreen::Weave::Legacy::Instrumentation.new(metrics_engine)
|
|
130
|
+
else
|
|
131
|
+
@instrumenter = Sqreen::Legacy::Instrumentation.new(metrics_engine)
|
|
132
|
+
end
|
|
121
133
|
|
|
122
134
|
Sqreen.log.debug "Using token #{@token}"
|
|
123
135
|
response = create_session(session_class)
|
|
@@ -235,7 +247,7 @@ module Sqreen
|
|
|
235
247
|
def remove_instrumentation(_context_infos = {})
|
|
236
248
|
Sqreen.log.debug 'Removing instrumentation'
|
|
237
249
|
instrumenter.remove_all_callbacks
|
|
238
|
-
Sqreen::Actions::Repository.
|
|
250
|
+
Sqreen::Actions::Repository.clear
|
|
239
251
|
Sqreen.log.debug 'Instrumentation removed'
|
|
240
252
|
true
|
|
241
253
|
end
|
|
@@ -244,7 +256,6 @@ module Sqreen
|
|
|
244
256
|
Sqreen.log.debug 'Reloading rules'
|
|
245
257
|
rulespack_id, rules = load_rules
|
|
246
258
|
instrumenter.remove_all_callbacks
|
|
247
|
-
Sqreen::Actions::Repository.instance.clear
|
|
248
259
|
|
|
249
260
|
@framework.instrument_when_ready!(instrumenter, rules)
|
|
250
261
|
Sqreen.log.debug 'Rules reloaded'
|
|
@@ -304,12 +315,18 @@ module Sqreen
|
|
|
304
315
|
Sqreen.update_features(features)
|
|
305
316
|
session.request_compression = features['request_compression'] if session
|
|
306
317
|
self.performance_metrics_period = features['performance_metrics_period']
|
|
318
|
+
|
|
319
|
+
unless @configuration.get(:weave)
|
|
320
|
+
|
|
307
321
|
config_binned_metrics(features['perf_level'] || DEFAULT_PERF_LEVEL,
|
|
308
322
|
features['perf_base'] || PerformanceNotifications::BinnedMetrics::DEFAULT_PERF_BASE,
|
|
309
323
|
features['perf_unit'] || PerformanceNotifications::BinnedMetrics::DEFAULT_PERF_UNIT,
|
|
310
324
|
features['perf_pct_base'] || PerformanceNotifications::BinnedMetrics::DEFAULT_PERF_PCT_BASE,
|
|
311
325
|
features['perf_pct_unit'] || PerformanceNotifications::BinnedMetrics::DEFAULT_PERF_PCT_UNIT,
|
|
312
326
|
)
|
|
327
|
+
|
|
328
|
+
end
|
|
329
|
+
|
|
313
330
|
self.call_counts_metrics_period = features['call_counts_metrics_period']
|
|
314
331
|
hd = features['heartbeat_delay'].to_i
|
|
315
332
|
self.heartbeat_delay = hd if hd > 0
|
|
@@ -456,13 +473,12 @@ module Sqreen
|
|
|
456
473
|
def load_actions(hashes)
|
|
457
474
|
unsupported = Set.new
|
|
458
475
|
|
|
459
|
-
|
|
460
|
-
repos.clear
|
|
476
|
+
new_repos = Sqreen::Actions::Repository.new
|
|
461
477
|
|
|
462
478
|
actions = hashes.map do |h|
|
|
463
479
|
begin
|
|
464
480
|
act = Sqreen::Actions.deserialize_action(h)
|
|
465
|
-
|
|
481
|
+
new_repos.add h['parameters'], act
|
|
466
482
|
act
|
|
467
483
|
rescue Sqreen::Actions::UnknownActionType => e
|
|
468
484
|
Sqreen.log.warn("Unsupported action type: #{e.action_type}")
|
|
@@ -476,6 +492,8 @@ module Sqreen
|
|
|
476
492
|
actions = actions.reject(&:nil?)
|
|
477
493
|
Sqreen.log.debug("Added #{actions.size} valid actions")
|
|
478
494
|
|
|
495
|
+
Sqreen::Actions::Repository.current = new_repos
|
|
496
|
+
|
|
479
497
|
unsupported
|
|
480
498
|
end
|
|
481
499
|
end
|
data/lib/sqreen/runtime_infos.rb
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
|
+
# typed: ignore
|
|
2
|
+
|
|
1
3
|
# Copyright (c) 2015 Sqreen. All Rights Reserved.
|
|
2
4
|
# Please refer to our terms for more information: https://www.sqreen.com/terms.html
|
|
3
5
|
|
|
4
6
|
require 'sqreen/version'
|
|
5
7
|
require 'sqreen/frameworks'
|
|
8
|
+
require 'sqreen/dependency/libsqreen'
|
|
6
9
|
|
|
7
10
|
require 'socket'
|
|
8
11
|
require 'digest/sha1'
|
|
@@ -71,15 +74,7 @@ module Sqreen
|
|
|
71
74
|
end
|
|
72
75
|
|
|
73
76
|
def libsqreen?
|
|
74
|
-
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
def libsqreen_loaded?
|
|
78
|
-
Kernel.const_defined?('LibSqreen')
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
def libsqreen_stub?
|
|
82
|
-
!::LibSqreen.respond_to?(:version)
|
|
77
|
+
Sqreen::Dependency::LibSqreen.required? && !Sqreen::Dependency::LibSqreen.stub?
|
|
83
78
|
end
|
|
84
79
|
|
|
85
80
|
def libsqreen_version
|
data/lib/sqreen/safe_json.rb
CHANGED
data/lib/sqreen/sdk.rb
CHANGED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# typed: true
|
|
2
|
+
|
|
3
|
+
# Copyright (c) 2015 Sqreen. All Rights Reserved.
|
|
4
|
+
# Please refer to our terms for more information: https://www.sqreen.com/terms.html
|
|
5
|
+
|
|
6
|
+
# TODO: Sqreen.config_get
|
|
7
|
+
|
|
8
|
+
require 'json'
|
|
9
|
+
require 'sqreen/log'
|
|
10
|
+
|
|
11
|
+
module Sqreen
|
|
12
|
+
# For redacting sensitive data and avoid having it sent to our servers
|
|
13
|
+
class SensitiveDataRedactor
|
|
14
|
+
DEFAULT_SENSITIVE_KEYS = Set.new(%w[password secret passwd authorization api_key apikey access_token]).freeze
|
|
15
|
+
DEFAULT_REGEX = /\A(?:\d[ -]*?){13,16}\z/
|
|
16
|
+
MASK = '<Redacted by Sqreen>'.freeze
|
|
17
|
+
|
|
18
|
+
def self.from_config
|
|
19
|
+
keys = Sqreen.config_get(:strip_sensitive_keys)
|
|
20
|
+
keys = keys.split(',') if keys && keys.is_a?(String)
|
|
21
|
+
|
|
22
|
+
regex = Sqreen.config_get(:strip_sensitive_regex)
|
|
23
|
+
if regex && regex.is_a?(String)
|
|
24
|
+
begin
|
|
25
|
+
regex = Regexp.compile(regex)
|
|
26
|
+
rescue RegexpError
|
|
27
|
+
Sqreen.log.warn("Invalid regular expression given in strip_sensitive_regex: #{regex}")
|
|
28
|
+
regex = nil
|
|
29
|
+
end
|
|
30
|
+
else
|
|
31
|
+
regex = nil
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
new(keys: keys, regex: regex)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def initialize(params = {})
|
|
38
|
+
@regex = params[:regex] || DEFAULT_REGEX
|
|
39
|
+
@keys = (params[:keys] || DEFAULT_SENSITIVE_KEYS).map(&:downcase)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def redact(obj)
|
|
43
|
+
result = obj
|
|
44
|
+
redacted = []
|
|
45
|
+
|
|
46
|
+
case obj
|
|
47
|
+
when String
|
|
48
|
+
if obj =~ @regex
|
|
49
|
+
result = MASK
|
|
50
|
+
redacted << obj
|
|
51
|
+
end
|
|
52
|
+
when Array
|
|
53
|
+
result = []
|
|
54
|
+
obj.each do |e|
|
|
55
|
+
e, r = redact(e)
|
|
56
|
+
result << e
|
|
57
|
+
redacted += r
|
|
58
|
+
end
|
|
59
|
+
when Hash
|
|
60
|
+
result = {}
|
|
61
|
+
obj.each do |k, v|
|
|
62
|
+
ck = k.is_a?(String) ? k.downcase : k
|
|
63
|
+
if @keys.include?(ck)
|
|
64
|
+
redacted << v
|
|
65
|
+
v = MASK
|
|
66
|
+
else
|
|
67
|
+
v, r = redact(v)
|
|
68
|
+
redacted += r
|
|
69
|
+
end
|
|
70
|
+
result[k] = v
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
[result, redacted]
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def redact_attacks!(attacks, values)
|
|
78
|
+
return attacks if values.empty?
|
|
79
|
+
|
|
80
|
+
values = values.map { |v| v.downcase if v.is_a?(String) }
|
|
81
|
+
|
|
82
|
+
attacks.each do |e|
|
|
83
|
+
next(e) unless e[:infos]
|
|
84
|
+
next(e) unless e[:infos][:waf_data]
|
|
85
|
+
|
|
86
|
+
parsed = JSON.parse(e[:infos][:waf_data])
|
|
87
|
+
redacted = parsed.each do |w|
|
|
88
|
+
next unless (filters = w['filter'])
|
|
89
|
+
|
|
90
|
+
filters.each do |f|
|
|
91
|
+
next unless (v = f['resolved_value'])
|
|
92
|
+
next unless values.include?(v.downcase)
|
|
93
|
+
|
|
94
|
+
f['match_status'] = MASK
|
|
95
|
+
f['resolved_value'] = MASK
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
e[:infos][:waf_data] = JSON.dump(redacted)
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def redact_exceptions!(exceptions, values)
|
|
103
|
+
return exceptions if values.empty?
|
|
104
|
+
|
|
105
|
+
exceptions.each do |e|
|
|
106
|
+
next(e) unless e[:infos]
|
|
107
|
+
next(e) unless e[:infos][:waf]
|
|
108
|
+
|
|
109
|
+
e[:infos][:waf].delete(:args)
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
data/lib/sqreen/serializer.rb
CHANGED
data/lib/sqreen/session.rb
CHANGED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# typed: true
|
|
2
|
+
|
|
3
|
+
# Copyright (c) 2015 Sqreen. All Rights Reserved.
|
|
4
|
+
# Please refer to our terms for more information: https://www.sqreen.com/terms.html
|
|
5
|
+
|
|
6
|
+
module Sqreen
|
|
7
|
+
class ShrinkWrap
|
|
8
|
+
def initialize(app)
|
|
9
|
+
@app = app
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def call(env)
|
|
13
|
+
@app.call(env)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# typed: true
|
|
2
|
+
|
|
3
|
+
# Copyright (c) 2015 Sqreen. All Rights Reserved.
|
|
4
|
+
# Please refer to our terms for more information: https://www.sqreen.com/terms.html
|
|
5
|
+
|
|
6
|
+
require 'openssl'
|
|
7
|
+
|
|
8
|
+
## Rules signature
|
|
9
|
+
module Sqreen
|
|
10
|
+
# Perform an EC + digest verification of a message.
|
|
11
|
+
class SignatureVerifier
|
|
12
|
+
def initialize(key, digest)
|
|
13
|
+
@pub_key = OpenSSL::PKey.read(key)
|
|
14
|
+
@digest = digest
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def verify(sig, val)
|
|
18
|
+
hashed_val = @digest.digest(val)
|
|
19
|
+
@pub_key.dsa_verify_asn1(hashed_val, sig)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# typed: true
|
|
2
|
+
|
|
3
|
+
# Copyright (c) 2015 Sqreen. All Rights Reserved.
|
|
4
|
+
# Please refer to our terms for more information: https://www.sqreen.com/terms.html
|
|
5
|
+
|
|
6
|
+
module Sqreen
|
|
7
|
+
class SinatraMiddleware
|
|
8
|
+
def initialize(app)
|
|
9
|
+
@app = app
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def call(env)
|
|
13
|
+
@app.call(env)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
# typed: false
|
|
2
|
+
|
|
1
3
|
# Copyright (c) 2015 Sqreen. All Rights Reserved.
|
|
2
4
|
# Please refer to our terms for more information: https://www.sqreen.com/terms.html
|
|
3
5
|
|
|
4
|
-
require 'sqreen/exception'
|
|
5
|
-
|
|
6
6
|
require 'set'
|
|
7
7
|
require 'openssl'
|
|
8
8
|
require 'base64'
|
|
@@ -18,21 +18,11 @@ else
|
|
|
18
18
|
end
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
+
require 'sqreen/exception'
|
|
22
|
+
require 'sqreen/signature_verifier'
|
|
23
|
+
|
|
21
24
|
## Rules signature
|
|
22
25
|
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
26
|
# Normalize and verify a rule
|
|
37
27
|
class SqreenSignedVerifier
|
|
38
28
|
REQUIRED_SIGNED_KEYS = %w[hookpoint name callbacks conditions].freeze
|
|
@@ -40,14 +30,14 @@ module Sqreen
|
|
|
40
30
|
SIGNATURE_VALUE_KEY = 'value'.freeze
|
|
41
31
|
SIGNED_KEYS_KEY = 'keys'.freeze
|
|
42
32
|
SIGNATURE_VERSION = 'v0_9'.freeze
|
|
43
|
-
PUBLIC_KEY = <<-
|
|
33
|
+
PUBLIC_KEY = <<-KEY.gsub(/^ */, '').freeze
|
|
44
34
|
-----BEGIN PUBLIC KEY-----
|
|
45
35
|
MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQA39oWMHR8sxb9LRaM5evZ7mw03iwJ
|
|
46
36
|
WNHuDeGqgPo1HmvuMfLnAyVLwaMXpGPuvbqhC1U65PG90bTJLpvNokQf0VMA5Tpi
|
|
47
37
|
m+NXwl7bjqa03vO/HErLbq3zBRysrZnC4OhJOF1jazkAg0psQOea2r5HcMcPHgMK
|
|
48
38
|
fnWXiKWnZX+uOWPuerE=
|
|
49
39
|
-----END PUBLIC KEY-----
|
|
50
|
-
|
|
40
|
+
KEY
|
|
51
41
|
|
|
52
42
|
attr_accessor :pub_key
|
|
53
43
|
attr_accessor :required_signed_keys
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# typed: strong
|
|
2
|
+
|
|
3
|
+
# Copyright (c) 2015 Sqreen. All Rights Reserved.
|
|
4
|
+
# Please refer to our terms for more information: https://www.sqreen.com/terms.html
|
|
5
|
+
|
|
6
|
+
require 'sqreen/exception'
|
|
7
|
+
|
|
8
|
+
module Sqreen
|
|
9
|
+
class TokenInvalidException < Sqreen::Exception; end
|
|
10
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# typed: strong
|
|
2
|
+
|
|
3
|
+
# Copyright (c) 2015 Sqreen. All Rights Reserved.
|
|
4
|
+
# Please refer to our terms for more information: https://www.sqreen.com/terms.html
|
|
5
|
+
|
|
6
|
+
require 'sqreen/exception'
|
|
7
|
+
|
|
8
|
+
module Sqreen
|
|
9
|
+
# When the token is not found
|
|
10
|
+
class TokenNotFoundException < Sqreen::Exception; end
|
|
11
|
+
end
|
data/lib/sqreen/trie.rb
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
|
+
# typed: false
|
|
2
|
+
|
|
1
3
|
# Copyright (c) 2015 Sqreen. All Rights Reserved.
|
|
2
4
|
# Please refer to our terms for more information: https://www.sqreen.com/terms.html
|
|
3
5
|
|
|
4
6
|
require 'ipaddr'
|
|
7
|
+
require 'sqreen/node'
|
|
8
|
+
|
|
9
|
+
# TODO: move to Sqreen::IP
|
|
5
10
|
|
|
6
11
|
module Sqreen
|
|
7
12
|
Trie = Struct.new(:head, :num_active_nodes, :family) do
|
|
@@ -211,68 +216,4 @@ module Sqreen
|
|
|
211
216
|
xstack
|
|
212
217
|
end
|
|
213
218
|
end
|
|
214
|
-
|
|
215
|
-
Prefix = Struct.new(:family, :bitlen, :address, :data) do # addr is integer
|
|
216
|
-
def initialize(*args)
|
|
217
|
-
super
|
|
218
|
-
raise ArgumentError, 'no family given' unless family
|
|
219
|
-
raise ArgumentError, 'no bitlen given' unless bitlen
|
|
220
|
-
raise ArgumentError, 'no address given' unless address
|
|
221
|
-
end
|
|
222
|
-
|
|
223
|
-
def matches?(addr, family)
|
|
224
|
-
raise 'family mismatch' unless family == self.family
|
|
225
|
-
shift_amount = (family == Socket::AF_INET ? 32 : 128) - self.bitlen
|
|
226
|
-
(addr ^ self.address) >> shift_amount == 0
|
|
227
|
-
end
|
|
228
|
-
end
|
|
229
|
-
|
|
230
|
-
def Prefix.from_str(str, data = nil)
|
|
231
|
-
ip_addr = IPAddr.new(str)
|
|
232
|
-
if str =~ /\/(\d+)$/
|
|
233
|
-
bitlen = $~[1].to_i
|
|
234
|
-
else
|
|
235
|
-
bitlen = ip_addr.family == Socket::AF_INET6 ? 128 : 32
|
|
236
|
-
end
|
|
237
|
-
Prefix.new(ip_addr.family, bitlen, ip_addr.to_i, data)
|
|
238
|
-
end
|
|
239
|
-
|
|
240
|
-
# bit starts at 0 (most significant)
|
|
241
|
-
Node = Struct.new(:bit, :prefix, :l, :r, :parent) do
|
|
242
|
-
def initialize(*args)
|
|
243
|
-
super
|
|
244
|
-
raise ArgumentError, 'no bit given' if bit.nil?
|
|
245
|
-
end
|
|
246
|
-
|
|
247
|
-
def empty?
|
|
248
|
-
prefix.nil?
|
|
249
|
-
end
|
|
250
|
-
|
|
251
|
-
# cover the whole tree
|
|
252
|
-
def walk(max_bits, empty_nodes = false)
|
|
253
|
-
xstack = Array.new(max_bits + 1)
|
|
254
|
-
sidx = 0 # stack index
|
|
255
|
-
xhead = self
|
|
256
|
-
xcur = xhead
|
|
257
|
-
while !xcur.nil?
|
|
258
|
-
yield xcur unless xcur.empty? && !empty_nodes
|
|
259
|
-
|
|
260
|
-
if xcur.l
|
|
261
|
-
if xcur.r
|
|
262
|
-
xstack[sidx] = xcur.r
|
|
263
|
-
sidx += 1
|
|
264
|
-
end
|
|
265
|
-
xcur = xcur.l
|
|
266
|
-
elsif xcur.r
|
|
267
|
-
xcur = xcur.r
|
|
268
|
-
elsif sidx.nonzero?
|
|
269
|
-
sidx -= 1
|
|
270
|
-
xcur = xstack[sidx]
|
|
271
|
-
else
|
|
272
|
-
xcur = nil
|
|
273
|
-
end
|
|
274
|
-
end
|
|
275
|
-
end
|
|
276
|
-
end
|
|
277
|
-
|
|
278
219
|
end
|