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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 18fc090589982cc7e09d74263a3bbb17ae9180f00afd8425c47498a0f8b75e36
4
- data.tar.gz: 074c3c9cad84ef1a52e6fd7ce1a4db5431920f59298e5b930206ca9a996141e9
3
+ metadata.gz: d7324df5cecbb626299a4e048550c6f7c5a3e15bef2eecc8d89011d0342914aa
4
+ data.tar.gz: eabb5203769dcf898d8a4e373c6cfee7e5b0eac8bbfc3977fb8924a54504b126
5
5
  SHA512:
6
- metadata.gz: afd27c8a52c0c5e21685b9bf6b346a28ca43ff297c529c1976d7197bc132d51a92f2ac52dcb4de150cd8c752c4875b4fdd3baf8e59560a0c1952c4df12585572
7
- data.tar.gz: 2e6d09aceaf1dcc351537b0a34e4459e7f1d4659a231cd515e6f01ec42f0515dc40ff89f14adb7094a6971f86fe3983e984bf35f8242b8f047405c164ef0874c
6
+ metadata.gz: 5e7f4bb53e01c0f5328a5190b189c82b596bcf28eada2104b1491c5601b1275866ef8950ae9ad92c91303011636a3c11ebcb3c3dbccd75280d6b89c1c69d301a
7
+ data.tar.gz: 77770ff7b00b9d07ea7f4137eadce1e840bc1ad94e885b42623354707306ebd42425187833e0403e33d02bea7471010bf934bda9010c5fe1d604715c5daf88c1
@@ -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
- ConditionEvaluator.hash_key_include?(values, v, min_value_size, rem - 1)
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
- values.include?(hkey.to_s) || ConditionEvaluator.hash_key_include?(values, hval, min_value_size, rem - 1)
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
@@ -8,7 +8,6 @@
8
8
  require 'json'
9
9
  require 'sqreen/log'
10
10
  require 'sqreen/event'
11
- require 'sqreen/encoding_sanitizer'
12
11
  require 'sqreen/sensitive_data_redactor'
13
12
 
14
13
  module Sqreen
@@ -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::EncodingSanitizer.sanitize(res)
170
+ res = Sqreen::Kit::StringSanitizer.sanitize(res)
170
171
 
171
172
  if rr.redactor
172
173
  res[:request], redacted = rr.redactor.redact(res[:request])
@@ -120,9 +120,13 @@ module Sqreen
120
120
 
121
121
  cb_class = ExecJSCB if js
122
122
 
123
- if cbname && Rules.const_defined?(cbname)
124
- # Only load callbacks from sqreen
125
- cb_class = Rules.const_get(cbname)
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 = open(File.join(File.dirname(__FILE__), '../attack_detected.html'))
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
@@ -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/encoding_sanitizer'
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('budget_in_ms', 0) * 1000).to_i
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::EncodingSanitizer.sanitize(waf_args)
85
+ waf_args = Sqreen::Kit::StringSanitizer.sanitize(waf_args)
86
86
 
87
87
  if budget
88
88
  rem_budget_s = budget - (Sqreen.time - start)
@@ -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.20.4.beta1'.freeze
7
+ VERSION = '1.20.4'.freeze
8
8
  end
@@ -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
- timer.tag =~ /@before/ && whence = 'pre'
217
- timer.tag =~ /@after/ && whence = 'post'
218
- timer.tag =~ /@raised/ && whence = 'failing'
218
+ next unless rule
219
219
 
220
- next unless rule && whence
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
- timer.tag =~ /@before/ && whence = 'pre'
275
- timer.tag =~ /@after/ && whence = 'post'
276
- timer.tag =~ /@raised/ && whence = 'failing'
280
+ next unless rule
277
281
 
278
- next unless rule && whence
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
- case ret[:status]
368
- when :skip, 'skip'
369
- throw(b, b.return(ret[:new_return_value]).break!) if ret.key?(:new_return_value)
370
- when :modify_args, 'modify_args'
371
- throw(b, b.args(ret[:args]))
372
- when :raise, 'raise'
373
- throw(b, b.raise(ret[:exception])) if ret.key?(:exception)
374
- throw(b, b.raise(Sqreen::AttackBlocked.new("Sqreen blocked a security threat (type: #{callback.rule_name}). No action is required.")))
375
- end unless ret.nil? || !ret.is_a?(Hash)
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.beta1
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-08-14 00:00:00.000000000 Z
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.1
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.1
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: |2
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: 1.3.1
294
+ version: '0'
298
295
  requirements: []
299
- rubygems_version: 3.1.2
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