sqreen 1.19.1 → 1.20.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +22 -0
  3. data/lib/sqreen/agent_message.rb +20 -0
  4. data/lib/sqreen/aggregated_metric.rb +25 -0
  5. data/lib/sqreen/attack_detected.html +1 -2
  6. data/lib/sqreen/ca.crt +24 -0
  7. data/lib/sqreen/configuration.rb +10 -4
  8. data/lib/sqreen/deferred_logger.rb +4 -0
  9. data/lib/sqreen/deliveries/batch.rb +4 -1
  10. data/lib/sqreen/deliveries/simple.rb +4 -0
  11. data/lib/sqreen/endpoint_testing.rb +184 -0
  12. data/lib/sqreen/event.rb +7 -5
  13. data/lib/sqreen/events/attack.rb +23 -18
  14. data/lib/sqreen/events/remote_exception.rb +0 -22
  15. data/lib/sqreen/events/request_record.rb +15 -70
  16. data/lib/sqreen/frameworks/request_recorder.rb +13 -2
  17. data/lib/sqreen/graft/call.rb +32 -19
  18. data/lib/sqreen/graft/callback.rb +1 -1
  19. data/lib/sqreen/graft/hook.rb +97 -116
  20. data/lib/sqreen/graft/hook_point.rb +1 -1
  21. data/lib/sqreen/kit/signals/specialized/aggregated_metric.rb +72 -0
  22. data/lib/sqreen/kit/signals/specialized/attack.rb +57 -0
  23. data/lib/sqreen/kit/signals/specialized/binning_metric.rb +76 -0
  24. data/lib/sqreen/kit/signals/specialized/http_trace.rb +26 -0
  25. data/lib/sqreen/kit/signals/specialized/sdk_track_call.rb +50 -0
  26. data/lib/sqreen/kit/signals/specialized/sqreen_exception.rb +57 -0
  27. data/lib/sqreen/legacy/instrumentation.rb +10 -10
  28. data/lib/sqreen/legacy/old_event_submission_strategy.rb +221 -0
  29. data/lib/sqreen/legacy/waf_redactions.rb +49 -0
  30. data/lib/sqreen/log/loggable.rb +2 -1
  31. data/lib/sqreen/logger.rb +4 -0
  32. data/lib/sqreen/metrics/base.rb +3 -0
  33. data/lib/sqreen/metrics_store.rb +22 -12
  34. data/lib/sqreen/performance_notifications/binned_metrics.rb +8 -2
  35. data/lib/sqreen/rules.rb +4 -2
  36. data/lib/sqreen/rules/not_found_cb.rb +2 -0
  37. data/lib/sqreen/rules/rule_cb.rb +2 -0
  38. data/lib/sqreen/rules/waf_cb.rb +13 -10
  39. data/lib/sqreen/runner.rb +75 -8
  40. data/lib/sqreen/sensitive_data_redactor.rb +19 -31
  41. data/lib/sqreen/session.rb +51 -43
  42. data/lib/sqreen/signals/conversions.rb +283 -0
  43. data/lib/sqreen/signals/http_trace_redaction.rb +111 -0
  44. data/lib/sqreen/signals/signals_submission_strategy.rb +78 -0
  45. data/lib/sqreen/version.rb +1 -1
  46. data/lib/sqreen/weave/legacy/instrumentation.rb +56 -53
  47. metadata +45 -7
  48. data/lib/sqreen/backport.rb +0 -9
  49. data/lib/sqreen/backport/clock_gettime.rb +0 -74
  50. data/lib/sqreen/backport/original_name.rb +0 -88
