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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1a1340b0e4265b69cea5bb84456f52586f310ccc03aadd9d6974779707d55329
|
4
|
+
data.tar.gz: 4da37a0e4bd305d18fc06d164683f46dddf830c54a67c3a3f3481a6314efbc34
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 662b2f798f20452c4a8cd328608277f68748584e2e335a9e2f4cc5a3acdc97fd5345136048f23813c76dee8974a0ae1e62bb2018b97b0d2bbe729d31603fbfec
|
7
|
+
data.tar.gz: 9f4d4c1efad12ed3831dedb528a677d1cf92bb7a0c3c7a07c21c26b5838a5081e2b3a8944bfb3a89c80b6f80f09c9cb676af23839c401187702038aae014c8cf
|
data/CHANGELOG.md
CHANGED
data/lib/sqreen/actions.rb
CHANGED
@@ -1,51 +1,26 @@
|
|
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 '
|
5
|
-
require 'sqreen/
|
6
|
-
|
7
|
-
require 'sqreen/
|
8
|
-
require 'sqreen/
|
9
|
-
require 'sqreen/
|
10
|
-
require '
|
4
|
+
require 'sqreen/actions/unknown_action_type'
|
5
|
+
require 'sqreen/actions/base'
|
6
|
+
|
7
|
+
require 'sqreen/actions/block_user'
|
8
|
+
require 'sqreen/actions/redirect_user'
|
9
|
+
require 'sqreen/actions/block_ip'
|
10
|
+
require 'sqreen/actions/redirect_ip'
|
11
|
+
require 'sqreen/actions/repository'
|
12
|
+
require 'sqreen/actions/unknown_action_type'
|
11
13
|
|
12
14
|
module Sqreen
|
13
15
|
# Implements actions (behavior taken in response to agent signals)
|
14
16
|
module Actions
|
15
|
-
# Exception for when an unknown action type is gotten from the server
|
16
|
-
class UnknownActionType < ::Sqreen::Exception
|
17
|
-
attr_reader :action_type
|
18
|
-
def initialize(action_type)
|
19
|
-
super("no such action type: #{action_type}. Must be one of #{Base.known_types}")
|
20
|
-
@action_type = action_type
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
# Where the currently loaded actions are stored. Singleton
|
25
|
-
class Repository
|
26
|
-
include Singleton
|
27
|
-
|
28
|
-
def add(params, action)
|
29
|
-
action.class.index(params || {}, action)
|
30
|
-
end
|
31
|
-
|
32
|
-
def get(action_class, key)
|
33
|
-
action_class = Base.get_type_class(action_class) unless action_class.class == Class
|
34
|
-
action_class.actions_matching key
|
35
|
-
end
|
36
|
-
|
37
|
-
def clear
|
38
|
-
Base.known_subclasses.each(&:clear)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
17
|
# @return [Sqreen::Actions::Base]
|
43
18
|
def self.deserialize_action(hash)
|
44
19
|
action_type = hash['action']
|
45
20
|
raise 'no action type available' unless action_type
|
46
21
|
|
47
|
-
subclass = Base.get_type_class(action_type)
|
48
|
-
raise UnknownActionType, action_type unless subclass
|
22
|
+
subclass = Sqreen::Actions::Base.get_type_class(action_type)
|
23
|
+
raise Sqreen::Actions::UnknownActionType, action_type unless subclass
|
49
24
|
|
50
25
|
id = hash['action_id']
|
51
26
|
raise 'no action id available' unless id
|
@@ -63,306 +38,5 @@ module Sqreen
|
|
63
38
|
|
64
39
|
subclass.new(id, opts, hash['parameters'] || {})
|
65
40
|
end
|
66
|
-
|
67
|
-
# Base class for actions
|
68
|
-
# subclasses must also implement some methods in their singleton classes
|
69
|
-
# (actions_matching, index and clear)
|
70
|
-
class Base
|
71
|
-
attr_reader :id, :expiry, :send_response
|
72
|
-
|
73
|
-
def initialize(id, opts)
|
74
|
-
@id = id
|
75
|
-
duration = opts[:duration]
|
76
|
-
@expiry = Time.new + duration unless duration.nil?
|
77
|
-
@send_response = if opts[:send_response].nil?
|
78
|
-
true
|
79
|
-
else
|
80
|
-
!!opts[:send_response]
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
# See Sqreen::CB for return values
|
85
|
-
def run(*args)
|
86
|
-
return if expiry && Time.new > expiry
|
87
|
-
ret = do_run *args
|
88
|
-
unless ret.nil? || !@send_response
|
89
|
-
Sqreen.internal_track(event_name,
|
90
|
-
'properties' => {
|
91
|
-
'output' => event_properties(*args),
|
92
|
-
'action_id' => id,
|
93
|
-
})
|
94
|
-
end
|
95
|
-
ret
|
96
|
-
end
|
97
|
-
|
98
|
-
protected
|
99
|
-
|
100
|
-
def do_run(*_args)
|
101
|
-
raise ::Sqreen::NotImplementedYet, "do_run not implemented in #{self.class}"
|
102
|
-
# implement in subclasses
|
103
|
-
end
|
104
|
-
|
105
|
-
def event_properties(*_run_args)
|
106
|
-
raise ::Sqreen::NotImplementedYet, "event_properties not implemented in #{self.class}"
|
107
|
-
# implement in subclasses
|
108
|
-
end
|
109
|
-
|
110
|
-
private
|
111
|
-
|
112
|
-
def event_name
|
113
|
-
"sq.action.#{self.class.type_name}"
|
114
|
-
end
|
115
|
-
|
116
|
-
@@subclasses = {}
|
117
|
-
class << self
|
118
|
-
private :new
|
119
|
-
|
120
|
-
attr_reader :type_name
|
121
|
-
|
122
|
-
def get_type_class(name)
|
123
|
-
@@subclasses[name]
|
124
|
-
end
|
125
|
-
|
126
|
-
def known_subclasses
|
127
|
-
@@subclasses.values
|
128
|
-
end
|
129
|
-
|
130
|
-
def known_types
|
131
|
-
@@subclasses.keys
|
132
|
-
end
|
133
|
-
|
134
|
-
# all actions matching, possibly already expired
|
135
|
-
def actions_matching(_key)
|
136
|
-
raise 'implement in singletons of subclasses'
|
137
|
-
end
|
138
|
-
|
139
|
-
def index(_params, _action)
|
140
|
-
raise 'implement in singletons of subclasses'
|
141
|
-
end
|
142
|
-
|
143
|
-
def clear
|
144
|
-
raise 'implement in singletons of subclasses'
|
145
|
-
end
|
146
|
-
|
147
|
-
def inherited(subclass)
|
148
|
-
class << subclass
|
149
|
-
public :new
|
150
|
-
end
|
151
|
-
end
|
152
|
-
|
153
|
-
protected
|
154
|
-
|
155
|
-
def type_name=(name)
|
156
|
-
@type_name = name
|
157
|
-
@@subclasses[name] = self
|
158
|
-
end
|
159
|
-
end
|
160
|
-
end
|
161
|
-
|
162
|
-
module IpRangesIndex
|
163
|
-
def add_prefix(prefix_str, data)
|
164
|
-
@trie_v4 ||= Sqreen::Trie.new
|
165
|
-
@trie_v6 ||= Sqreen::Trie.new(nil, nil, Socket::AF_INET6)
|
166
|
-
prefix = Sqreen::Prefix.from_str(prefix_str, data)
|
167
|
-
trie = prefix.family == Socket::AF_INET6 ? @trie_v6 : @trie_v4
|
168
|
-
trie.insert prefix
|
169
|
-
end
|
170
|
-
|
171
|
-
def matching_actions(client_ip)
|
172
|
-
parsed_ip = IPAddr.new(client_ip.gsub(/%[^%\/]+/, ''))
|
173
|
-
trie = parsed_ip.family == Socket::AF_INET6 ? @trie_v6 : @trie_v4
|
174
|
-
return [] unless trie
|
175
|
-
found = trie.search_matching(parsed_ip.to_i, parsed_ip.family)
|
176
|
-
return [] unless found.size > 0
|
177
|
-
|
178
|
-
Sqreen.log.debug("Client ip #{client_ip} matches #{found.inspect}")
|
179
|
-
found.map(&:data)
|
180
|
-
end
|
181
|
-
|
182
|
-
def clear
|
183
|
-
@trie_v4 = Sqreen::Trie.new
|
184
|
-
@trie_v6 = Sqreen::Trie.new(nil, nil, Socket::AF_INET6)
|
185
|
-
end
|
186
|
-
end
|
187
|
-
|
188
|
-
module IpRangeIndexedActionClass
|
189
|
-
include IpRangesIndex
|
190
|
-
|
191
|
-
def actions_matching(client_ip)
|
192
|
-
matching_actions client_ip
|
193
|
-
end
|
194
|
-
|
195
|
-
def index(params, action)
|
196
|
-
ranges = parse_ip_ranges params
|
197
|
-
|
198
|
-
ranges.each do |r|
|
199
|
-
add_prefix r, action
|
200
|
-
end
|
201
|
-
end
|
202
|
-
|
203
|
-
private
|
204
|
-
|
205
|
-
# returns array of prefixes in string form
|
206
|
-
def parse_ip_ranges(params)
|
207
|
-
ranges = params['ip_cidr']
|
208
|
-
unless ranges && ranges.is_a?(Array) && !ranges.empty?
|
209
|
-
raise 'no non-empty ip_cidr array present'
|
210
|
-
end
|
211
|
-
|
212
|
-
ranges
|
213
|
-
end
|
214
|
-
end
|
215
|
-
|
216
|
-
# Block a list of IP address ranges. Standard "raise" behavior.
|
217
|
-
class BlockIp < Base
|
218
|
-
extend IpRangeIndexedActionClass
|
219
|
-
|
220
|
-
self.type_name = 'block_ip'
|
221
|
-
|
222
|
-
def initialize(id, opts, params = {})
|
223
|
-
# no need to store the ranges for this action, the index filter the class
|
224
|
-
super(id, opts)
|
225
|
-
end
|
226
|
-
|
227
|
-
def do_run(client_ip)
|
228
|
-
e = Sqreen::AttackBlocked.new("Blocked client's IP #{client_ip} " \
|
229
|
-
"(action: #{id}). No action is required")
|
230
|
-
{ :status => :raise, :exception => e, :skip_rem_cbs => true }
|
231
|
-
end
|
232
|
-
|
233
|
-
def event_properties(client_ip)
|
234
|
-
{ 'ip_address' => client_ip }
|
235
|
-
end
|
236
|
-
end
|
237
|
-
|
238
|
-
# Block a list of IP address ranges by forcefully redirecting the user
|
239
|
-
# to a specific URL.
|
240
|
-
class RedirectIp < Base
|
241
|
-
extend IpRangeIndexedActionClass
|
242
|
-
|
243
|
-
self.type_name = 'redirect_ip'
|
244
|
-
|
245
|
-
attr_reader :redirect_url
|
246
|
-
|
247
|
-
def initialize(id, opts, params = {})
|
248
|
-
super(id, opts)
|
249
|
-
@redirect_url = params['url']
|
250
|
-
raise "no url provided for action #{id}" unless @redirect_url
|
251
|
-
end
|
252
|
-
|
253
|
-
def do_run(client_ip)
|
254
|
-
Sqreen.log.info "Will request redirect for client with IP #{client_ip} " \
|
255
|
-
"(action: #{id})."
|
256
|
-
{
|
257
|
-
:status => :skip,
|
258
|
-
:new_return_value => [303, { 'Location' => @redirect_url }, ['']],
|
259
|
-
:skip_rem_cbs => true,
|
260
|
-
}
|
261
|
-
end
|
262
|
-
|
263
|
-
def event_properties(client_ip)
|
264
|
-
{ 'ip_address' => client_ip, 'url' => @redirect_url }
|
265
|
-
end
|
266
|
-
end
|
267
|
-
|
268
|
-
module UserActionClass
|
269
|
-
def actions_matching(identity_params)
|
270
|
-
return [] unless @idx
|
271
|
-
key = stringify_keys(identity_params)
|
272
|
-
actions = @idx[key]
|
273
|
-
actions || []
|
274
|
-
end
|
275
|
-
|
276
|
-
def index(params, action)
|
277
|
-
@idx ||= {}
|
278
|
-
users = params['users']
|
279
|
-
raise ::Sqreen::Exception, 'nil "users" param for block_user action' if users.nil?
|
280
|
-
raise ::Sqreen::Exception, '"users" param must be an array' unless users.is_a? Array
|
281
|
-
|
282
|
-
users.each do |u|
|
283
|
-
@idx[u] ||= []
|
284
|
-
@idx[u] << action
|
285
|
-
end
|
286
|
-
end
|
287
|
-
|
288
|
-
def clear
|
289
|
-
@idx = {}
|
290
|
-
end
|
291
|
-
|
292
|
-
private
|
293
|
-
|
294
|
-
def stringify_keys(hash)
|
295
|
-
Hash[
|
296
|
-
hash.map { |k, v| [k.to_s, v] }
|
297
|
-
]
|
298
|
-
end
|
299
|
-
end
|
300
|
-
|
301
|
-
# Blocks a user at the point Sqreen::identify()
|
302
|
-
# or Sqreen::auth_track() are called
|
303
|
-
class BlockUser < Base
|
304
|
-
extend UserActionClass
|
305
|
-
|
306
|
-
self.type_name = 'block_user'
|
307
|
-
|
308
|
-
def initialize(id, opts, params = {})
|
309
|
-
super(id, opts)
|
310
|
-
end
|
311
|
-
|
312
|
-
def do_run(identity_params)
|
313
|
-
Sqreen.log.info(
|
314
|
-
"Will raise due to user being blocked by action #{id}. " \
|
315
|
-
"Blocked user identity: #{identity_params}"
|
316
|
-
)
|
317
|
-
|
318
|
-
e = Sqreen::AttackBlocked.new(
|
319
|
-
"Blocked user with identity #{identity_params} " \
|
320
|
-
'due to automatic security response. No action is required'
|
321
|
-
)
|
322
|
-
|
323
|
-
{
|
324
|
-
:status => :raise,
|
325
|
-
:exception => e,
|
326
|
-
}
|
327
|
-
end
|
328
|
-
|
329
|
-
def event_properties(identity_params)
|
330
|
-
{ 'user' => identity_params }
|
331
|
-
end
|
332
|
-
end
|
333
|
-
|
334
|
-
# Redirects a user at the point Sqreen::identify()
|
335
|
-
# or Sqreen::auth_track() are called
|
336
|
-
class RedirectUser < Base
|
337
|
-
extend UserActionClass
|
338
|
-
|
339
|
-
self.type_name = 'redirect_user'
|
340
|
-
|
341
|
-
def initialize(id, opts, params = {})
|
342
|
-
super(id, opts)
|
343
|
-
@redirect_url = params['url']
|
344
|
-
raise "no url provided for action #{id}" unless @redirect_url
|
345
|
-
end
|
346
|
-
|
347
|
-
def do_run(identity_params)
|
348
|
-
Sqreen.log.info 'Will request redirect for user with identity ' \
|
349
|
-
"#{identity_params} (action: #{id})."
|
350
|
-
|
351
|
-
e = Sqreen::AttackBlocked.new(
|
352
|
-
"Redirected user with identity #{identity_params} " \
|
353
|
-
'due to automatic security response. No action is required'
|
354
|
-
)
|
355
|
-
e.redirect_url = @redirect_url
|
356
|
-
|
357
|
-
{
|
358
|
-
:status => :raise,
|
359
|
-
:exception => e,
|
360
|
-
}
|
361
|
-
end
|
362
|
-
|
363
|
-
def event_properties(identity_params)
|
364
|
-
{ 'user' => identity_params }
|
365
|
-
end
|
366
|
-
end
|
367
41
|
end
|
368
42
|
end
|
@@ -0,0 +1,110 @@
|
|
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: remove class vars
|
5
|
+
|
6
|
+
require 'sqreen/exception'
|
7
|
+
|
8
|
+
module Sqreen
|
9
|
+
# Implements actions (behavior taken in response to agent signals)
|
10
|
+
module Actions
|
11
|
+
# Base class for actions
|
12
|
+
# subclasses must also implement some methods in their singleton classes
|
13
|
+
# (actions_matching, index and clear)
|
14
|
+
class Base
|
15
|
+
attr_reader :id, :expiry, :send_response
|
16
|
+
|
17
|
+
def initialize(id, opts)
|
18
|
+
@id = id
|
19
|
+
duration = opts[:duration]
|
20
|
+
@expiry = Time.new + duration unless duration.nil?
|
21
|
+
@send_response = if opts[:send_response].nil?
|
22
|
+
true
|
23
|
+
else
|
24
|
+
opts[:send_response] ? true : false
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# See Sqreen::CB for return values
|
29
|
+
def run(*args)
|
30
|
+
return if expiry && Time.new > expiry
|
31
|
+
ret = do_run(*args)
|
32
|
+
unless ret.nil? || !@send_response
|
33
|
+
Sqreen.internal_track(event_name,
|
34
|
+
'properties' => {
|
35
|
+
'output' => event_properties(*args),
|
36
|
+
'action_id' => id,
|
37
|
+
})
|
38
|
+
end
|
39
|
+
ret
|
40
|
+
end
|
41
|
+
|
42
|
+
protected
|
43
|
+
|
44
|
+
def do_run(*_args)
|
45
|
+
raise ::Sqreen::NotImplementedYet, "do_run not implemented in #{self.class}"
|
46
|
+
# implement in subclasses
|
47
|
+
end
|
48
|
+
|
49
|
+
def event_properties(*_run_args)
|
50
|
+
raise ::Sqreen::NotImplementedYet, "event_properties not implemented in #{self.class}"
|
51
|
+
# implement in subclasses
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def event_name
|
57
|
+
"sq.action.#{self.class.type_name}"
|
58
|
+
end
|
59
|
+
|
60
|
+
@@subclasses = {} # rubocop:disable Style/ClassVars
|
61
|
+
class << self
|
62
|
+
private :new
|
63
|
+
|
64
|
+
attr_reader :type_name
|
65
|
+
|
66
|
+
def get_type_class(name)
|
67
|
+
subclasses[name]
|
68
|
+
end
|
69
|
+
|
70
|
+
def known_subclasses
|
71
|
+
subclasses.values
|
72
|
+
end
|
73
|
+
|
74
|
+
def known_types
|
75
|
+
subclasses.keys
|
76
|
+
end
|
77
|
+
|
78
|
+
# all actions matching, possibly already expired
|
79
|
+
def actions_matching(_key)
|
80
|
+
raise 'implement in singletons of subclasses'
|
81
|
+
end
|
82
|
+
|
83
|
+
def index(_params, _action)
|
84
|
+
raise 'implement in singletons of subclasses'
|
85
|
+
end
|
86
|
+
|
87
|
+
def clear
|
88
|
+
raise 'implement in singletons of subclasses'
|
89
|
+
end
|
90
|
+
|
91
|
+
def inherited(subclass)
|
92
|
+
class << subclass
|
93
|
+
public :new
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
protected
|
98
|
+
|
99
|
+
def subclasses
|
100
|
+
@@subclasses
|
101
|
+
end
|
102
|
+
|
103
|
+
def type_name=(name)
|
104
|
+
@type_name = name
|
105
|
+
subclasses[name] = self
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|