sqreen 1.20.0 → 1.20.4
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 +29 -0
- data/lib/sqreen/actions/block_user.rb +1 -1
- data/lib/sqreen/actions/redirect_ip.rb +1 -1
- data/lib/sqreen/actions/redirect_user.rb +1 -1
- data/lib/sqreen/agent_message.rb +20 -0
- data/lib/sqreen/attack_detected.html +1 -2
- data/lib/sqreen/ca.crt +24 -0
- data/lib/sqreen/condition_evaluator.rb +8 -2
- data/lib/sqreen/configuration.rb +5 -3
- data/lib/sqreen/deferred_logger.rb +50 -14
- data/lib/sqreen/deprecation.rb +38 -0
- data/lib/sqreen/endpoint_testing.rb +184 -0
- data/lib/sqreen/events/request_record.rb +0 -1
- data/lib/sqreen/frameworks/generic.rb +9 -0
- data/lib/sqreen/frameworks/rails.rb +0 -7
- data/lib/sqreen/frameworks/request_recorder.rb +2 -0
- data/lib/sqreen/graft/call.rb +76 -18
- data/lib/sqreen/graft/callback.rb +1 -1
- data/lib/sqreen/graft/hook.rb +187 -85
- data/lib/sqreen/graft/hook_point.rb +1 -1
- data/lib/sqreen/legacy/instrumentation.rb +22 -10
- data/lib/sqreen/legacy/old_event_submission_strategy.rb +2 -1
- data/lib/sqreen/log.rb +3 -2
- data/lib/sqreen/log/loggable.rb +2 -1
- data/lib/sqreen/logger.rb +24 -0
- data/lib/sqreen/metrics_store.rb +11 -0
- data/lib/sqreen/null_logger.rb +22 -0
- data/lib/sqreen/remote_command.rb +1 -0
- data/lib/sqreen/rules.rb +8 -4
- data/lib/sqreen/rules/blacklist_ips_cb.rb +2 -2
- data/lib/sqreen/rules/custom_error_cb.rb +3 -3
- data/lib/sqreen/rules/rule_cb.rb +2 -0
- data/lib/sqreen/rules/waf_cb.rb +3 -3
- data/lib/sqreen/runner.rb +64 -9
- data/lib/sqreen/session.rb +17 -11
- data/lib/sqreen/version.rb +1 -1
- data/lib/sqreen/weave/budget.rb +46 -0
- data/lib/sqreen/weave/legacy/instrumentation.rb +194 -103
- data/lib/sqreen/worker.rb +6 -2
- metadata +9 -7
- data/lib/sqreen/encoding_sanitizer.rb +0 -27
data/lib/sqreen/session.rb
CHANGED
@@ -50,7 +50,7 @@ module Sqreen
|
|
50
50
|
|
51
51
|
attr_accessor :request_compression
|
52
52
|
|
53
|
-
def initialize(server_url, token, app_name = nil, proxy_url = nil)
|
53
|
+
def initialize(server_url, cert_store, token, app_name = nil, proxy_url = nil)
|
54
54
|
@token = token
|
55
55
|
@app_name = app_name
|
56
56
|
@session_id = nil
|
@@ -73,12 +73,7 @@ module Sqreen
|
|
73
73
|
@http = Net::HTTP.new(uri.host, uri.port, *proxy_params)
|
74
74
|
@http.use_ssl = use_ssl
|
75
75
|
@http.verify_mode = OpenSSL::SSL::VERIFY_NONE if ENV['SQREEN_SSL_NO_VERIFY'] # for testing
|
76
|
-
if use_ssl
|
77
|
-
cert_file = File.join(File.dirname(__FILE__), 'ca.crt')
|
78
|
-
cert_store = OpenSSL::X509::Store.new
|
79
|
-
cert_store.add_file cert_file
|
80
|
-
@http.cert_store = cert_store
|
81
|
-
end
|
76
|
+
@http.cert_store = cert_store if use_ssl
|
82
77
|
self.use_signals = false
|
83
78
|
end
|
84
79
|
|
@@ -240,10 +235,7 @@ module Sqreen
|
|
240
235
|
end
|
241
236
|
|
242
237
|
def login(framework)
|
243
|
-
headers =
|
244
|
-
'x-api-key' => @token,
|
245
|
-
'x-app-name' => @app_name || framework.application_name,
|
246
|
-
}.reject { |k, v| v == nil }
|
238
|
+
headers = prelogin_auth_headers(framework)
|
247
239
|
|
248
240
|
Sqreen.log.warn "Using app name: #{headers['x-app-name']}"
|
249
241
|
|
@@ -312,6 +304,11 @@ module Sqreen
|
|
312
304
|
@evt_sub_strategy.post_batch(events)
|
313
305
|
end
|
314
306
|
|
307
|
+
def post_agent_message(framework, agent_message)
|
308
|
+
headers = prelogin_auth_headers(framework)
|
309
|
+
post('app_agent_message', agent_message.to_h, headers, 0)
|
310
|
+
end
|
311
|
+
|
315
312
|
# Perform agent logout
|
316
313
|
# @param retrying [Boolean] whether to try again on error
|
317
314
|
def logout(retrying = true)
|
@@ -325,5 +322,14 @@ module Sqreen
|
|
325
322
|
Sqreen.logged_in = false
|
326
323
|
disconnect
|
327
324
|
end
|
325
|
+
|
326
|
+
private
|
327
|
+
|
328
|
+
def prelogin_auth_headers(framework)
|
329
|
+
{
|
330
|
+
'x-api-key' => @token,
|
331
|
+
'x-app-name' => @app_name || framework.application_name,
|
332
|
+
}.reject { |_k, v| v == nil }
|
333
|
+
end
|
328
334
|
end
|
329
335
|
end
|
data/lib/sqreen/version.rb
CHANGED
@@ -0,0 +1,46 @@
|
|
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
|
+
require 'sqreen/log/loggable'
|
7
|
+
require 'sqreen/weave'
|
8
|
+
|
9
|
+
class Sqreen::Weave::Budget
|
10
|
+
include Sqreen::Log::Loggable
|
11
|
+
|
12
|
+
def initialize(threshold, ratio = nil)
|
13
|
+
@threshold = threshold
|
14
|
+
@ratio = ratio
|
15
|
+
end
|
16
|
+
|
17
|
+
def static?
|
18
|
+
threshold && !ratio
|
19
|
+
end
|
20
|
+
|
21
|
+
def dynamic?
|
22
|
+
threshold && ratio
|
23
|
+
end
|
24
|
+
|
25
|
+
attr_reader :threshold
|
26
|
+
attr_reader :ratio
|
27
|
+
|
28
|
+
def to_h
|
29
|
+
{ threshold: threshold, ratio: ratio }
|
30
|
+
end
|
31
|
+
|
32
|
+
class << self
|
33
|
+
attr_reader :current
|
34
|
+
|
35
|
+
def update(opts = nil)
|
36
|
+
Sqreen::Weave.logger.info("budget update:#{opts.inspect}")
|
37
|
+
|
38
|
+
return @current = nil if opts.nil? || opts.empty?
|
39
|
+
|
40
|
+
threshold = opts[:threshold]
|
41
|
+
ratio = opts[:ratio]
|
42
|
+
|
43
|
+
@current = new(threshold, ratio)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -4,10 +4,13 @@
|
|
4
4
|
# Please refer to our terms for more information: https://www.sqreen.com/terms.html
|
5
5
|
|
6
6
|
require 'sqreen/weave/legacy'
|
7
|
+
require 'sqreen/weave/budget'
|
8
|
+
require 'sqreen/graft/hook'
|
7
9
|
require 'sqreen/graft/hook_point'
|
8
10
|
require 'sqreen/call_countable'
|
9
11
|
require 'sqreen/rules'
|
10
12
|
require 'sqreen/rules/record_request_context'
|
13
|
+
require 'sqreen/sqreen_signed_verifier'
|
11
14
|
|
12
15
|
class Sqreen::Weave::Legacy::Instrumentation
|
13
16
|
attr_accessor :metrics_engine
|
@@ -60,6 +63,27 @@ class Sqreen::Weave::Legacy::Instrumentation
|
|
60
63
|
'options' => opts[:perf_metric_percent] || { 'base' => 1.3, 'factor' => 1.0 },
|
61
64
|
)
|
62
65
|
|
66
|
+
metrics_engine.create_metric(
|
67
|
+
'name' => 'req.sq.hook.overhead',
|
68
|
+
'period' => 60,
|
69
|
+
'kind' => 'Binning',
|
70
|
+
'options' => { 'base' => 2.0, 'factor' => 0.1 },
|
71
|
+
)
|
72
|
+
|
73
|
+
metrics_engine.create_metric(
|
74
|
+
'name' => 'sq.hook.overhead',
|
75
|
+
'period' => 60,
|
76
|
+
'kind' => 'Binning',
|
77
|
+
'options' => { 'base' => 2.0, 'factor' => 0.1 },
|
78
|
+
)
|
79
|
+
|
80
|
+
metrics_engine.create_metric(
|
81
|
+
'name' => 'sq.shrinkwrap',
|
82
|
+
'period' => 60,
|
83
|
+
'kind' => 'Binning',
|
84
|
+
'options' => { 'base' => 2.0, 'factor' => 0.1 },
|
85
|
+
)
|
86
|
+
|
63
87
|
Sqreen.thread_cpu_time? && metrics_engine.create_metric(
|
64
88
|
'name' => 'sq_thread_cpu_pct',
|
65
89
|
'period' => opts[:period] || 60,
|
@@ -84,6 +108,15 @@ class Sqreen::Weave::Legacy::Instrumentation
|
|
84
108
|
|
85
109
|
### set up rule signature verifier
|
86
110
|
verifier = nil
|
111
|
+
if Sqreen.features['rules_signature'] &&
|
112
|
+
Sqreen.config_get(:rules_verify_signature) == true &&
|
113
|
+
!defined?(::JRUBY_VERSION)
|
114
|
+
verifier = Sqreen::SqreenSignedVerifier.new
|
115
|
+
Sqreen::Weave.logger.debug('Rules signature enabled')
|
116
|
+
else
|
117
|
+
Sqreen::Weave.logger.debug('Rules signature disabled')
|
118
|
+
end
|
119
|
+
|
87
120
|
### force clean instrumentation callback list
|
88
121
|
@hooks = []
|
89
122
|
### for each rule description
|
@@ -94,6 +127,25 @@ class Sqreen::Weave::Legacy::Instrumentation
|
|
94
127
|
next unless rule_callback
|
95
128
|
### attach framework to callback
|
96
129
|
rule_callback.framework = framework
|
130
|
+
## create metric
|
131
|
+
Sqreen::Weave.logger.debug { "Adding rule metric: #{rule_callback}" }
|
132
|
+
[:pre, :post, :failing].each do |whence|
|
133
|
+
next unless rule_callback.send(:"#{whence}?")
|
134
|
+
metric_name = "sq.#{rule['name']}.#{whence}"
|
135
|
+
metrics_engine.create_metric(
|
136
|
+
'name' => metric_name,
|
137
|
+
'period' => 60,
|
138
|
+
'kind' => 'Binning',
|
139
|
+
'options' => { 'base' => 2.0, 'factor' => 0.1 },
|
140
|
+
)
|
141
|
+
metric_name = "req.sq.#{rule['name']}.#{whence}"
|
142
|
+
metrics_engine.create_metric(
|
143
|
+
'name' => metric_name,
|
144
|
+
'period' => 60,
|
145
|
+
'kind' => 'Binning',
|
146
|
+
'options' => { 'base' => 2.0, 'factor' => 0.1 },
|
147
|
+
)
|
148
|
+
end
|
97
149
|
### install callback, observing priority
|
98
150
|
Sqreen::Weave.logger.debug { "Adding rule callback: #{rule_callback}" }
|
99
151
|
@hooks << add_callback("weave,rule=#{rule['name']}", rule_callback, strategy)
|
@@ -107,30 +159,43 @@ class Sqreen::Weave::Legacy::Instrumentation
|
|
107
159
|
end
|
108
160
|
|
109
161
|
metrics_engine = self.metrics_engine
|
162
|
+
|
110
163
|
request_hook = Sqreen::Graft::Hook['Sqreen::ShrinkWrap#call', strategy]
|
111
164
|
@hooks << request_hook
|
112
165
|
request_hook.add do
|
113
166
|
before('wave,meta,request', rank: -100000, mandatory: true) do |_call|
|
114
167
|
next unless Sqreen.instrumentation_ready
|
115
168
|
|
116
|
-
|
117
|
-
|
169
|
+
# shrinkwrap_timer = Sqreen::Graft::Timer.new('weave,shrinkwrap')
|
170
|
+
# shrinkwrap_timer.start
|
171
|
+
|
172
|
+
request_timer = Sqreen::Graft::Timer.new("request")
|
173
|
+
request_timer.start
|
174
|
+
sqreen_timer = Sqreen::Graft::Timer.new("sqreen")
|
175
|
+
budget = Sqreen::Weave::Budget.current
|
176
|
+
request_budget_threshold = budget.threshold if budget
|
177
|
+
request_budget_ratio = budget.ratio if budget
|
178
|
+
request_budget_is_dynamic = !request_budget_ratio.nil?
|
179
|
+
request_budget = !request_budget_threshold.nil?
|
180
|
+
timed_level = (Sqreen.features['perf_level'] || 1).to_i
|
181
|
+
Sqreen::Weave.logger.debug { "request budget: #{budget.to_h} timed.level: #{timed_level}" } if Sqreen::Weave.logger.debug?
|
182
|
+
|
118
183
|
Thread.current[:sqreen_http_request] = {
|
119
|
-
|
120
|
-
|
121
|
-
time_budget: Sqreen.performance_budget,
|
184
|
+
request_timer: request_timer,
|
185
|
+
sqreen_timer: sqreen_timer,
|
122
186
|
time_budget_expended: false,
|
123
|
-
|
187
|
+
time_budget_threshold: request_budget_threshold,
|
188
|
+
time_budget_dynamic: request_budget_is_dynamic,
|
189
|
+
time_budget_ratio: request_budget_ratio,
|
190
|
+
time_budget: request_budget,
|
124
191
|
timed_callbacks: [],
|
125
192
|
timed_hooks: [],
|
126
|
-
|
127
|
-
timed_hooks_after: [],
|
128
|
-
timed_hooks_raised: [],
|
129
|
-
timed_hooks_ensured: [],
|
193
|
+
timed_level: timed_level,
|
130
194
|
skipped_callbacks: [],
|
195
|
+
# timed_shrinkwrap: shrinkwrap_timer,
|
131
196
|
}
|
132
197
|
|
133
|
-
|
198
|
+
# shrinkwrap_timer.stop
|
134
199
|
end
|
135
200
|
|
136
201
|
ensured('weave,meta,request', rank: 100000, mandatory: true) do |_call|
|
@@ -138,105 +203,118 @@ class Sqreen::Weave::Legacy::Instrumentation
|
|
138
203
|
|
139
204
|
next if request.nil?
|
140
205
|
|
206
|
+
# shrinkwrap_timer = request[:timed_shrinkwrap]
|
207
|
+
# shrinkwrap_timer.start
|
208
|
+
|
141
209
|
Thread.current[:sqreen_http_request] = nil
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
request[:
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
metrics_engine.
|
161
|
-
|
162
|
-
'period' => 60,
|
163
|
-
'kind' => 'Binning',
|
164
|
-
'options' => { 'base' => 2.0, 'factor' => 0.1 },
|
165
|
-
)
|
210
|
+
request_timer = request[:request_timer]
|
211
|
+
now = request_timer.stop
|
212
|
+
|
213
|
+
if request[:timed_level] >= 1
|
214
|
+
request[:timed_callbacks].each do |timer|
|
215
|
+
duration = timer.duration
|
216
|
+
|
217
|
+
timer.tag =~ /weave,rule=(.*)$/ && rule = $1
|
218
|
+
next unless rule
|
219
|
+
|
220
|
+
whence = case timer.tag
|
221
|
+
when /@before/ then 'pre'
|
222
|
+
when /@after/ then 'post'
|
223
|
+
when /@raised/ then 'failing'
|
224
|
+
end
|
225
|
+
next unless whence
|
226
|
+
|
227
|
+
metric_name = "sq.#{rule}.#{whence}"
|
228
|
+
metrics_engine.update(metric_name, now, nil, duration * 1000)
|
229
|
+
# Sqreen.observations_queue.push([metric_name, nil, duration * 1000, utc_now])
|
166
230
|
end
|
167
|
-
metrics_engine.update(metric_name, now, nil, duration * 1000)
|
168
|
-
end
|
169
231
|
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
'period' => 60,
|
176
|
-
'kind' => 'Binning',
|
177
|
-
'options' => { 'base' => 2.0, 'factor' => 0.1 },
|
178
|
-
)
|
179
|
-
end
|
180
|
-
metrics_engine.update(metric_name, now, nil, duration * 1000)
|
181
|
-
|
182
|
-
metric_name = 'sq.hooks_post.post'
|
183
|
-
duration = request[:timed_hooks_after].sum(&:duration)
|
184
|
-
unless metrics_engine.metric?(metric_name)
|
185
|
-
metrics_engine.create_metric(
|
186
|
-
'name' => metric_name,
|
187
|
-
'period' => 60,
|
188
|
-
'kind' => 'Binning',
|
189
|
-
'options' => { 'base' => 2.0, 'factor' => 0.1 },
|
190
|
-
)
|
191
|
-
end
|
192
|
-
metrics_engine.update(metric_name, now, nil, duration * 1000)
|
193
|
-
|
194
|
-
metric_name = 'sq.hooks_failing.failing'
|
195
|
-
duration = request[:timed_hooks_raised].sum(&:duration)
|
196
|
-
unless metrics_engine.metric?(metric_name)
|
197
|
-
metrics_engine.create_metric(
|
198
|
-
'name' => metric_name,
|
199
|
-
'period' => 60,
|
200
|
-
'kind' => 'Binning',
|
201
|
-
'options' => { 'base' => 2.0, 'factor' => 0.1 },
|
202
|
-
)
|
232
|
+
request[:timed_hooks].each do |timer|
|
233
|
+
duration = timer.duration
|
234
|
+
metrics_engine.update('sq.hook.overhead', now, nil, duration * 1000)
|
235
|
+
# Sqreen.observations_queue.push(['sq.hook.overhead', nil, duration * 1000, utc_now])
|
236
|
+
end
|
203
237
|
end
|
204
|
-
metrics_engine.update(metric_name, now, nil, duration * 1000)
|
205
238
|
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
total =
|
210
|
-
Sqreen::Weave.logger.debug { "request
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
239
|
+
sqreen_timer = request[:sqreen_timer]
|
240
|
+
total = sqreen_timer.duration
|
241
|
+
Sqreen::Weave.logger.debug { "request sqreen_timer.total: #{'%.03fus' % (total * 1_000_000)}" } if Sqreen::Weave.logger.debug?
|
242
|
+
total = request_timer.duration
|
243
|
+
Sqreen::Weave.logger.debug { "request request_timer.total: #{'%.03fus' % (total * 1_000_000)}" } if Sqreen::Weave.logger.debug?
|
244
|
+
|
245
|
+
if request[:timed_level] >= 2
|
246
|
+
skipped = request[:skipped_callbacks].map(&:name)
|
247
|
+
Sqreen::Weave.logger.debug { "request callback.skipped.count: #{skipped.count}" } if Sqreen::Weave.logger.debug?
|
248
|
+
timings = request[:timed_callbacks].map(&:to_s)
|
249
|
+
total = request[:timed_callbacks].sum(&:duration)
|
250
|
+
Sqreen::Weave.logger.debug { "request callback.total: #{'%.03fus' % (total * 1_000_000)} callback.count: #{timings.count}" } if Sqreen::Weave.logger.debug?
|
251
|
+
timings = request[:timed_hooks].map(&:to_s)
|
252
|
+
total = request[:timed_hooks].sum(&:duration)
|
253
|
+
Sqreen::Weave.logger.debug { "request hook.total: #{'%.03fus' % (total * 1_000_000)} hook.count: #{timings.count}" } if Sqreen::Weave.logger.debug?
|
254
|
+
end
|
217
255
|
|
218
256
|
skipped = request[:skipped_callbacks].map(&:name)
|
219
257
|
skipped_rule_name = skipped.first && skipped.first =~ /weave,rule=(.*)$/ && $1
|
220
|
-
|
258
|
+
metrics_engine.update('request_overtime', now, skipped_rule_name, 1) if skipped_rule_name
|
259
|
+
# Sqreen.observations_queue.push(['request_overtime', skipped_rule_name, 1, utc_now]) if skipped_rule_name
|
221
260
|
|
222
|
-
sqreen_request_duration =
|
223
|
-
|
261
|
+
sqreen_request_duration = sqreen_timer.duration
|
262
|
+
metrics_engine.update('sq', now, nil, sqreen_request_duration * 1000)
|
263
|
+
# Sqreen.observations_queue.push(['sq', nil, sqreen_request_duration * 1000, utc_now])
|
224
264
|
|
225
|
-
request_duration =
|
226
|
-
|
265
|
+
request_duration = request_timer.duration
|
266
|
+
metrics_engine.update('req', now, nil, request_duration * 1000)
|
267
|
+
# Sqreen.observations_queue.push(['req', nil, request_duration * 1000, utc_now])
|
227
268
|
|
228
269
|
sqreen_request_ratio = (sqreen_request_duration * 100.0) / (request_duration - sqreen_request_duration)
|
229
|
-
|
270
|
+
metrics_engine.update('pct', now, nil, sqreen_request_ratio)
|
271
|
+
# Sqreen.observations_queue.push(['pct', nil, sqreen_request_ratio, utc_now])
|
272
|
+
Sqreen::Weave.logger.debug { "request sqreen_timer.ratio: #{'%.03f' % (sqreen_request_ratio / 100.0)}" } if Sqreen::Weave.logger.debug?
|
273
|
+
|
274
|
+
if request[:timed_level] >= 2
|
275
|
+
tallies = Hash.new(0.0)
|
276
|
+
request[:timed_callbacks].each do |timer|
|
277
|
+
duration = timer.duration
|
278
|
+
|
279
|
+
timer.tag =~ /weave,rule=(.*)$/ && rule = $1
|
280
|
+
next unless rule
|
281
|
+
|
282
|
+
whence = case timer.tag
|
283
|
+
when /@before/ then 'pre'
|
284
|
+
when /@after/ then 'post'
|
285
|
+
when /@raised/ then 'failing'
|
286
|
+
end
|
287
|
+
next unless whence
|
288
|
+
|
289
|
+
metric_name = "req.sq.#{rule}.#{whence}"
|
290
|
+
tallies[metric_name] += duration
|
291
|
+
end
|
292
|
+
tallies.each do |metric_name, duration|
|
293
|
+
metrics_engine.update(metric_name, now, nil, duration * 1000)
|
294
|
+
# Sqreen.observations_queue.push([metric_name, nil, duration * 1000, utc_now])
|
295
|
+
end
|
296
|
+
|
297
|
+
duration = request[:timed_hooks].sum(&:duration)
|
298
|
+
metrics_engine.update('req.sq.hook.overhead', now, nil, duration * 1000)
|
299
|
+
# Sqreen.observations_queue.push(['req.sq.hook.overhead', nil, duration * 1000, utc_now])
|
300
|
+
end
|
301
|
+
|
302
|
+
# shrinkwrap_timer.stop
|
303
|
+
|
304
|
+
# duration = shrinkwrap_timer.duration
|
305
|
+
# metrics_engine.update('sq.shrinkwrap', now, nil, duration * 1000)
|
230
306
|
end
|
231
307
|
end.install
|
232
308
|
|
233
309
|
### globally declare instrumentation ready
|
234
310
|
Sqreen.instrumentation_ready = true
|
311
|
+
Sqreen::Weave.logger.info { "Instrumentation activated" }
|
235
312
|
end
|
236
313
|
|
237
314
|
# needed by Sqreen::Runner
|
238
315
|
def remove_all_callbacks
|
239
316
|
Sqreen.instrumentation_ready = false
|
317
|
+
Sqreen::Weave.logger.info { "Instrumentation deactivated" }
|
240
318
|
|
241
319
|
loop do
|
242
320
|
hook = @hooks.pop
|
@@ -253,6 +331,15 @@ class Sqreen::Weave::Legacy::Instrumentation
|
|
253
331
|
klass = callback.klass
|
254
332
|
method = callback.method
|
255
333
|
|
334
|
+
if (call_count = ENV['SQREEN_DEBUG_CALL_COUNT'])
|
335
|
+
call_count = JSON.parse(call_count)
|
336
|
+
if callback.respond_to?(:rule_name) && call_count.key?(callback.rule_name)
|
337
|
+
count = call_count[callback.rule_name]
|
338
|
+
Sqreen::Weave.logger.debug { "override rule: #{callback.rule_name} call_count: #{count.inspect}" }
|
339
|
+
callback.instance_eval { @call_count_interval = call_count[callback.rule_name] }
|
340
|
+
end
|
341
|
+
end
|
342
|
+
|
256
343
|
if Sqreen::Graft::HookPoint.new("#{klass}.#{method}").exist?
|
257
344
|
hook_point = "#{klass}.#{method}"
|
258
345
|
elsif Sqreen::Graft::HookPoint.new("#{klass}##{method}").exist?
|
@@ -275,7 +362,6 @@ class Sqreen::Weave::Legacy::Instrumentation
|
|
275
362
|
a = call.args
|
276
363
|
r = call.remaining
|
277
364
|
|
278
|
-
Sqreen::Weave.logger.debug { "#{rule} klass=#{callback.klass} method=#{callback.method} when=#pre instance=#{i}" }
|
279
365
|
begin
|
280
366
|
ret = callback.pre(i, a, r)
|
281
367
|
rescue StandardError => e
|
@@ -286,17 +372,26 @@ class Sqreen::Weave::Legacy::Instrumentation
|
|
286
372
|
Sqreen::RemoteException.record(e)
|
287
373
|
end
|
288
374
|
end
|
289
|
-
Sqreen::Weave.logger.debug { "#{rule} klass=#{callback.klass} method=#{callback.method} when=#pre instance=#{i} => return=#{ret.inspect}" }
|
290
375
|
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
376
|
+
next if ret.nil? || !ret.is_a?(Hash)
|
377
|
+
|
378
|
+
throw_val =
|
379
|
+
case ret[:status]
|
380
|
+
when :skip, 'skip'
|
381
|
+
b.return(ret[:new_return_value]).break! if ret.key?(:new_return_value)
|
382
|
+
when :modify_args, 'modify_args'
|
383
|
+
b.args(ret[:args])
|
384
|
+
when :raise, 'raise'
|
385
|
+
if ret.key?(:exception)
|
386
|
+
b.raise(ret[:exception])
|
387
|
+
else
|
388
|
+
b.raise(Sqreen::AttackBlocked.new("Sqreen blocked a security threat (type: #{callback.rule_name}). No action is required."))
|
389
|
+
end
|
390
|
+
end
|
391
|
+
|
392
|
+
next unless throw_val
|
393
|
+
throw_val.break! if ret[:skip_rem_cbs]
|
394
|
+
throw(b, throw_val)
|
300
395
|
end
|
301
396
|
end
|
302
397
|
|
@@ -309,7 +404,6 @@ class Sqreen::Weave::Legacy::Instrumentation
|
|
309
404
|
a = call.args
|
310
405
|
r = call.remaining
|
311
406
|
|
312
|
-
Sqreen::Weave.logger.debug { "#{rule} klass=#{callback.klass} method=#{callback.method} when=#post instance=#{i}" }
|
313
407
|
begin
|
314
408
|
ret = callback.post(v, i, a, r)
|
315
409
|
rescue StandardError => e
|
@@ -320,7 +414,6 @@ class Sqreen::Weave::Legacy::Instrumentation
|
|
320
414
|
Sqreen::RemoteException.record(e)
|
321
415
|
end
|
322
416
|
end
|
323
|
-
Sqreen::Weave.logger.debug { "#{rule} klass=#{callback.klass} method=#{callback.method} when=#post instance=#{i} => return=#{ret.inspect}" }
|
324
417
|
|
325
418
|
case ret[:status]
|
326
419
|
when :override, 'override'
|
@@ -341,7 +434,6 @@ class Sqreen::Weave::Legacy::Instrumentation
|
|
341
434
|
a = call.args
|
342
435
|
r = call.remaining
|
343
436
|
|
344
|
-
Sqreen::Weave.logger.debug { "#{rule} klass=#{callback.klass} method=#{callback.method} when=#failing instance=#{i}" }
|
345
437
|
begin
|
346
438
|
ret = callback.failing(e, i, a, r)
|
347
439
|
rescue StandardError => e
|
@@ -352,7 +444,6 @@ class Sqreen::Weave::Legacy::Instrumentation
|
|
352
444
|
Sqreen::RemoteException.record(e)
|
353
445
|
end
|
354
446
|
end
|
355
|
-
Sqreen::Weave.logger.debug { "#{rule} klass=#{callback.klass} method=#{callback.method} when=#failing instance=#{i} => return=#{ret.inspect}" }
|
356
447
|
|
357
448
|
throw(b, b.raise(e)) if ret.nil? || !ret.is_a?(Hash)
|
358
449
|
|