@@ -0,0 +1,111 @@
1
+ require 'json'
2
+ require 'sqreen/kit/loggable'
3
+ require 'sqreen/kit/signals/specialized/http_trace'
4
+
5
+ module Sqreen
6
+ module Signals
7
+ module HttpTraceRedaction
8
+ class << self
9
+ include Sqreen::Kit::Loggable
10
+
11
+ # @param [Sqreen::Kit::Signals::Specialized::HttpTrace] trace
12
+ # @param [Sqreen::SensitiveDataRedactor] redactor
13
+ def redact_trace!(trace, redactor)
14
+ return unless redactor
15
+ # redact headers (keys unsafe)
16
+ # @type [Sqreen::Kit::Signals::Context::HttpContext]
17
+ http_context = trace.context
18
+
19
+ all_redacted = []
20
+
21
+ # Redact headers; save redacted values
22
+ # headers are encoded as [key, value], not a hash, so
23
+ # they require some transformation
24
+ orig_headers = http_context.headers
25
+ if orig_headers
26
+ headers = orig_headers.map { |(k, v)| { k => v } }
27
+ headers, redacted = redactor.redact(headers)
28
+ http_context.headers = headers.map(&:first)
29
+ all_redacted += redacted
30
+ end
31
+
32
+ # Redact params; save redacted values
33
+ Kit::Signals::Context::HttpContext::PARAMS_ATTRS.each do |attr|
34
+ value = http_context.public_send(attr)
35
+ next unless value
36
+ value, redacted = redactor.redact(value)
37
+ all_redacted += redacted
38
+ http_context.public_send(:"#{attr}=", value)
39
+ end
40
+
41
+ all_redacted = all_redacted.uniq.map(&:downcase)
42
+
43
+ # Redact attacks and exceptions
44
+ # XXX: no redaction for infos in attacks/exceptions except for WAF data
45
+ # Is this the correct behavior?
46
+ redact_attacks!(trace, redactor, all_redacted)
47
+ redact_exceptions!(trace, redactor, all_redacted)
48
+ end
49
+
50
+ private
51
+
52
+ # @param [Sqreen::Kit::Signals::Specialized::HttpTrace] trace
53
+ # @param [Sqreen::SensitiveDataRedactor] redactor
54
+ # Redacts WAF data according to specific rules therefor
55
+ # Redacts infos according to general rules
56
+ def redact_attacks!(trace, redactor, redacted_data)
57
+ trace.data.each do |signal|
58
+ next unless signal.is_a?(Kit::Signals::Specialized::Attack)
59
+ # @type [Sqreen::Kit::Signals::Specialized::Attack::Payload] payload
60
+ payload = signal.payload
61
+ next unless payload.infos
62
+
63
+ if payload.infos[:waf_data]
64
+ redact_waf_attack_data!(payload.infos, redacted_data)
65
+ end
66
+ payload.infos, = redactor.redact(payload.infos)
67
+ end
68
+ end
69
+
70
+ def redact_exceptions!(trace, redactor, redacted_data)
71
+ trace.data.each do |signal|
72
+ next unless signal.is_a?(Kit::Signals::Specialized::SqreenException)
73
+ infos = signal.infos
74
+ next unless infos
75
+
76
+ redact_waf_exception_data!(signal.infos, redacted_data) if signal.infos[:waf]
77
+ signal.infos, = redactor.redact(infos)
78
+ end
79
+ end
80
+
81
+ # @param [Hash] infos from WAF attack
82
+ def redact_waf_attack_data!(infos, redacted_data)
83
+ begin
84
+ parsed = JSON.parse(infos[:waf_data])
85
+ rescue JSON::JSONError => e
86
+ logger.warn("waf_data is not valid json: #{e.message}")
87
+ return
88
+ end
89
+ redacted = parsed.each do |w|
90
+ next unless (filters = w['filter'])
91
+
92
+ filters.each do |f|
93
+ next unless (v = f['resolved_value'])
94
+ next unless redacted_data.include?(v.downcase)
95
+
96
+ f['match_status'] = SensitiveDataRedactor::MASK
97
+ f['resolved_value'] = SensitiveDataRedactor::MASK
98
+ end
99
+ end
100
+ infos[:waf_data] = JSON.dump(redacted)
101
+ end
102
+
103
+ # see https://github.com/sqreen/TechDoc/blob/master/content/specs/spec000022-waf-data-sanitization.md#changes-to-the-agents
104
+ def redact_waf_exception_data!(infos, redacted_data)
105
+ return if redacted_data.empty?
106
+ infos[:waf].delete(:args)
107
+ end
108
+ end
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,78 @@
1
+ require 'sqreen/aggregated_metric'
2
+ require 'sqreen/kit'
3
+ require 'sqreen/kit/string_sanitizer'
4
+ require 'sqreen/signals/conversions'
5
+ require 'sqreen/log/loggable'
6
+
7
+ module Sqreen
8
+ module Signals
9
+ # see also Sqreen::Legacy::OldEventSubmissionStrategy
10
+ # usage in Sqreen:Session
11
+ class SignalsSubmissionStrategy
12
+ include Sqreen::Log::Loggable
13
+
14
+ # @param [Array<Sqreen::AggregatedMetric>] metrics
15
+ def post_metrics(metrics)
16
+ return if metrics.nil? || metrics.empty?
17
+
18
+ guarded 'Failed to serialize or submit aggregated metrics' do
19
+ batch = metrics.map do |m|
20
+ Conversions.convert_metric_sample(m)
21
+ end
22
+ client.report_batch(batch)
23
+ end
24
+ end
25
+
26
+ # @param _attack [Sqreen::Attack]
27
+ # XXX: unused
28
+ def post_attack(_attack)
29
+ raise NotImplementedError
30
+ end
31
+
32
+ # @param request_record [Sqreen::RequestRecord]
33
+ def post_request_record(request_record)
34
+ guarded 'Failed to serialize or submit request record' do
35
+ trace = Conversions.convert_req_record(request_record)
36
+ append_sanitizing_filter(trace)
37
+ client.report_trace(trace)
38
+ end
39
+ end
40
+
41
+ # Post an exception to Sqreen for analysis
42
+ # @param exception [RemoteException] Exception and context to be sent over
43
+ def post_sqreen_exception(exception)
44
+ guarded 'Failed to serialize or submit exception', false do
45
+ data = Conversions.convert_exception(exception)
46
+ append_sanitizing_filter(data)
47
+ client.report_signal(data)
48
+ end
49
+ end
50
+
51
+ def post_batch(events)
52
+ guarded 'Failed to serialize or submit batch of events' do
53
+ batch = Conversions.convert_batch(events)
54
+ batch.each { |sig_or_trace| append_sanitizing_filter(sig_or_trace) }
55
+ client.report_batch(batch)
56
+ end
57
+ end
58
+
59
+ private
60
+
61
+ def append_sanitizing_filter(sig_or_trace)
62
+ sig_or_trace.append_to_h_filter Kit::StringSanitizer.method(:sanitize)
63
+ end
64
+
65
+ # we don't want exceptions to propagate and kill the worker thread
66
+ def guarded(msg, report = true)
67
+ yield
68
+ rescue StandardError => e
69
+ logger.warn "#{msg}: #{e.message}\n#{e.backtrace.map { |x| " #{x}" }.join("\n")}"
70
+ post_sqreen_exception(RemoteException.new(e)) if report
71
+ end
72
+
73
+ def client
74
+ Sqreen::Kit.auth_signals_client
75
+ end
76
+ end
77
+ end
78
+ end
@@ -4,5 +4,5 @@
4
4
  # Please refer to our terms for more information: https://www.sqreen.com/terms.html
