sqreen 1.21.0.beta2 → 1.21.0.beta3
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 +15 -7
- 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/condition_evaluator.rb +9 -2
- data/lib/sqreen/conditionable.rb +24 -6
- data/lib/sqreen/configuration.rb +1 -1
- data/lib/sqreen/deferred_logger.rb +50 -14
- data/lib/sqreen/deprecation.rb +38 -0
- data/lib/sqreen/ecosystem_integration.rb +7 -1
- data/lib/sqreen/ecosystem_integration/around_callbacks.rb +20 -10
- data/lib/sqreen/ecosystem_integration/instrumentation_service.rb +8 -4
- 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 +99 -21
- data/lib/sqreen/graft/callback.rb +1 -1
- data/lib/sqreen/graft/hook.rb +212 -100
- data/lib/sqreen/graft/hook_point.rb +18 -11
- 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 +1 -0
- data/lib/sqreen/logger.rb +24 -0
- data/lib/sqreen/metrics.rb +1 -0
- data/lib/sqreen/metrics/req_detailed.rb +41 -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 +4 -2
- data/lib/sqreen/rules/waf_cb.rb +3 -3
- data/lib/sqreen/runner.rb +46 -5
- data/lib/sqreen/version.rb +1 -1
- data/lib/sqreen/weave/budget.rb +35 -0
- data/lib/sqreen/weave/legacy/instrumentation.rb +274 -132
- data/lib/sqreen/worker.rb +6 -2
- metadata +22 -6
- data/lib/sqreen/encoding_sanitizer.rb +0 -27
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 88934827e2aa5f84ae21f96fb33afdada009fb118d94e8940fe61973812da4d4
|
4
|
+
data.tar.gz: b30da2199b4dc96d0193c671872ac192396c988ef67845c26fc1ed36a7704bfd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 19942da7597a18aee5b46aa4ef664c5083eadf3a878c5f431f9dde83196fc15f3263509c6cda6537a5c823de310f117dbb7c600130478a0828d2dbc73f0bf53c
|
7
|
+
data.tar.gz: c8b1293e8480043d3b494d6335725f649107c56e7bf282580592de7d680eaeb9475bd9091ea280ad2d2e473b100789a9b80c3dac93b9ddebbddb2f8ec4f3ced6
|
data/CHANGELOG.md
CHANGED
@@ -1,10 +1,18 @@
|
|
1
|
-
## 1.21.0.
|
2
|
-
|
3
|
-
*
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
*
|
1
|
+
## 1.21.0.beta3
|
2
|
+
|
3
|
+
* Avoid fd leak in `custom_error_cb` (ARB-109)
|
4
|
+
* Support `skip_rem_cbs` (ARB-107)
|
5
|
+
* Fix instrumentation in Ruby 2.0
|
6
|
+
* Fix encoding exception on `hash_key_include` (ARB-53)
|
7
|
+
* Fix erroneous start in non-Rails context (SQREEN-880)
|
8
|
+
* Make metrics thread-safe
|
9
|
+
* Add restart command
|
10
|
+
* Fix `overtime_cb`
|
11
|
+
* Add `perf_level` 2
|
12
|
+
* Several performance optimizations
|
13
|
+
* WAF: rename `budget_in_ms` to `max_budget_ms`
|
14
|
+
* Transport/Tracing with http module
|
15
|
+
* Update the blocking page
|
8
16
|
|
9
17
|
## 1.20.1
|
10
18
|
|
@@ -24,7 +24,7 @@ module Sqreen
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def do_run(identity_params)
|
27
|
-
Sqreen.log.
|
27
|
+
Sqreen.log.debug 'Will request redirect for user with identity ' \
|
28
28
|
"#{identity_params} (action: #{id})."
|
29
29
|
|
30
30
|
e = Sqreen::AttackBlocked.new(
|
@@ -67,7 +67,7 @@ module Sqreen
|
|
67
67
|
return true if rem <= 0
|
68
68
|
if hash.is_a?(Array)
|
69
69
|
return hash.any? do |v|
|
70
|
-
|
70
|
+
hash_key_include?(values, v, min_value_size, rem - 1)
|
71
71
|
end
|
72
72
|
end
|
73
73
|
|
@@ -81,7 +81,14 @@ module Sqreen
|
|
81
81
|
if hkey.respond_to?(:empty?) && hkey.empty?
|
82
82
|
false
|
83
83
|
else
|
84
|
-
|
84
|
+
key_incl =
|
85
|
+
if values.is_a?(String)
|
86
|
+
str_include? values, hkey.to_s
|
87
|
+
else
|
88
|
+
values.include?(hkey.to_s)
|
89
|
+
end
|
90
|
+
|
91
|
+
key_incl || hash_key_include?(values, hval, min_value_size, rem - 1)
|
85
92
|
end
|
86
93
|
end
|
87
94
|
end
|
data/lib/sqreen/conditionable.rb
CHANGED
@@ -28,21 +28,39 @@ module Sqreen
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def pre_with_conditions(inst, args, budget = nil, &block)
|
31
|
+
return pre_without_conditions(inst, args, budget, &block) if pre_conditions.nil?
|
32
|
+
|
31
33
|
eargs = [nil, framework, inst, args, @data, nil]
|
32
|
-
return nil
|
33
|
-
|
34
|
+
return nil unless pre_conditions.evaluate(*eargs)
|
35
|
+
|
36
|
+
res = pre_without_conditions(inst, args, budget, &block)
|
37
|
+
return { passed_conditions: true } unless res.is_a?(Hash)
|
38
|
+
res[:passed_conditions] = true
|
39
|
+
res
|
34
40
|
end
|
35
41
|
|
36
42
|
def post_with_conditions(rv, inst, args, budget = nil, &block)
|
43
|
+
return post_without_conditions(rv, inst, args, budget, &block) if post_conditions.nil?
|
44
|
+
|
37
45
|
eargs = [nil, framework, inst, args, @data, rv]
|
38
|
-
return nil
|
39
|
-
|
46
|
+
return nil unless post_conditions.evaluate(*eargs)
|
47
|
+
|
48
|
+
res = post_without_conditions(rv, inst, args, budget, &block)
|
49
|
+
return { passed_conditions: true } if res.nil?
|
50
|
+
res[:passed_conditions] = true
|
51
|
+
res
|
40
52
|
end
|
41
53
|
|
42
54
|
def failing_with_conditions(rv, inst, args, budget = nil, &block)
|
55
|
+
return failing_without_conditions(rv, inst, args, budget, &block) if failing_conditions.nil?
|
56
|
+
|
43
57
|
eargs = [nil, framework, inst, args, @data, rv]
|
44
|
-
return nil
|
45
|
-
|
58
|
+
return nil unless failing_conditions.evaluate(*eargs)
|
59
|
+
|
60
|
+
res = failing_without_conditions(rv, inst, args, budget, &block)
|
61
|
+
return { passed_conditions: true } if res.nil?
|
62
|
+
res[:passed_conditions] = true
|
63
|
+
res
|
46
64
|
end
|
47
65
|
|
48
66
|
protected
|
data/lib/sqreen/configuration.rb
CHANGED
@@ -57,7 +57,7 @@ module Sqreen
|
|
57
57
|
{ :env => :SQREEN_RULES_SIGNATURE, :name => :rules_verify_signature,
|
58
58
|
:default => true },
|
59
59
|
{ :env => :SQREEN_LOG_LEVEL, :name => :log_level,
|
60
|
-
:default => '
|
60
|
+
:default => 'INFO', :choice => %w[UNKNOWN FATAL ERROR WARN INFO DEBUG] },
|
61
61
|
{ :env => :SQREEN_LOG_LOCATION, :name => :log_location,
|
62
62
|
:default => 'log/sqreen.log' },
|
63
63
|
{ :env => :SQREEN_RUN_IN_TEST, :name => :run_in_test,
|
@@ -9,35 +9,70 @@ require 'sqreen/logger'
|
|
9
9
|
|
10
10
|
module Sqreen
|
11
11
|
class DeferredLogger
|
12
|
-
|
12
|
+
MAX_ENTRIES = 1000
|
13
|
+
|
14
|
+
Entry = Struct.new(:severity, :message)
|
13
15
|
|
14
16
|
def initialize
|
15
17
|
@buffer = StringIO.new
|
16
18
|
@logger = ::Logger.new(@buffer)
|
19
|
+
@entries = []
|
20
|
+
@mutex = Mutex.new
|
21
|
+
end
|
22
|
+
|
23
|
+
def debug?
|
24
|
+
true
|
25
|
+
end
|
26
|
+
|
27
|
+
def info?
|
28
|
+
true
|
29
|
+
end
|
30
|
+
|
31
|
+
def warn?
|
32
|
+
true
|
33
|
+
end
|
34
|
+
|
35
|
+
def error?
|
36
|
+
true
|
37
|
+
end
|
38
|
+
|
39
|
+
def fatal?
|
40
|
+
true
|
17
41
|
end
|
18
42
|
|
19
43
|
def debug(msg = nil, &block)
|
20
|
-
|
44
|
+
add(::Logger::DEBUG, msg, &block)
|
21
45
|
end
|
22
46
|
|
23
47
|
def info(msg = nil, &block)
|
24
|
-
|
48
|
+
add(::Logger::INFO, msg, &block)
|
25
49
|
end
|
26
50
|
|
27
51
|
def warn(msg = nil, &block)
|
28
|
-
|
52
|
+
add(::Logger::WARN, msg, &block)
|
29
53
|
end
|
30
54
|
|
31
55
|
def error(msg = nil, &block)
|
32
|
-
|
56
|
+
add(::Logger::ERROR, msg, &block)
|
33
57
|
end
|
34
58
|
|
35
59
|
def fatal(msg = nil, &block)
|
36
|
-
|
60
|
+
add(::Logger::FATAL, msg, &block)
|
61
|
+
end
|
62
|
+
|
63
|
+
def unknown(msg = nil, &block)
|
64
|
+
add(::Logger::UNKNOWN, msg, &block)
|
37
65
|
end
|
38
66
|
|
39
67
|
def add(severity, msg = nil, &block)
|
40
|
-
|
68
|
+
@mutex.synchronize do
|
69
|
+
@entries.shift if @entries.count >= MAX_ENTRIES
|
70
|
+
mark = @buffer.pos
|
71
|
+
@logger.add(severity, msg, &block)
|
72
|
+
@buffer.seek(mark)
|
73
|
+
@entries << Entry.new(severity, @buffer.read)
|
74
|
+
@buffer.truncate(0)
|
75
|
+
end
|
41
76
|
end
|
42
77
|
|
43
78
|
def formatter=(value)
|
@@ -45,21 +80,22 @@ module Sqreen
|
|
45
80
|
end
|
46
81
|
|
47
82
|
def flush_to(logger)
|
48
|
-
|
83
|
+
@mutex.synchronize do
|
84
|
+
@entries.each do |entry|
|
85
|
+
next if entry.severity < logger.level
|
86
|
+
logger.instance_eval { @logdev }.write(entry.message)
|
87
|
+
end
|
88
|
+
reset
|
89
|
+
end
|
49
90
|
end
|
50
91
|
|
51
92
|
private
|
52
93
|
|
53
|
-
def read
|
54
|
-
@buffer.rewind
|
55
|
-
@buffer.read
|
56
|
-
end
|
57
|
-
|
58
94
|
def reset
|
59
95
|
buffer = StringIO.new
|
60
96
|
logger = ::Logger.new(buffer)
|
61
97
|
logger.formatter = @logger.formatter
|
62
|
-
@buffer, @logger = buffer, logger
|
98
|
+
@buffer, @logger, @entries = buffer, logger, []
|
63
99
|
end
|
64
100
|
end
|
65
101
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# typed: strong
|
2
|
+
|
3
|
+
# Copyright (c) 2015 Sqreen. All Rights Reserved.
|
4
|
+
# Please refer to our terms for more information: https://www.sqreen.com/terms.html
|
5
|
+
|
6
|
+
require 'sqreen/log/loggable'
|
7
|
+
|
8
|
+
module Sqreen
|
9
|
+
module Deprecation
|
10
|
+
include Sqreen::Log::Loggable
|
11
|
+
|
12
|
+
module_function
|
13
|
+
|
14
|
+
def deprecate(method)
|
15
|
+
return unless ENV['SQREEN_DEBUG_DEPRECATION']
|
16
|
+
|
17
|
+
owner = method.owner
|
18
|
+
deprecated = :"_deprecated_#{method.name}"
|
19
|
+
klass = owner.is_a?(Module)
|
20
|
+
target = klass ? owner.to_s : owner.class.to_s
|
21
|
+
|
22
|
+
method.owner.instance_eval do
|
23
|
+
alias_method deprecated, method.name
|
24
|
+
|
25
|
+
define_method(method.name) do |*args, &block|
|
26
|
+
msg = [
|
27
|
+
"deprecation",
|
28
|
+
"target:#{target}",
|
29
|
+
"method:#{method.name}",
|
30
|
+
"caller:#{Kernel.caller_locations[0]}",
|
31
|
+
].join(' ')
|
32
|
+
Sqreen::Deprecation.logger.info(msg)
|
33
|
+
send(deprecated, *args, &block)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'sqreen/log/loggable'
|
2
|
+
require 'sqreen/metrics_store'
|
2
3
|
require 'sqreen/ecosystem'
|
3
4
|
require 'sqreen/ecosystem/dispatch_table'
|
5
|
+
require 'sqreen/ecosystem_integration/around_callbacks'
|
4
6
|
require 'sqreen/ecosystem_integration/instrumentation_service'
|
5
7
|
require 'sqreen/ecosystem_integration/request_lifecycle_tracking'
|
6
8
|
require 'sqreen/ecosystem_integration/signal_consumption'
|
@@ -17,9 +19,12 @@ module Sqreen
|
|
17
19
|
include Sqreen::Log::Loggable
|
18
20
|
|
19
21
|
# @param [Sqreen::Framework] framework
|
20
|
-
|
22
|
+
# @param [Proc] create_binning_metric
|
23
|
+
def initialize(framework, queue, create_binning_metric)
|
21
24
|
@framework = framework
|
22
25
|
@queue = queue
|
26
|
+
# XXX: created metrics are insulated from feature upgrades
|
27
|
+
@create_binning_metric = create_binning_metric
|
23
28
|
@request_lifecycle = RequestLifecycleTracking.new
|
24
29
|
@online = false
|
25
30
|
end
|
@@ -28,6 +33,7 @@ module Sqreen
|
|
28
33
|
raise 'already initialized' if @online
|
29
34
|
|
30
35
|
setup_dispatch_table
|
36
|
+
AroundCallbacks.create_metric = @create_binning_metric
|
31
37
|
Ecosystem.init
|
32
38
|
logger.info 'Ecosystem successfully initialized'
|
33
39
|
@online = true
|
@@ -1,6 +1,8 @@
|
|
1
|
+
require 'sqreen/metrics_store'
|
1
2
|
require 'sqreen/log/loggable'
|
2
3
|
require 'sqreen/events/remote_exception'
|
3
4
|
require 'sqreen/mono_time'
|
5
|
+
require 'sqreen/graft/call'
|
4
6
|
|
5
7
|
module Sqreen
|
6
8
|
class EcosystemIntegration
|
@@ -8,27 +10,32 @@ module Sqreen
|
|
8
10
|
class << self
|
9
11
|
include Log::Loggable::ClassMethods
|
10
12
|
|
13
|
+
# @return [Proc]
|
14
|
+
attr_accessor :create_metric
|
15
|
+
|
11
16
|
# for instrumentation hooks
|
12
|
-
# instrumentation hooks already handle budgets
|
13
|
-
# to do in that respect
|
17
|
+
# instrumentation hooks already handle budgets/metrics
|
14
18
|
def wrap_instrumentation_hook(module_name, action, callable)
|
15
|
-
|
19
|
+
# make tag similar to that of rules
|
20
|
+
# TODO: move to structured tags to avoid silly string manips
|
21
|
+
action_for_metric = if %w[pre post failing finally].include?(action)
|
22
|
+
action
|
23
|
+
else
|
24
|
+
'pre'
|
25
|
+
end
|
26
|
+
metric_name = "sq.ecosystem_#{module_name}.#{action_for_metric}"
|
27
|
+
create_metric.call(metric_name)
|
16
28
|
|
17
29
|
Proc.new do |*args|
|
18
30
|
begin
|
19
|
-
start = Sqreen.time
|
20
31
|
callable.call(*args)
|
21
32
|
rescue ::Exception => e # rubocop:disable Lint/RescueException
|
22
33
|
# 2) rescue exceptions
|
23
34
|
logger.warn { "Error in #{module_name}:#{action}: #{e.message}" }
|
24
35
|
logger.debug { e.backtrace.map { |x| " #{x}" }.join("\n") }
|
25
36
|
Sqreen::RemoteException.record(e)
|
26
|
-
|
27
|
-
|
28
|
-
stop = Sqreen.time
|
29
|
-
Sqreen::PerformanceNotifications.notify(perf_notif_name, action, start, stop)
|
30
|
-
end # end proc
|
31
|
-
end # end begin
|
37
|
+
end # end begin
|
38
|
+
end # end proc
|
32
39
|
end
|
33
40
|
|
34
41
|
# XXX: not used yet
|
@@ -36,6 +43,8 @@ module Sqreen
|
|
36
43
|
timer_name = "ecosystem:#{module_name}@#{action}"
|
37
44
|
perf_notif_name = "ecosystem_#{module_name}"
|
38
45
|
|
46
|
+
# XXX: register metric
|
47
|
+
|
39
48
|
Proc.new do |*args|
|
40
49
|
begin
|
41
50
|
req_storage = Thread.current[:sqreen_http_request]
|
@@ -76,6 +85,7 @@ module Sqreen
|
|
76
85
|
if timer
|
77
86
|
req_timer.include_measurements(timer) if req_timer
|
78
87
|
|
88
|
+
# XXX: PerformanceNotifications is used no more
|
79
89
|
Sqreen::PerformanceNotifications.notify(
|
80
90
|
perf_notif_name, action, *timer.start_and_end
|
81
91
|
)
|
@@ -12,22 +12,26 @@ module Sqreen
|
|
12
12
|
hook = Sqreen::Graft::Hook[method].add do
|
13
13
|
if spec[:before]
|
14
14
|
cb = AroundCallbacks.wrap_instrumentation_hook(module_name, 'pre', spec[:before])
|
15
|
-
|
15
|
+
tag = "weave,rule=ecosystem_#{module_name}"
|
16
|
+
before(tag, flow: true, &cb)
|
16
17
|
end
|
17
18
|
|
18
19
|
if spec[:after]
|
19
20
|
cb = AroundCallbacks.wrap_instrumentation_hook(module_name, 'post', spec[:after])
|
20
|
-
|
21
|
+
tag = "weave,rule=ecosystem_#{module_name}"
|
22
|
+
after(tag, flow: true, &cb)
|
21
23
|
end
|
22
24
|
|
23
25
|
if spec[:raised]
|
24
26
|
cb = AroundCallbacks.wrap_instrumentation_hook(module_name, 'failing', spec[:raised])
|
25
|
-
|
27
|
+
tag = "weave,rule=ecosystem_#{module_name}"
|
28
|
+
raised(tag, flow: true, &cb)
|
26
29
|
end
|
27
30
|
|
28
31
|
if spec[:ensured]
|
29
32
|
cb = AroundCallbacks.wrap_instrumentation_hook(module_name, 'finally', spec[:ensured])
|
30
|
-
|
33
|
+
tag = "weave,rule=ecosystem_#{module_name}"
|
34
|
+
ensured(tag, flow: true, &cb)
|
31
35
|
end
|
32
36
|
end
|
33
37
|
hook.install
|
@@ -218,7 +218,16 @@ module Sqreen
|
|
218
218
|
|
219
219
|
# Should the agent not be starting up?
|
220
220
|
def prevent_startup
|
221
|
+
# SQREEN-880 - prevent Sqreen startup on Sidekiq workers
|
222
|
+
return :sidekiq_cli if defined?(Sidekiq::CLI)
|
223
|
+
return :delayed_job if defined?(Delayed::Command)
|
224
|
+
|
225
|
+
# Prevent Sqreen startup on rake tasks - unless this is a Sqreen test
|
226
|
+
run_in_test = sqreen_configuration.get(:run_in_test)
|
227
|
+
return :rake if !run_in_test && $0.end_with?('rake')
|
228
|
+
|
221
229
|
return :irb if $0 == 'irb'
|
230
|
+
|
222
231
|
return if sqreen_configuration.nil?
|
223
232
|
disable = sqreen_configuration.get(:disable)
|
224
233
|
return :config_disable if disable == true || disable.to_s.to_i == 1
|