sqreen 1.19.0.beta1 → 1.19.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 +21 -2
- data/lib/sqreen/rules/not_found_cb.rb +2 -0
- data/lib/sqreen/rules/waf_cb.rb +28 -8
- data/lib/sqreen/runner.rb +5 -1
- data/lib/sqreen/version.rb +1 -1
- data/lib/sqreen/weave/legacy/instrumentation.rb +25 -7
- metadata +14 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a1a0d2f8489dac7835a9d2135b0e35c15848a4fa094f7912f9979a83a9d2670e
|
4
|
+
data.tar.gz: 9bfc5db45531824d4f968f45fe495c9fad5da7c258c368fec5821aba8f66b124
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f2c2e5a91c6e415c6003dae1c3ca775b9d40eaacb34e4d28d07c991e46941bcb0bb0f1e9d01bdb1644562fb35852c9fb222bd8f1b83a008be3871ee6a5880cb9
|
7
|
+
data.tar.gz: 9164671762553af1f0cd658e3d654432a3eebfe81050f32d9cf8fc7c36fedb8c40a530629e57a16bec62536a080a931a2f2b34ba1fcb33521ab2964db38bc224
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,25 @@
|
|
1
|
-
## 1.19.
|
1
|
+
## 1.19.4
|
2
2
|
|
3
|
-
*
|
3
|
+
* Fix signature check
|
4
|
+
|
5
|
+
## 1.19.3
|
6
|
+
|
7
|
+
* Improve WAF PII protection
|
8
|
+
|
9
|
+
## 1.19.2
|
10
|
+
|
11
|
+
* Handle unexpected rule callback return values more gracefully
|
12
|
+
* Fix incorrect return value for 404 native callback
|
13
|
+
|
14
|
+
## 1.19.1
|
15
|
+
|
16
|
+
* Fix LocalJumpError when reaching a Rack app nested in a Rails app
|
17
|
+
|
18
|
+
## 1.19.0
|
19
|
+
|
20
|
+
* Upgrade WAF features via libsqreen 0.6.1
|
21
|
+
* Improve time defensiveness in WAF
|
22
|
+
* Improve compatibility with APM agents via a new optional instrumentation engine
|
4
23
|
* Fix action reloading not being entirely cleared on reload
|
5
24
|
* Improve handling of hash symbol keys in some security rules
|
6
25
|
* Fix constant resolution scope on agent boot
|
data/lib/sqreen/rules/waf_cb.rb
CHANGED
@@ -11,11 +11,15 @@ require 'sqreen/safe_json'
|
|
11
11
|
require 'sqreen/exception'
|
12
12
|
require 'sqreen/util/capper'
|
13
13
|
require 'sqreen/dependency/libsqreen'
|
14
|
+
require 'sqreen/encoding_sanitizer'
|
14
15
|
|
15
16
|
module Sqreen
|
16
17
|
module Rules
|
17
18
|
class WAFCB < RuleCB
|
18
|
-
|
19
|
+
# 2^30 -1 or 2^62 -1
|
20
|
+
MAX_FIXNUM = 1.size == 4 ? 1_073_741_823 : 4_611_686_018_427_387_903
|
21
|
+
# will be converted to a long, so better not to overflow
|
22
|
+
INFINITE_BUDGET_US = MAX_FIXNUM
|
19
23
|
|
20
24
|
def self.libsqreen?
|
21
25
|
Sqreen::Dependency::LibSqreen.required?
|
@@ -25,7 +29,7 @@ module Sqreen
|
|
25
29
|
Sqreen::Dependency.const_exist?('LibSqreen::WAF')
|
26
30
|
end
|
27
31
|
|
28
|
-
attr_reader :binding_accessors, :
|
32
|
+
attr_reader :binding_accessors, :max_run_budget_us, :waf_rule_name
|
29
33
|
|
30
34
|
def initialize(*args)
|
31
35
|
super(*args)
|
@@ -54,8 +58,12 @@ module Sqreen
|
|
54
58
|
@binding_accessors = @data['values'].fetch('binding_accessors', []).each_with_object({}) do |e, h|
|
55
59
|
h[e] = BindingAccessor.new(e)
|
56
60
|
end
|
57
|
-
|
58
|
-
|
61
|
+
|
62
|
+
# 0 for using defaults (PW_RUN_TIMEOUT)
|
63
|
+
@max_run_budget_us = (@data['values'].fetch('budget_in_ms', 0) * 1000).to_i
|
64
|
+
@max_run_budget_us = INFINITE_BUDGET_US if @max_run_budget_us >= INFINITE_BUDGET_US
|
65
|
+
|
66
|
+
Sqreen.log.debug { "Max WAF run budget for #{@waf_rule_name} set to #{@max_run_budget_us} us" }
|
59
67
|
|
60
68
|
ObjectSpace.define_finalizer(self, WAFCB.finalizer(@waf_rule_name.dup))
|
61
69
|
end
|
@@ -68,20 +76,32 @@ module Sqreen
|
|
68
76
|
|
69
77
|
env = [binding, framework, instance, args]
|
70
78
|
|
79
|
+
start = Sqreen.time if budget
|
80
|
+
|
71
81
|
capper = Sqreen::Util::Capper.new(string_size_cap: 4096, size_cap: 150, depth_cap: 10)
|
72
82
|
waf_args = binding_accessors.each_with_object({}) do |(e, b), h|
|
73
83
|
h[e] = capper.call(b.resolve(*env))
|
74
84
|
end
|
75
85
|
waf_args = Sqreen::EncodingSanitizer.sanitize(waf_args)
|
76
|
-
|
77
|
-
|
86
|
+
|
87
|
+
if budget
|
88
|
+
rem_budget_s = budget - (Sqreen.time - start)
|
89
|
+
return advise_action(nil) if rem_budget_s <= 0.0
|
90
|
+
|
91
|
+
waf_gen_budget_us = [(rem_budget_s * 1_000_000).to_i, MAX_FIXNUM].min
|
92
|
+
else # no budget
|
93
|
+
waf_gen_budget_us = INFINITE_BUDGET_US
|
94
|
+
end
|
95
|
+
|
96
|
+
action, data = ::LibSqreen::WAF.run(waf_rule_name, waf_args,
|
97
|
+
waf_gen_budget_us, @max_run_budget_us)
|
78
98
|
|
79
99
|
case action
|
80
100
|
when :monitor
|
81
|
-
record_event({
|
101
|
+
record_event({ waf_data: data })
|
82
102
|
advise_action(nil)
|
83
103
|
when :block
|
84
|
-
record_event({
|
104
|
+
record_event({ waf_data: data })
|
85
105
|
advise_action(:raise)
|
86
106
|
when :good
|
87
107
|
advise_action(nil)
|
data/lib/sqreen/runner.rb
CHANGED
@@ -121,7 +121,11 @@ module Sqreen
|
|
121
121
|
|
122
122
|
self.metrics_engine = MetricsStore.new
|
123
123
|
|
124
|
-
|
124
|
+
needs_weave = proc do
|
125
|
+
Gem::Specification.select { |s| s.name == 'scout_apm' && Gem::Requirement.new('>= 2.5.2').satisfied_by?(Gem::Version.new(s.version)) }.any?
|
126
|
+
end
|
127
|
+
|
128
|
+
if @configuration.get(:weave) || needs_weave.call
|
125
129
|
@instrumenter = Sqreen::Weave::Legacy::Instrumentation.new(metrics_engine)
|
126
130
|
else
|
127
131
|
@instrumenter = Sqreen::Legacy::Instrumentation.new(metrics_engine)
|
data/lib/sqreen/version.rb
CHANGED
@@ -8,6 +8,7 @@ require 'sqreen/graft/hook_point'
|
|
8
8
|
require 'sqreen/call_countable'
|
9
9
|
require 'sqreen/rules'
|
10
10
|
require 'sqreen/rules/record_request_context'
|
11
|
+
require 'sqreen/sqreen_signed_verifier'
|
11
12
|
|
12
13
|
class Sqreen::Weave::Legacy::Instrumentation
|
13
14
|
attr_accessor :metrics_engine
|
@@ -76,11 +77,23 @@ class Sqreen::Weave::Legacy::Instrumentation
|
|
76
77
|
if strategy == :prepend && !Module.respond_to?(:prepend)
|
77
78
|
Sqreen::Weave.logger.warn { "strategy: #{strategy.inspect} unavailable, falling back to :chain" }
|
78
79
|
strategy = :chain
|
80
|
+
elsif strategy == :chain && Gem::Specification.select { |s| s.name == 'scout_apm' && Gem::Requirement.new('>= 2.5.2').satisfied_by?(Gem::Version.new(s.version)) }.any?
|
81
|
+
Sqreen::Weave.logger.warn { "strategy: #{strategy.inspect} unavailable with scout_apm >= 2.5.2, switching to :prepend" }
|
82
|
+
strategy = :prepend
|
79
83
|
end
|
80
84
|
Sqreen::Weave.logger.debug { "strategy: #{strategy.inspect}" }
|
81
85
|
|
82
86
|
### set up rule signature verifier
|
83
87
|
verifier = nil
|
88
|
+
if Sqreen.features['rules_signature'] &&
|
89
|
+
Sqreen.config_get(:rules_verify_signature) == true &&
|
90
|
+
!defined?(::JRUBY_VERSION)
|
91
|
+
verifier = Sqreen::SqreenSignedVerifier.new
|
92
|
+
Sqreen::Weave.logger.debug('Rules signature enabled')
|
93
|
+
else
|
94
|
+
Sqreen::Weave.logger.debug('Rules signature disabled')
|
95
|
+
end
|
96
|
+
|
84
97
|
### force clean instrumentation callback list
|
85
98
|
@hooks = []
|
86
99
|
### for each rule description
|
@@ -108,6 +121,8 @@ class Sqreen::Weave::Legacy::Instrumentation
|
|
108
121
|
@hooks << request_hook
|
109
122
|
request_hook.add do
|
110
123
|
before('wave,meta,request', rank: -100000, mandatory: true) do |_call|
|
124
|
+
next unless Sqreen.instrumentation_ready
|
125
|
+
|
111
126
|
uuid = SecureRandom.uuid
|
112
127
|
now = Sqreen::Graft::Timer.read
|
113
128
|
Thread.current[:sqreen_http_request] = {
|
@@ -130,6 +145,9 @@ class Sqreen::Weave::Legacy::Instrumentation
|
|
130
145
|
|
131
146
|
ensured('weave,meta,request', rank: 100000, mandatory: true) do |_call|
|
132
147
|
request = Thread.current[:sqreen_http_request]
|
148
|
+
|
149
|
+
next if request.nil?
|
150
|
+
|
133
151
|
Thread.current[:sqreen_http_request] = nil
|
134
152
|
now = Sqreen::Graft::Timer.read
|
135
153
|
utc_now = Time.now.utc
|
@@ -261,7 +279,7 @@ class Sqreen::Weave::Legacy::Instrumentation
|
|
261
279
|
hook.add do
|
262
280
|
if callback.pre?
|
263
281
|
before(rule, rank: priority, mandatory: !callback.overtimeable, flow: block, ignore: ignore) do |call, b|
|
264
|
-
|
282
|
+
next unless Thread.current[:sqreen_http_request]
|
265
283
|
|
266
284
|
i = call.instance
|
267
285
|
a = call.args
|
@@ -288,13 +306,13 @@ class Sqreen::Weave::Legacy::Instrumentation
|
|
288
306
|
when :raise, 'raise'
|
289
307
|
throw(b, b.raise(ret[:exception])) if ret.key?(:exception)
|
290
308
|
throw(b, b.raise(Sqreen::AttackBlocked.new("Sqreen blocked a security threat (type: #{callback.rule_name}). No action is required.")))
|
291
|
-
end unless ret.nil?
|
309
|
+
end unless ret.nil? || !ret.is_a?(Hash)
|
292
310
|
end
|
293
311
|
end
|
294
312
|
|
295
313
|
if callback.post?
|
296
314
|
after(rule, rank: -priority, mandatory: !callback.overtimeable, flow: block, ignore: ignore) do |call, b|
|
297
|
-
|
315
|
+
next unless Thread.current[:sqreen_http_request]
|
298
316
|
|
299
317
|
i = call.instance
|
300
318
|
v = call.returned
|
@@ -320,13 +338,13 @@ class Sqreen::Weave::Legacy::Instrumentation
|
|
320
338
|
when :raise, 'raise'
|
321
339
|
throw(b, b.raise(ret[:exception])) if ret.key?(:exception)
|
322
340
|
throw(b, b.raise(Sqreen::AttackBlocked.new("Sqreen blocked a security threat (type: #{callback.rule_name}). No action is required.")))
|
323
|
-
end unless ret.nil?
|
341
|
+
end unless ret.nil? || !ret.is_a?(Hash)
|
324
342
|
end
|
325
343
|
end
|
326
344
|
|
327
345
|
if callback.failing?
|
328
346
|
raised(rule, rank: priority, mandatory: !callback.overtimeable, flow: block, ignore: ignore) do |call, b|
|
329
|
-
|
347
|
+
next unless Thread.current[:sqreen_http_request]
|
330
348
|
|
331
349
|
i = call.instance
|
332
350
|
e = call.raised
|
@@ -346,7 +364,7 @@ class Sqreen::Weave::Legacy::Instrumentation
|
|
346
364
|
end
|
347
365
|
Sqreen::Weave.logger.debug { "#{rule} klass=#{callback.klass} method=#{callback.method} when=#failing instance=#{i} => return=#{ret.inspect}" }
|
348
366
|
|
349
|
-
raise
|
367
|
+
throw(b, b.raise(e)) if ret.nil? || !ret.is_a?(Hash)
|
350
368
|
|
351
369
|
case ret[:status]
|
352
370
|
when :override, 'override'
|
@@ -360,7 +378,7 @@ class Sqreen::Weave::Legacy::Instrumentation
|
|
360
378
|
throw(b, b.raise(e))
|
361
379
|
else
|
362
380
|
throw(b, b.raise(e))
|
363
|
-
end unless ret.nil?
|
381
|
+
end unless ret.nil? || !ret.is_a?(Hash)
|
364
382
|
end
|
365
383
|
end
|
366
384
|
end.install
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sqreen
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.19.
|
4
|
+
version: 1.19.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sqreen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-07-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sq_mini_racer
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 0.
|
33
|
+
version: 0.6.1.0.0
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 0.
|
40
|
+
version: 0.6.1.0.0
|
41
41
|
description: Sqreen is a SaaS based Application protection and monitoring platform
|
42
42
|
that integrates directly into your Ruby applications. Learn more at https://sqreen.com.
|
43
43
|
email: contact@sqreen.com
|
@@ -232,10 +232,13 @@ files:
|
|
232
232
|
homepage: https://www.sqreen.com/
|
233
233
|
licenses:
|
234
234
|
- Sqreen
|
235
|
-
metadata:
|
236
|
-
|
237
|
-
|
238
|
-
|
235
|
+
metadata:
|
236
|
+
homepage_uri: https://sqreen.com
|
237
|
+
documentation_uri: https://docs.sqreen.com/
|
238
|
+
changelog_uri: https://docs.sqreen.com/ruby/release-notes/
|
239
|
+
source_code_uri: https://github.com/sqreen/ruby-agent
|
240
|
+
bug_tracker_uri: https://github.com/sqreen/ruby-agent/issues
|
241
|
+
post_install_message:
|
239
242
|
rdoc_options: []
|
240
243
|
require_paths:
|
241
244
|
- lib
|
@@ -246,11 +249,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
246
249
|
version: 1.9.3
|
247
250
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
248
251
|
requirements:
|
249
|
-
- - "
|
252
|
+
- - ">="
|
250
253
|
- !ruby/object:Gem::Version
|
251
|
-
version:
|
254
|
+
version: '0'
|
252
255
|
requirements: []
|
253
|
-
rubygems_version: 3.
|
256
|
+
rubygems_version: 3.1.2
|
254
257
|
signing_key:
|
255
258
|
specification_version: 4
|
256
259
|
summary: Sqreen Ruby agent
|