5
5
 
6
6
  module Sqreen
7
- VERSION = '1.19.1'.freeze
7
+ VERSION = '1.20.2'.freeze
8
8
  end
@@ -60,6 +60,27 @@ class Sqreen::Weave::Legacy::Instrumentation
60
60
  'options' => opts[:perf_metric_percent] || { 'base' => 1.3, 'factor' => 1.0 },
61
61
  )
62
62
 
63
+ metrics_engine.create_metric(
64
+ 'name' => 'req_sq_hook_overhead',
65
+ 'period' => 60,
66
+ 'kind' => 'Binning',
67
+ 'options' => { 'base' => 2.0, 'factor' => 0.1 },
68
+ )
69
+
70
+ metrics_engine.create_metric(
71
+ 'name' => 'sq.hook.overhead',
72
+ 'period' => 60,
73
+ 'kind' => 'Binning',
74
+ 'options' => { 'base' => 2.0, 'factor' => 0.1 },
75
+ )
76
+
77
+ metrics_engine.create_metric(
78
+ 'name' => 'sq.shrinkwrap',
79
+ 'period' => 60,
80
+ 'kind' => 'Binning',
81
+ 'options' => { 'base' => 2.0, 'factor' => 0.1 },
82
+ )
83
+
63
84
  Sqreen.thread_cpu_time? && metrics_engine.create_metric(
64
85
  'name' => 'sq_thread_cpu_pct',
65
86
  'period' => opts[:period] || 60,
@@ -113,6 +134,9 @@ class Sqreen::Weave::Legacy::Instrumentation
113
134
  before('wave,meta,request', rank: -100000, mandatory: true) do |_call|
114
135
  next unless Sqreen.instrumentation_ready
115
136
 
137
+ # shrinkwrap_timer = Sqreen::Graft::Timer.new('weave,shrinkwrap')
138
+ # shrinkwrap_timer.start
139
+
116
140
  uuid = SecureRandom.uuid
117
141
  now = Sqreen::Graft::Timer.read
118
142
  Thread.current[:sqreen_http_request] = {
@@ -123,14 +147,13 @@ class Sqreen::Weave::Legacy::Instrumentation
123
147
  timer: Sqreen::Graft::Timer.new("request_#{uuid}"),
124
148
  timed_callbacks: [],
125
149
  timed_hooks: [],
126
- timed_hooks_before: [],
127
- timed_hooks_after: [],
128
- timed_hooks_raised: [],
129
- timed_hooks_ensured: [],
130
150
  skipped_callbacks: [],
151
+ # timed_shrinkwrap: shrinkwrap_timer,
131
152
  }
132
153
 
133
154
  Sqreen::Weave.logger.debug { "request.uuid: #{uuid}" }
155
+
156
+ # shrinkwrap_timer.stop
134
157
  end
135
158
 
136
159
  ensured('weave,meta,request', rank: 100000, mandatory: true) do |_call|
@@ -138,6 +161,9 @@ class Sqreen::Weave::Legacy::Instrumentation
138
161
 
139
162
  next if request.nil?
140
163
 
164
+ # shrinkwrap_timer = request[:timed_shrinkwrap]
165
+ # shrinkwrap_timer.start
166
+
141
167
  Thread.current[:sqreen_http_request] = nil
142
168
  now = Sqreen::Graft::Timer.read
143
169
  utc_now = Time.now.utc
@@ -167,59 +193,28 @@ class Sqreen::Weave::Legacy::Instrumentation
167
193
  metrics_engine.update(metric_name, now, nil, duration * 1000)
168
194
  end
169
195
 
170
- metric_name = 'sq.hooks_pre.pre'
171
- duration = request[:timed_hooks_before].sum(&:duration)
172
- unless metrics_engine.metric?(metric_name)
173
- metrics_engine.create_metric(
174
- 'name' => metric_name,
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
- )
196
+ request[:timed_hooks].each do |timer|
197
+ duration = timer.duration
198
+ metrics_engine.update('sq.hook.overhead', now, nil, duration * 1000)
203
199
  end
204
- metrics_engine.update(metric_name, now, nil, duration * 1000)
205
200
 
206
201
  skipped = request[:skipped_callbacks].map(&:name)
207
- Sqreen::Weave.logger.debug { "request:#{request[:uuid]} callback.skipped.size: #{skipped.count} callback.skipped: [#{skipped.join(', ')}]" }
202
+ Sqreen::Weave.logger.debug { "request:#{request[:uuid]} callback.skipped.size: #{skipped.count} callback.skipped: [#{skipped.join(', ')}]" } if Sqreen::Weave.logger.debug?
208
203
  timer = request[:timer]
209
204
  total = timer.duration
210
- Sqreen::Weave.logger.debug { "request:#{request[:uuid]} timer.total: #{'%.03fus' % (total * 1_000_000)} timer.size: #{timer.size}" }
205
+ Sqreen::Weave.logger.debug { "request:#{request[:uuid]} timer.total: #{'%.03fus' % (total * 1_000_000)}" } if Sqreen::Weave.logger.debug?
211
206
  timings = request[:timed_callbacks].map(&:to_s)
212
207
  total = request[:timed_callbacks].sum(&:duration)
213
- Sqreen::Weave.logger.debug { "request:#{request[:uuid]} callback.total: #{'%.03fus' % (total * 1_000_000)} callback.timings: [#{timings.join(', ')}]" }
208
+ Sqreen::Weave.logger.debug { "request:#{request[:uuid]} callback.total: #{'%.03fus' % (total * 1_000_000)} callback.timings: [#{timings.join(', ')}]" } if Sqreen::Weave.logger.debug?
214
209
  timings = request[:timed_hooks].map(&:to_s)
215
210
  total = request[:timed_hooks].sum(&:duration)
216
- Sqreen::Weave.logger.debug { "request:#{request[:uuid]} hook.total: #{'%.03fus' % (total * 1_000_000)} hook.timings: [#{timings.join(', ')}]" }
211
+ Sqreen::Weave.logger.debug { "request:#{request[:uuid]} hook.total: #{'%.03fus' % (total * 1_000_000)} hook.timings: [#{timings.join(', ')}]" } if Sqreen::Weave.logger.debug?
217
212
 
218
213
  skipped = request[:skipped_callbacks].map(&:name)
219
214
  skipped_rule_name = skipped.first && skipped.first =~ /weave,rule=(.*)$/ && $1
220
215
  Sqreen.observations_queue.push(['request_overtime', skipped_rule_name, 1, utc_now]) if skipped_rule_name
221
216
 
222
- sqreen_request_duration = total
217
+ sqreen_request_duration = request[:timed_hooks].sum(&:duration) + request[:timed_callbacks].sum(&:duration)
223
218
  Sqreen.observations_queue.push(['sq', nil, sqreen_request_duration * 1000, utc_now])
224
219
 
225
220
  request_duration = now - request[:start_time]
@@ -227,6 +222,14 @@ class Sqreen::Weave::Legacy::Instrumentation
227
222
 
228
223
  sqreen_request_ratio = (sqreen_request_duration * 100.0) / (request_duration - sqreen_request_duration)
229
224
  Sqreen.observations_queue.push(['pct', nil, sqreen_request_ratio, utc_now])
225
+
226
+ duration = request[:timed_hooks].sum(&:duration)
227
+ metrics_engine.update('req_sq_hook_overhead', now, nil, duration * 1000)
228
+
229
+ # shrinkwrap_timer.stop
230
+
231
+ # duration = shrinkwrap_timer.duration
232
+ # metrics_engine.update('sq.shrinkwrap', now, nil, duration * 1000)
230
233
  end
231
234
  end.install
232
235
 
@@ -275,7 +278,7 @@ class Sqreen::Weave::Legacy::Instrumentation
275
278
  a = call.args
276
279
  r = call.remaining
277
280
 
278
- Sqreen::Weave.logger.debug { "#{rule} klass=#{callback.klass} method=#{callback.method} when=#pre instance=#{i}" }
281
+ Sqreen::Weave.logger.debug { "#{rule} klass=#{callback.klass} method=#{callback.method} when=#pre instance=#{i}" } if Sqreen::Weave.logger.debug?
279
282
  begin
280
283
  ret = callback.pre(i, a, r)
281
284
  rescue StandardError => e
@@ -286,7 +289,7 @@ class Sqreen::Weave::Legacy::Instrumentation
286
289
  Sqreen::RemoteException.record(e)
287
290
  end
288
291
  end
289
- Sqreen::Weave.logger.debug { "#{rule} klass=#{callback.klass} method=#{callback.method} when=#pre instance=#{i} => return=#{ret.inspect}" }
292
+ Sqreen::Weave.logger.debug { "#{rule} klass=#{callback.klass} method=#{callback.method} when=#pre instance=#{i} => return=#{ret.inspect}" } if Sqreen::Weave.logger.debug?
290
293
 
291
294
  case ret[:status]
292
295
  when :skip, 'skip'
@@ -296,7 +299,7 @@ class Sqreen::Weave::Legacy::Instrumentation
296
299
  when :raise, 'raise'
297
300
  throw(b, b.raise(ret[:exception])) if ret.key?(:exception)
298
301
  throw(b, b.raise(Sqreen::AttackBlocked.new("Sqreen blocked a security threat (type: #{callback.rule_name}). No action is required.")))
299
- end unless ret.nil?
302
+ end unless ret.nil? || !ret.is_a?(Hash)
300
303
  end
301
304
  end
302
305
 
@@ -309,7 +312,7 @@ class Sqreen::Weave::Legacy::Instrumentation
309
312
  a = call.args
310
313
  r = call.remaining
311
314
 
312
- Sqreen::Weave.logger.debug { "#{rule} klass=#{callback.klass} method=#{callback.method} when=#post instance=#{i}" }
315
+ Sqreen::Weave.logger.debug { "#{rule} klass=#{callback.klass} method=#{callback.method} when=#post instance=#{i}" } if Sqreen::Weave.logger.debug?
313
316
  begin
314
317
  ret = callback.post(v, i, a, r)
315
318
  rescue StandardError => e
@@ -320,7 +323,7 @@ class Sqreen::Weave::Legacy::Instrumentation
320
323
  Sqreen::RemoteException.record(e)
321
324
  end
322
325
  end
323
- Sqreen::Weave.logger.debug { "#{rule} klass=#{callback.klass} method=#{callback.method} when=#post instance=#{i} => return=#{ret.inspect}" }
326
+ Sqreen::Weave.logger.debug { "#{rule} klass=#{callback.klass} method=#{callback.method} when=#post instance=#{i} => return=#{ret.inspect}" } if Sqreen::Weave.logger.debug?
324
327
 
325
328
  case ret[:status]
326
329
  when :override, 'override'
@@ -328,7 +331,7 @@ class Sqreen::Weave::Legacy::Instrumentation
328
331
  when :raise, 'raise'
329
332
  throw(b, b.raise(ret[:exception])) if ret.key?(:exception)
330
333
  throw(b, b.raise(Sqreen::AttackBlocked.new("Sqreen blocked a security threat (type: #{callback.rule_name}). No action is required.")))
331
- end unless ret.nil?
334
+ end unless ret.nil? || !ret.is_a?(Hash)
332
335
  end
333
336
  end
334
337
 
@@ -341,7 +344,7 @@ class Sqreen::Weave::Legacy::Instrumentation
341
344
  a = call.args
342
345
  r = call.remaining
343
346
 
344
- Sqreen::Weave.logger.debug { "#{rule} klass=#{callback.klass} method=#{callback.method} when=#failing instance=#{i}" }
347
+ Sqreen::Weave.logger.debug { "#{rule} klass=#{callback.klass} method=#{callback.method} when=#failing instance=#{i}" } if Sqreen::Weave.logger.debug?
345
348
  begin
346
349
  ret = callback.failing(e, i, a, r)
347
350
  rescue StandardError => e
@@ -352,9 +355,9 @@ class Sqreen::Weave::Legacy::Instrumentation
352
355
  Sqreen::RemoteException.record(e)
353
356
  end
354
357
  end
355
- Sqreen::Weave.logger.debug { "#{rule} klass=#{callback.klass} method=#{callback.method} when=#failing instance=#{i} => return=#{ret.inspect}" }
358
+ Sqreen::Weave.logger.debug { "#{rule} klass=#{callback.klass} method=#{callback.method} when=#failing instance=#{i} => return=#{ret.inspect}" } if Sqreen::Weave.logger.debug?
356
359
 
357
- raise e if ret.nil?
360
+ throw(b, b.raise(e)) if ret.nil? || !ret.is_a?(Hash)
358
361
 
359
362
  case ret[:status]
360
363
  when :override, 'override'
@@ -368,7 +371,7 @@ class Sqreen::Weave::Legacy::Instrumentation
368
371
  throw(b, b.raise(e))
369
372
  else
370
373
  throw(b, b.raise(e))
371
- end unless ret.nil?
374
+ end unless ret.nil? || !ret.is_a?(Hash)
372
375
  end
373
376
  end
374
377
  end.install
metadata CHANGED
@@ -1,15 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sqreen
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.19.1
4
+ version: 1.20.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sqreen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-06-01 00:00:00.000000000 Z
11
+ date: 2020-07-23 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: sqreen-backport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.1.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.1.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: sqreen-kit
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.2.1
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 0.2.1
13
41
  - !ruby/object:Gem::Dependency
14
42
  name: sq_mini_racer
15
43
  requirement: !ruby/object:Gem::Requirement
@@ -65,11 +93,10 @@ files:
65
93
  - lib/sqreen/actions/user_action_class.rb
66
94
  - lib/sqreen/actions/users_index.rb
67
95
  - lib/sqreen/agent.rb
96
+ - lib/sqreen/agent_message.rb
97
+ - lib/sqreen/aggregated_metric.rb
68
98
  - lib/sqreen/attack_blocked.rb
69
99
  - lib/sqreen/attack_detected.html
70
- - lib/sqreen/backport.rb
71
- - lib/sqreen/backport/clock_gettime.rb
72
- - lib/sqreen/backport/original_name.rb
73
100
  - lib/sqreen/binding_accessor.rb
74
101
  - lib/sqreen/binding_accessor/path_elem.rb
75
102
  - lib/sqreen/binding_accessor/transforms.rb
@@ -96,6 +123,7 @@ files:
96
123
  - lib/sqreen/dependency/sentry.rb
97
124
  - lib/sqreen/dependency/sinatra.rb
98
125
  - lib/sqreen/encoding_sanitizer.rb
126
+ - lib/sqreen/endpoint_testing.rb
99
127
  - lib/sqreen/error_handling_middleware.rb
100
128
  - lib/sqreen/event.rb
101
129
  - lib/sqreen/events/attack.rb
@@ -129,8 +157,16 @@ files:
129
157
  - lib/sqreen/js/mini_racer_adapter.rb
130
158
  - lib/sqreen/js/mini_racer_executable_js.rb
131
159
  - lib/sqreen/js/thread_local_exec_js_runnable.rb
160
+ - lib/sqreen/kit/signals/specialized/aggregated_metric.rb
161
+ - lib/sqreen/kit/signals/specialized/attack.rb
162
+ - lib/sqreen/kit/signals/specialized/binning_metric.rb
163
+ - lib/sqreen/kit/signals/specialized/http_trace.rb
164
+ - lib/sqreen/kit/signals/specialized/sdk_track_call.rb
165
+ - lib/sqreen/kit/signals/specialized/sqreen_exception.rb
132
166
  - lib/sqreen/legacy.rb
133
167
  - lib/sqreen/legacy/instrumentation.rb
168
+ - lib/sqreen/legacy/old_event_submission_strategy.rb
169
+ - lib/sqreen/legacy/waf_redactions.rb
134
170
  - lib/sqreen/log.rb
135
171
  - lib/sqreen/log/loggable.rb
136
172
  - lib/sqreen/logger.rb
@@ -201,6 +237,9 @@ files:
201
237
  - lib/sqreen/shared_storage.rb
202
238
  - lib/sqreen/shared_storage23.rb
203
239
  - lib/sqreen/shrink_wrap.rb
240
+ - lib/sqreen/signals/conversions.rb
241
+ - lib/sqreen/signals/http_trace_redaction.rb
242
+ - lib/sqreen/signals/signals_submission_strategy.rb
204
243
  - lib/sqreen/signature_verifier.rb
205
244
  - lib/sqreen/sinatra_middleware.rb
206
245
  - lib/sqreen/sqreen_signed_verifier.rb
@@ -253,8 +292,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
253
292
  - !ruby/object:Gem::Version
254
293
  version: '0'
255
294
  requirements: []
256
- rubyforge_project:
257
- rubygems_version: 2.7.7
295
+ rubygems_version: 3.1.2
258
296
  signing_key:
259
297
  specification_version: 4
260
298
  summary: Sqreen Ruby agent