sqreen 1.20.4.beta1 → 1.20.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -0
- data/lib/sqreen/condition_evaluator.rb +8 -2
- data/lib/sqreen/events/request_record.rb +0 -1
- data/lib/sqreen/frameworks/request_recorder.rb +2 -0
- data/lib/sqreen/legacy/old_event_submission_strategy.rb +2 -1
- data/lib/sqreen/rules.rb +7 -3
- data/lib/sqreen/rules/custom_error_cb.rb +3 -3
- data/lib/sqreen/rules/waf_cb.rb +3 -3
- data/lib/sqreen/version.rb +1 -1
- data/lib/sqreen/weave/legacy/instrumentation.rb +38 -19
- metadata +8 -11
- 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: d7324df5cecbb626299a4e048550c6f7c5a3e15bef2eecc8d89011d0342914aa
|
4
|
+
data.tar.gz: eabb5203769dcf898d8a4e373c6cfee7e5b0eac8bbfc3977fb8924a54504b126
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5e7f4bb53e01c0f5328a5190b189c82b596bcf28eada2104b1491c5601b1275866ef8950ae9ad92c91303011636a3c11ebcb3c3dbccd75280d6b89c1c69d301a
|
7
|
+
data.tar.gz: 77770ff7b00b9d07ea7f4137eadce1e840bc1ad94e885b42623354707306ebd42425187833e0403e33d02bea7471010bf934bda9010c5fe1d604715c5daf88c1
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
## 1.20.4
|
2
|
+
|
3
|
+
* Fix missing budget check
|
4
|
+
* Improve performance
|
5
|
+
* Align internal setting name for WAF
|
6
|
+
* Include response information in all payloads
|
7
|
+
* Improve robustness against invalid Unicode
|
8
|
+
* Prevent rule execution to pursue in early block cases
|
9
|
+
|
1
10
|
## 1.20.4.beta1
|
2
11
|
|
3
12
|
* Add optional dynamic time budget
|
@@ -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,13 @@ module Sqreen
|
|
81
81
|
if hkey.respond_to?(:empty?) && hkey.empty?
|
82
82
|
false
|
83
83
|
else
|
84
|
-
|
84
|
+
key_incl = if values.is_a?(String)
|
85
|
+
str_include?(values, hkey.to_s)
|
86
|
+
else
|
87
|
+
values.include?(hkey.to_s)
|
88
|
+
end
|
89
|
+
|
90
|
+
key_incl || hash_key_include?(values, hval, min_value_size, rem - 1)
|
85
91
|
end
|
86
92
|
end
|
87
93
|
end
|
@@ -69,6 +69,8 @@ module Sqreen
|
|
69
69
|
|
70
70
|
# signals require request section to be present
|
71
71
|
payload_requests << 'request'
|
72
|
+
# for signals, response is optional, but the backend team wants them
|
73
|
+
payload_requests << 'response'
|
72
74
|
payload = payload_creator.payload(payload_requests)
|
73
75
|
payload[:observed] = observed_items
|
74
76
|
|
@@ -6,6 +6,7 @@
|
|
6
6
|
require 'sqreen/aggregated_metric'
|
7
7
|
require 'sqreen/log/loggable'
|
8
8
|
require 'sqreen/legacy/waf_redactions'
|
9
|
+
require 'sqreen/kit/string_sanitizer'
|
9
10
|
|
10
11
|
module Sqreen
|
11
12
|
module Legacy
|
@@ -166,7 +167,7 @@ module Sqreen
|
|
166
167
|
res[:request][:parameters] = payload['params'] if payload['params']
|
167
168
|
res[:request][:headers] = payload['headers'] if payload['headers']
|
168
169
|
|
169
|
-
res = Sqreen::
|
170
|
+
res = Sqreen::Kit::StringSanitizer.sanitize(res)
|
170
171
|
|
171
172
|
if rr.redactor
|
172
173
|
res[:request], redacted = rr.redactor.redact(res[:request])
|
data/lib/sqreen/rules.rb
CHANGED
@@ -120,9 +120,13 @@ module Sqreen
|
|
120
120
|
|
121
121
|
cb_class = ExecJSCB if js
|
122
122
|
|
123
|
-
if cbname
|
124
|
-
|
125
|
-
|
123
|
+
if cbname
|
124
|
+
cb_class = if cbname.include?('::')
|
125
|
+
# Only load callbacks from sqreen
|
126
|
+
Rules.walk_const_get(cbname) if cbname.start_with?('::Sqreen::', 'Sqreen::')
|
127
|
+
else
|
128
|
+
Rules.const_get(cbname) if Rules.const_defined?(cbname) # rubocop:disable Style/IfInsideElse
|
129
|
+
end
|
126
130
|
end
|
127
131
|
|
128
132
|
if cb_class.nil?
|
@@ -55,12 +55,12 @@ module Sqreen
|
|
55
55
|
end
|
56
56
|
|
57
57
|
def respond_page
|
58
|
-
page
|
58
|
+
@page ||= File.read(File.join(File.dirname(__FILE__), '../attack_detected.html'))
|
59
59
|
headers = {
|
60
60
|
'Content-Type' => 'text/html',
|
61
|
-
'Content-Length' => page.size.to_s,
|
61
|
+
'Content-Length' => @page.size.to_s,
|
62
62
|
}
|
63
|
-
[@status_code, headers, page]
|
63
|
+
[@status_code, headers, [@page]]
|
64
64
|
end
|
65
65
|
end
|
66
66
|
end
|
data/lib/sqreen/rules/waf_cb.rb
CHANGED
@@ -11,7 +11,7 @@ require 'sqreen/safe_json'
|
|
11
11
|
require 'sqreen/exception'
|
12
12
|
require 'sqreen/util/capper'
|
13
13
|
require 'sqreen/dependency/libsqreen'
|
14
|
-
require 'sqreen/
|
14
|
+
require 'sqreen/kit/string_sanitizer'
|
15
15
|
|
16
16
|
module Sqreen
|
17
17
|
module Rules
|
@@ -60,7 +60,7 @@ module Sqreen
|
|
60
60
|
end
|
61
61
|
|
62
62
|
# 0 for using defaults (PW_RUN_TIMEOUT)
|
63
|
-
@max_run_budget_us = (@data['values'].fetch('
|
63
|
+
@max_run_budget_us = (@data['values'].fetch('max_budget_ms', 0) * 1000).to_i
|
64
64
|
@max_run_budget_us = INFINITE_BUDGET_US if @max_run_budget_us >= INFINITE_BUDGET_US
|
65
65
|
|
66
66
|
Sqreen.log.debug { "Max WAF run budget for #{@waf_rule_name} set to #{@max_run_budget_us} us" }
|
@@ -82,7 +82,7 @@ module Sqreen
|
|
82
82
|
waf_args = binding_accessors.each_with_object({}) do |(e, b), h|
|
83
83
|
h[e] = capper.call(b.resolve(*env))
|
84
84
|
end
|
85
|
-
waf_args = Sqreen::
|
85
|
+
waf_args = Sqreen::Kit::StringSanitizer.sanitize(waf_args)
|
86
86
|
|
87
87
|
if budget
|
88
88
|
rem_budget_s = budget - (Sqreen.time - start)
|
data/lib/sqreen/version.rb
CHANGED
@@ -5,6 +5,7 @@
|
|
5
5
|
|
6
6
|
require 'sqreen/weave/legacy'
|
7
7
|
require 'sqreen/weave/budget'
|
8
|
+
require 'sqreen/graft/hook'
|
8
9
|
require 'sqreen/graft/hook_point'
|
9
10
|
require 'sqreen/call_countable'
|
10
11
|
require 'sqreen/rules'
|
@@ -172,8 +173,8 @@ class Sqreen::Weave::Legacy::Instrumentation
|
|
172
173
|
request_timer.start
|
173
174
|
sqreen_timer = Sqreen::Graft::Timer.new("sqreen")
|
174
175
|
budget = Sqreen::Weave::Budget.current
|
175
|
-
request_budget_threshold = budget.threshold
|
176
|
-
request_budget_ratio = budget.ratio
|
176
|
+
request_budget_threshold = budget.threshold if budget
|
177
|
+
request_budget_ratio = budget.ratio if budget
|
177
178
|
request_budget_is_dynamic = !request_budget_ratio.nil?
|
178
179
|
request_budget = !request_budget_threshold.nil?
|
179
180
|
timed_level = (Sqreen.features['perf_level'] || 1).to_i
|
@@ -212,12 +213,16 @@ class Sqreen::Weave::Legacy::Instrumentation
|
|
212
213
|
if request[:timed_level] >= 1
|
213
214
|
request[:timed_callbacks].each do |timer|
|
214
215
|
duration = timer.duration
|
216
|
+
|
215
217
|
timer.tag =~ /weave,rule=(.*)$/ && rule = $1
|
216
|
-
|
217
|
-
timer.tag =~ /@after/ && whence = 'post'
|
218
|
-
timer.tag =~ /@raised/ && whence = 'failing'
|
218
|
+
next unless rule
|
219
219
|
|
220
|
-
|
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
|
221
226
|
|
222
227
|
metric_name = "sq.#{rule}.#{whence}"
|
223
228
|
metrics_engine.update(metric_name, now, nil, duration * 1000)
|
@@ -270,12 +275,16 @@ class Sqreen::Weave::Legacy::Instrumentation
|
|
270
275
|
tallies = Hash.new(0.0)
|
271
276
|
request[:timed_callbacks].each do |timer|
|
272
277
|
duration = timer.duration
|
278
|
+
|
273
279
|
timer.tag =~ /weave,rule=(.*)$/ && rule = $1
|
274
|
-
|
275
|
-
timer.tag =~ /@after/ && whence = 'post'
|
276
|
-
timer.tag =~ /@raised/ && whence = 'failing'
|
280
|
+
next unless rule
|
277
281
|
|
278
|
-
|
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
|
279
288
|
|
280
289
|
metric_name = "req.sq.#{rule}.#{whence}"
|
281
290
|
tallies[metric_name] += duration
|
@@ -364,15 +373,25 @@ class Sqreen::Weave::Legacy::Instrumentation
|
|
364
373
|
end
|
365
374
|
end
|
366
375
|
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
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)
|
376
395
|
end
|
377
396
|
end
|
378
397
|
|
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.20.4
|
4
|
+
version: 1.20.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-09-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sqreen-backport
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 0.2.
|
33
|
+
version: 0.2.2
|
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.2.
|
40
|
+
version: 0.2.2
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: sq_mini_racer
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -123,7 +123,6 @@ files:
|
|
123
123
|
- lib/sqreen/dependency/sentry.rb
|
124
124
|
- lib/sqreen/dependency/sinatra.rb
|
125
125
|
- lib/sqreen/deprecation.rb
|
126
|
-
- lib/sqreen/encoding_sanitizer.rb
|
127
126
|
- lib/sqreen/endpoint_testing.rb
|
128
127
|
- lib/sqreen/error_handling_middleware.rb
|
129
128
|
- lib/sqreen/event.rb
|
@@ -279,9 +278,7 @@ metadata:
|
|
279
278
|
changelog_uri: https://docs.sqreen.com/ruby/release-notes/
|
280
279
|
source_code_uri: https://github.com/sqreen/ruby-agent
|
281
280
|
bug_tracker_uri: https://github.com/sqreen/ruby-agent/issues
|
282
|
-
post_install_message:
|
283
|
-
This is a Sqreen beta release and may not work in all situations.
|
284
|
-
Make sure to review CHANGELOG.md for important details.
|
281
|
+
post_install_message:
|
285
282
|
rdoc_options: []
|
286
283
|
require_paths:
|
287
284
|
- lib
|
@@ -292,11 +289,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
292
289
|
version: 1.9.3
|
293
290
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
294
291
|
requirements:
|
295
|
-
- - "
|
292
|
+
- - ">="
|
296
293
|
- !ruby/object:Gem::Version
|
297
|
-
version:
|
294
|
+
version: '0'
|
298
295
|
requirements: []
|
299
|
-
rubygems_version: 3.1.
|
296
|
+
rubygems_version: 3.1.4
|
300
297
|
signing_key:
|
301
298
|
specification_version: 4
|
302
299
|
summary: Sqreen Ruby agent
|
@@ -1,27 +0,0 @@
|
|
1
|
-
# typed: true
|
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
|
-
module Sqreen
|
7
|
-
class EncodingSanitizer
|
8
|
-
def self.sanitize(obj)
|
9
|
-
case obj
|
10
|
-
when String
|
11
|
-
sanitize_string(obj)
|
12
|
-
when Array
|
13
|
-
obj.map { |e| sanitize(e) }
|
14
|
-
when Hash
|
15
|
-
obj.each_with_object({}) { |(k, v), h| h[k] = sanitize(v) }
|
16
|
-
else
|
17
|
-
obj
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
def self.sanitize_string(s)
|
22
|
-
return s if s.encoding.name == 'UTF-8' && s.valid_encoding?
|
23
|
-
|
24
|
-
s.encode('UTF-16', :invalid => :replace, :undef => :replace).encode('UTF-8')
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|