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
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# typed: false
|
|
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: remove class vars
|
|
7
|
+
|
|
8
|
+
require 'sqreen/sdk'
|
|
9
|
+
require 'sqreen/exception'
|
|
10
|
+
|
|
11
|
+
module Sqreen
|
|
12
|
+
# Implements actions (behavior taken in response to agent signals)
|
|
13
|
+
module Actions
|
|
14
|
+
# Base class for actions
|
|
15
|
+
# subclasses must also implement some methods in their singleton classes
|
|
16
|
+
# (actions_matching, index and clear)
|
|
17
|
+
class Base
|
|
18
|
+
attr_reader :id, :expiry, :send_response
|
|
19
|
+
|
|
20
|
+
def initialize(id, opts)
|
|
21
|
+
@id = id
|
|
22
|
+
duration = opts[:duration]
|
|
23
|
+
@expiry = Time.new + duration unless duration.nil?
|
|
24
|
+
@send_response = if opts[:send_response].nil?
|
|
25
|
+
true
|
|
26
|
+
else
|
|
27
|
+
opts[:send_response] ? true : false
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# See Sqreen::CB for return values
|
|
32
|
+
def run(*args)
|
|
33
|
+
return if expiry && Time.new > expiry
|
|
34
|
+
ret = do_run(*args)
|
|
35
|
+
unless ret.nil? || !@send_response
|
|
36
|
+
Sqreen.internal_track(event_name,
|
|
37
|
+
'properties' => {
|
|
38
|
+
'output' => event_properties(*args),
|
|
39
|
+
'action_id' => id,
|
|
40
|
+
})
|
|
41
|
+
end
|
|
42
|
+
ret
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
protected
|
|
46
|
+
|
|
47
|
+
def do_run(*_args)
|
|
48
|
+
raise ::Sqreen::NotImplementedYet, "do_run not implemented in #{self.class}"
|
|
49
|
+
# implement in subclasses
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def event_properties(*_run_args)
|
|
53
|
+
raise ::Sqreen::NotImplementedYet, "event_properties not implemented in #{self.class}"
|
|
54
|
+
# implement in subclasses
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
private
|
|
58
|
+
|
|
59
|
+
def event_name
|
|
60
|
+
"sq.action.#{self.class.type_name}"
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
@@subclasses = {} # rubocop:disable Style/ClassVars
|
|
64
|
+
class << self
|
|
65
|
+
private :new
|
|
66
|
+
|
|
67
|
+
attr_reader :type_name
|
|
68
|
+
|
|
69
|
+
def get_type_class(name)
|
|
70
|
+
subclasses[name]
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def known_subclasses
|
|
74
|
+
subclasses.values
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def known_types
|
|
78
|
+
subclasses.keys
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def new_index
|
|
82
|
+
raise 'implement in singletons of subclasses'
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def inherited(subclass)
|
|
86
|
+
class << subclass
|
|
87
|
+
public :new
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
protected
|
|
92
|
+
|
|
93
|
+
def subclasses
|
|
94
|
+
@@subclasses
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def type_name=(name)
|
|
98
|
+
@type_name = name
|
|
99
|
+
subclasses[name] = self
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
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 'sqreen/exception'
|
|
7
|
+
require 'sqreen/actions/base'
|
|
8
|
+
require 'sqreen/actions/ip_range_indexed_action_class'
|
|
9
|
+
|
|
10
|
+
module Sqreen
|
|
11
|
+
module Actions
|
|
12
|
+
# Block a list of IP address ranges. Standard "raise" behavior.
|
|
13
|
+
class BlockIp < Base
|
|
14
|
+
extend IpRangeIndexedActionClass
|
|
15
|
+
|
|
16
|
+
self.type_name = 'block_ip'
|
|
17
|
+
|
|
18
|
+
def initialize(id, opts, _params = {})
|
|
19
|
+
# no need to store the ranges for this action, the index filter the class
|
|
20
|
+
super(id, opts)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def do_run(client_ip)
|
|
24
|
+
e = Sqreen::AttackBlocked.new("Blocked client's IP #{client_ip} " \
|
|
25
|
+
"(action: #{id}). No action is required")
|
|
26
|
+
{ :status => :raise, :exception => e, :skip_rem_cbs => true }
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def event_properties(client_ip)
|
|
30
|
+
{ 'ip_address' => client_ip }
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
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 'sqreen/log'
|
|
7
|
+
require 'sqreen/exception'
|
|
8
|
+
require 'sqreen/actions/base'
|
|
9
|
+
require 'sqreen/actions/user_action_class'
|
|
10
|
+
|
|
11
|
+
module Sqreen
|
|
12
|
+
module Actions
|
|
13
|
+
# Blocks a user at the point Sqreen::identify()
|
|
14
|
+
# or Sqreen::auth_track() are called
|
|
15
|
+
class BlockUser < Base
|
|
16
|
+
extend UserActionClass
|
|
17
|
+
|
|
18
|
+
self.type_name = 'block_user'
|
|
19
|
+
|
|
20
|
+
def initialize(id, opts, _params = {})
|
|
21
|
+
super(id, opts)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def do_run(identity_params)
|
|
25
|
+
Sqreen.log.info(
|
|
26
|
+
"Will raise due to user being blocked by action #{id}. " \
|
|
27
|
+
"Blocked user identity: #{identity_params}"
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
e = Sqreen::AttackBlocked.new(
|
|
31
|
+
"Blocked user with identity #{identity_params} " \
|
|
32
|
+
'due to automatic security response. No action is required'
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
{
|
|
36
|
+
:status => :raise,
|
|
37
|
+
:exception => e,
|
|
38
|
+
}
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def event_properties(identity_params)
|
|
42
|
+
{ 'user' => identity_params }
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
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
|
+
require 'sqreen/actions/ip_ranges_index'
|
|
7
|
+
|
|
8
|
+
module Sqreen
|
|
9
|
+
module Actions
|
|
10
|
+
module IpRangeIndexedActionClass
|
|
11
|
+
def new_index
|
|
12
|
+
IpRangesIndex.new
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
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 'ipaddr'
|
|
7
|
+
require 'sqreen/actions/actions_index'
|
|
8
|
+
require 'sqreen/trie'
|
|
9
|
+
require 'sqreen/prefix'
|
|
10
|
+
|
|
11
|
+
module Sqreen
|
|
12
|
+
module Actions
|
|
13
|
+
class IpRangesIndex < ActionsIndex
|
|
14
|
+
def initialize
|
|
15
|
+
@trie_v4 = Sqreen::Trie.new
|
|
16
|
+
@trie_v6 = Sqreen::Trie.new(nil, nil, Socket::AF_INET6)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def index(params, action)
|
|
20
|
+
ranges = parse_ip_ranges params
|
|
21
|
+
|
|
22
|
+
ranges.each do |r|
|
|
23
|
+
add_prefix r, action
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def actions_matching(client_ip)
|
|
28
|
+
parsed_ip = IPAddr.new(client_ip.gsub(/%[^%\/]+/, ''))
|
|
29
|
+
trie = parsed_ip.family == Socket::AF_INET6 ? @trie_v6 : @trie_v4
|
|
30
|
+
return [] unless trie
|
|
31
|
+
found = trie.search_matching(parsed_ip.to_i, parsed_ip.family)
|
|
32
|
+
return [] unless found.size > 0
|
|
33
|
+
|
|
34
|
+
Sqreen.log.debug("Client ip #{client_ip} matches #{found.inspect}")
|
|
35
|
+
found.map(&:data)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
private
|
|
39
|
+
|
|
40
|
+
# returns array of prefixes in string form
|
|
41
|
+
def parse_ip_ranges(params)
|
|
42
|
+
ranges = params['ip_cidr']
|
|
43
|
+
unless ranges && ranges.is_a?(Array) && !ranges.empty?
|
|
44
|
+
raise 'no non-empty ip_cidr array present'
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
ranges
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def add_prefix(prefix_str, data)
|
|
51
|
+
prefix = Sqreen::Prefix.from_str(prefix_str, data)
|
|
52
|
+
trie = prefix.family == Socket::AF_INET6 ? @trie_v6 : @trie_v4
|
|
53
|
+
trie.insert prefix
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
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 'sqreen/log'
|
|
7
|
+
require 'sqreen/exception'
|
|
8
|
+
require 'sqreen/actions/base'
|
|
9
|
+
|
|
10
|
+
module Sqreen
|
|
11
|
+
module Actions
|
|
12
|
+
# Block a list of IP address ranges by forcefully redirecting the user
|
|
13
|
+
# to a specific URL.
|
|
14
|
+
class RedirectIp < Base
|
|
15
|
+
extend IpRangeIndexedActionClass
|
|
16
|
+
|
|
17
|
+
self.type_name = 'redirect_ip'
|
|
18
|
+
|
|
19
|
+
attr_reader :redirect_url
|
|
20
|
+
|
|
21
|
+
def initialize(id, opts, params = {})
|
|
22
|
+
super(id, opts)
|
|
23
|
+
@redirect_url = params['url']
|
|
24
|
+
raise "no url provided for action #{id}" unless @redirect_url
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def do_run(client_ip)
|
|
28
|
+
Sqreen.log.info "Will request redirect for client with IP #{client_ip} " \
|
|
29
|
+
"(action: #{id})."
|
|
30
|
+
{
|
|
31
|
+
:status => :skip,
|
|
32
|
+
:new_return_value => [303, { 'Location' => @redirect_url }, ['']],
|
|
33
|
+
:skip_rem_cbs => true,
|
|
34
|
+
}
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def event_properties(client_ip)
|
|
38
|
+
{ 'ip_address' => client_ip, 'url' => @redirect_url }
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
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 'sqreen/log'
|
|
7
|
+
require 'sqreen/exception'
|
|
8
|
+
require 'sqreen/actions/base'
|
|
9
|
+
require 'sqreen/actions/user_action_class'
|
|
10
|
+
|
|
11
|
+
module Sqreen
|
|
12
|
+
module Actions
|
|
13
|
+
# Redirects a user at the point Sqreen::identify()
|
|
14
|
+
# or Sqreen::auth_track() are called
|
|
15
|
+
class RedirectUser < Base
|
|
16
|
+
extend UserActionClass
|
|
17
|
+
|
|
18
|
+
self.type_name = 'redirect_user'
|
|
19
|
+
|
|
20
|
+
def initialize(id, opts, params = {})
|
|
21
|
+
super(id, opts)
|
|
22
|
+
@redirect_url = params['url']
|
|
23
|
+
raise "no url provided for action #{id}" unless @redirect_url
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def do_run(identity_params)
|
|
27
|
+
Sqreen.log.info 'Will request redirect for user with identity ' \
|
|
28
|
+
"#{identity_params} (action: #{id})."
|
|
29
|
+
|
|
30
|
+
e = Sqreen::AttackBlocked.new(
|
|
31
|
+
"Redirected user with identity #{identity_params} " \
|
|
32
|
+
'due to automatic security response. No action is required'
|
|
33
|
+
)
|
|
34
|
+
e.redirect_url = @redirect_url
|
|
35
|
+
|
|
36
|
+
{
|
|
37
|
+
:status => :raise,
|
|
38
|
+
:exception => e,
|
|
39
|
+
}
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def event_properties(identity_params)
|
|
43
|
+
{ 'user' => identity_params }
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
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
|
+
module Actions
|
|
8
|
+
# Where the actions are stored
|
|
9
|
+
# The current ones are stored in Repository.current
|
|
10
|
+
class Repository
|
|
11
|
+
def initialize
|
|
12
|
+
@indexes = Hash[Base.known_subclasses.map do |clazz|
|
|
13
|
+
[clazz.type_name, clazz.new_index]
|
|
14
|
+
end]
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def add(params, action)
|
|
18
|
+
@indexes[action.class.type_name].index(params || {}, action)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# type is either a class or a type name
|
|
22
|
+
def get(type, key)
|
|
23
|
+
type = type.type_name if type.class == Class
|
|
24
|
+
@indexes[type].actions_matching key
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
singleton_class.class_eval do
|
|
28
|
+
attr_reader :current
|
|
29
|
+
def current=(new_inst)
|
|
30
|
+
raise 'nil is unacceptable' if new_inst.nil?
|
|
31
|
+
@current = new_inst
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def clear
|
|
35
|
+
self.current = Repository.new
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# initialize current to empty repository
|
|
40
|
+
clear
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
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 'sqreen/exception'
|
|
7
|
+
|
|
8
|
+
module Sqreen
|
|
9
|
+
# Implements actions (behavior taken in response to agent signals)
|
|
10
|
+
module Actions
|
|
11
|
+
# Exception for when an unknown action type is gotten from the server
|
|
12
|
+
class UnknownActionType < ::Sqreen::Exception
|
|
13
|
+
attr_reader :action_type
|
|
14
|
+
def initialize(action_type)
|
|
15
|
+
super("no such action type: #{action_type}. Must be one of #{Base.known_types}")
|
|
16
|
+
@action_type = action_type
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
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
|
+
require 'sqreen/actions/users_index'
|
|
7
|
+
|
|
8
|
+
module Sqreen
|
|
9
|
+
module Actions
|
|
10
|
+
module UserActionClass
|
|
11
|
+
def new_index
|
|
12
|
+
UsersIndex.new
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# typed: true
|
|
2
|
+
require 'sqreen/actions/actions_index'
|
|
3
|
+
|
|
4
|
+
module Sqreen
|
|
5
|
+
module Actions
|
|
6
|
+
class UsersIndex < ActionsIndex
|
|
7
|
+
def actions_matching(identity_params)
|
|
8
|
+
return [] unless @idx
|
|
9
|
+
key = stringify_keys(identity_params)
|
|
10
|
+
actions = @idx[key]
|
|
11
|
+
actions || []
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def index(params, action)
|
|
15
|
+
@idx ||= {}
|
|
16
|
+
users = params['users']
|
|
17
|
+
raise ::Sqreen::Exception, 'nil "users" param for block_user action' if users.nil?
|
|
18
|
+
raise ::Sqreen::Exception, '"users" param must be an array' unless users.is_a? Array
|
|
19
|
+
|
|
20
|
+
users.each do |u|
|
|
21
|
+
@idx[u] ||= []
|
|
22
|
+
@idx[u] << action
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
def stringify_keys(hash)
|
|
29
|
+
Hash[
|
|
30
|
+
hash.map { |k, v| [k.to_s, v] }
|
|
31
|
+
]
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|