sqreen 1.16.1 → 1.16.2

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: f14c1978c48e3db55da6c20eb782a5313066c357038b215821652be20bec7a90
4
- data.tar.gz: 91eee47349717f3d760ede2086586a3ab009449acadcdbb4b4120586afe7601c
3
+ metadata.gz: 424c794c9315a7e1a0544fd6be427194ec7d7155e665ba86c1c3413306078941
4
+ data.tar.gz: 815fa9b893dd2577360a0408cc44194879c9fb1bbe5074cdce6c8c8629e82704
5
5
  SHA512:
6
- metadata.gz: 2c92239048effb55846ac2777d59f92b73295d13548cc881ccd6686a4191d7691a4238a59f94820d99eb01f5435d8874d7afdb60518cafb0c4337b317969a18b
7
- data.tar.gz: 3c2f2413eb44ede4c346f07d9956cd49b511cad33e6f8c0962c41cb34ef146bf973eb02861ce0984b486ea43a6dcd80f4848450d74c990447926b5c93bbf3684
6
+ metadata.gz: 9bc336364648476b1e6a0b6a3955215646c008a418b35f39abacc1cee9fccd5bab9374e8e90b444bc2a1482eebc25ddf463526154479acca14acc7605e438bdf
7
+ data.tar.gz: 53433d834097073f8ec98dd4396243029fb55e60c675bb6da379d12090000cbb31be0a23e736a9cc70615dd5fe7991559cc4a3c3c884d02cbbe6e5c787e5b415
@@ -18,7 +18,6 @@ require 'thread'
18
18
 
19
19
  Sqreen.framework.on_start do |framework|
20
20
  if Sqreen.framework.on_pre_fork_preload?
21
- STDERR.puts("Avoiding launching sqreen thread pre-fork") # sqreen log unavailable
22
21
  next
23
22
  end
24
23
  Thread.new do
@@ -127,7 +127,7 @@ module Sqreen
127
127
  begin
128
128
  regex = Regexp.compile(regex)
129
129
  rescue RegexpError
130
- Sqreen.log.warn("Invalid regular expression given in strip_sensitive_keys: #{regex}")
130
+ Sqreen.log.warn("Invalid regular expression given in strip_sensitive_regex: #{regex}")
131
131
  regex = nil
132
132
  end
133
133
  else
@@ -139,7 +139,7 @@ module Sqreen
139
139
 
140
140
  def initialize(params = {})
141
141
  @regex = params[:regex] || DEFAULT_REGEX
142
- @keys = params[:keys] || DEFAULT_SENSITIVE_KEYS
142
+ @keys = (params[:keys] || DEFAULT_SENSITIVE_KEYS).map(&:downcase)
143
143
  end
144
144
 
145
145
  def redact(obj)
@@ -122,7 +122,9 @@ module Sqreen
122
122
  def http_headers
123
123
  req = request
124
124
  return nil unless req
125
- req.env.select { |k, _| k.to_s.start_with?('HTTP_') }
125
+ # dup to avoid potential error because of change (in another thread)
126
+ # during iteration
127
+ req.env.dup.select { |k, _| k.to_s.start_with?('HTTP_') }
126
128
  end
127
129
 
128
130
  def hostname
@@ -111,6 +111,8 @@ module Sqreen
111
111
 
112
112
  ctx.add_code(@code_id, @code) unless ctx.has_code?(@code_id)
113
113
 
114
+ # mini_racer expects timeout to be in ms
115
+ ctx.timeout = budget ? budget * 1000.0 : nil
114
116
  begin
115
117
  ctx.call("sqreen_#{@code_id}_#{cb_name}", *arguments)
116
118
  rescue @module::ScriptTerminatedError
@@ -133,6 +135,7 @@ module Sqreen
133
135
  SqreenContext.class_eval do
134
136
  attr_accessor :gc_threshold_in_bytes
135
137
  attr_accessor :gc_load
138
+ attr_writer :timeout
136
139
 
137
140
  def has_code?(code_id)
138
141
  return false unless @code_ids
@@ -95,7 +95,7 @@ module Sqreen
95
95
 
96
96
  def call_callback(cb_name, budget, inst, cb_ba_args, args, rv = nil)
97
97
  arguments = cb_ba_args.map do |ba|
98
- ba.resolve(binding, framework, inst, args, @data, rv)
98
+ ba.resolve(binding, framework, inst, args, @data, rv)
99
99
  end
100
100
  arguments = @argument_filter.filter(cb_name, arguments)
101
101
 
@@ -1,5 +1,5 @@
1
1
  # Copyright (c) 2015 Sqreen. All Rights Reserved.
2
2
  # Please refer to our terms for more information: https://www.sqreen.io/terms.html
3
3
  module Sqreen
4
- VERSION = '1.16.1'.freeze
4
+ VERSION = '1.16.2'.freeze
5
5
  end
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.16.1
4
+ version: 1.16.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sqreen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-01-18 00:00:00.000000000 Z
11
+ date: 2019-02-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sq_mini_racer
@@ -96,7 +96,6 @@ files:
96
96
  - lib/sqreen/rules_callbacks/crawler_user_agent_matches_metrics.rb
97
97
  - lib/sqreen/rules_callbacks/custom_error.rb
98
98
  - lib/sqreen/rules_callbacks/execjs.rb
99
- - lib/sqreen/rules_callbacks/execjs_old.rb
100
99
  - lib/sqreen/rules_callbacks/headers_insert.rb
101
100
  - lib/sqreen/rules_callbacks/inspect_rule.rb
102
101
  - lib/sqreen/rules_callbacks/matcher_rule.rb
@@ -1,315 +0,0 @@
1
- # Copyright (c) 2015 Sqreen. All Rights Reserved.
2
- # Please refer to our terms for more information: https://www.sqreen.io/terms.html
3
-
4
- if defined?(::JRUBY_VERSION)
5
- require 'rhino'
6
- SQREEN_MINI_RACER = false
7
- else
8
- begin
9
- require 'mini_racer'
10
- SQREEN_MINI_RACER = true
11
- GC_MINI_RACER = 10_000
12
- rescue LoadError
13
- require 'therubyracer'
14
- SQREEN_MINI_RACER = false
15
- end
16
- end
17
-
18
- require 'weakref'
19
- require 'execjs'
20
-
21
- require 'sqreen/rule_attributes'
22
- require 'sqreen/rule_callback'
23
- require 'sqreen/condition_evaluator'
24
- require 'sqreen/binding_accessor'
25
- require 'sqreen/events/remote_exception'
26
-
27
- module Sqreen
28
- if SQREEN_MINI_RACER
29
- # Context specialized for Sqreen usage
30
- class SqreenContext < MiniRacer::Context
31
- def eval_unsafe(str, filename = nil, timeoutv = nil)
32
- # Beware, timeout could be kept in the context
33
- # if perf cap is removed after having been activated
34
- # As it's unused by execjscb we are not cleaning it
35
- return super(str, filename) if timeoutv.nil?
36
- return if timeoutv <= 0.0
37
- timeoutv *= 1000 # Timeout are currently expressed in seconds
38
- @timeout = timeoutv
39
- @eval_thread = Thread.current
40
- timeout do
41
- super(str, filename)
42
- end
43
- end
44
- end
45
-
46
- # Weak ref to a context
47
- # enables us to skip a method missing call
48
- class WeakCtx < WeakRef
49
- def initialize(*args)
50
- super(*args)
51
- end
52
-
53
- def eval_unsafe(str, filename, timeoutv)
54
- __getobj__.eval_unsafe(str, filename, timeoutv)
55
- end
56
- end
57
- end
58
- module Rules
59
- # Exec js callbacks
60
- class ExecJSCBOld < RuleCB
61
- attr_accessor :restrict_max_depth
62
- attr_reader :runtimes
63
- attr_accessor :recycle_runtime_every
64
-
65
- def initialize(klass, method, rule_hash)
66
- super(klass, method, rule_hash)
67
- callbacks = @rule[Attrs::CALLBACKS]
68
- @conditions = @rule.fetch(Attrs::CONDITIONS, {})
69
-
70
- if callbacks['pre'].nil? &&
71
- callbacks['post'].nil? &&
72
- callbacks['failing'].nil?
73
- raise(Sqreen::Exception, 'no JS CB provided')
74
- end
75
-
76
- build_runnable(callbacks)
77
- @restrict_max_depth = 20
78
- unless SQREEN_MINI_RACER
79
- @compiled = ExecJS.compile(@source)
80
- return
81
- end
82
- @recycle_runtime_every = GC_MINI_RACER
83
- @snapshot = MiniRacer::Snapshot.new(@source)
84
- @runtimes = []
85
- @key = "SQREEN_MINI_RACER_CONTEXT_#{object_id}".freeze
86
- end
87
-
88
- def pre?
89
- @js_pre
90
- end
91
-
92
- def post?
93
- @js_post
94
- end
95
-
96
- def failing?
97
- @js_failing
98
- end
99
-
100
- def pre(inst, args, budget = nil, &_block)
101
- return unless pre?
102
-
103
- call_callback('pre', inst, budget, args)
104
- end
105
-
106
- def post(rv, inst, args, budget = nil, &_block)
107
- return unless post?
108
-
109
- call_callback('post', inst, budget, args, rv)
110
- end
111
-
112
- def failing(rv, inst, args, budget = nil, &_block)
113
- return unless failing?
114
-
115
- call_callback('failing', inst, budget, args, rv)
116
- end
117
-
118
- def self.hash_val_included(needed, haystack, min_length = 8, max_depth = 20)
119
- new_obj = {}
120
- insert = []
121
- to_do = haystack.map { |k, v| [new_obj, k, v, 0] }
122
- until to_do.empty?
123
- where, key, value, deepness = to_do.pop
124
- safe_key = key.is_a?(Integer) ? key : key.to_s
125
- if value.is_a?(Hash) && deepness < max_depth
126
- val = {}
127
- insert << [where, safe_key, val]
128
- to_do += value.map { |k, v| [val, k, v, deepness + 1] }
129
- elsif value.is_a?(Array) && deepness < max_depth
130
- val = []
131
- insert << [where, safe_key, val]
132
- i = -1
133
- to_do += value.map { |v| [val, i += 1, v, deepness + 1] }
134
- elsif deepness >= max_depth # if we are after max_depth don't try to filter
135
- insert << [where, safe_key, value]
136
- else
137
- v = value.to_s
138
- if v.size >= min_length && ConditionEvaluator.str_include?(needed.to_s, v)
139
- case where
140
- when Array
141
- where << value
142
- else
143
- where[safe_key] = value
144
- end
145
- end
146
- end
147
- end
148
- insert.reverse.each do |wh, ikey, ival|
149
- case wh
150
- when Array
151
- wh << ival unless ival.respond_to?(:empty?) && ival.empty?
152
- else
153
- wh[ikey] = ival unless ival.respond_to?(:empty?) && ival.empty?
154
- end
155
- end
156
- new_obj
157
- end
158
-
159
- protected
160
-
161
- def record_and_continue?(ret)
162
- case ret
163
- when NilClass
164
- false
165
- when Hash
166
- ret.keys.each do |k|
167
- ret[(begin
168
- k.to_sym
169
- rescue StandardError
170
- k
171
- end)] = ret[k] end
172
- record_event(ret[:record]) unless ret[:record].nil?
173
- unless ret['observations'].nil?
174
- ret['observations'].each do |obs|
175
- obs[3] = Time.parse(obs[3]) if obs.size >= 3 && obs[3].is_a?(String)
176
- record_observation(*obs)
177
- end
178
- end
179
- !ret[:call].nil?
180
- else
181
- raise Sqreen::Exception, "Invalid return type #{ret.inspect}"
182
- end
183
- end
184
-
185
- def push_runtime(runtime)
186
- @runtimes.delete_if do |th, runt, _thid|
187
- del = th.nil? || !th.weakref_alive? || !th.alive?
188
- runt.dispose if del
189
- del
190
- end
191
- @runtimes.push [WeakRef.new(Thread.current), runtime, Thread.current.object_id]
192
- end
193
-
194
- def dispose_runtime(runtime)
195
- @runtimes.delete_if { |_th, _runt, thid| thid == Thread.current.object_id }
196
- runtime.dispose
197
- end
198
-
199
- def call_callback(name, inst, budget, args, rv = nil)
200
- mini_racer_context = nil
201
- if SQREEN_MINI_RACER
202
- mini_racer_context = Thread.current[@key]
203
- dead_runtime = !mini_racer_context || !mini_racer_context[:r] || !mini_racer_context[:r].weakref_alive?
204
- if !dead_runtime && mini_racer_context[:c] >= @recycle_runtime_every
205
- dispose_runtime(mini_racer_context[:r])
206
- dead_runtime = true
207
- end
208
- if dead_runtime
209
- new_runtime = SqreenContext.new(:snapshot => @snapshot)
210
- push_runtime new_runtime
211
- mini_racer_context = {
212
- :c => 0,
213
- :r => WeakCtx.new(new_runtime),
214
- }
215
- Thread.current[@key] = mini_racer_context
216
- end
217
- end
218
- ret = nil
219
- args_override = nil
220
- arguments = nil
221
- while true
222
- arguments = (args_override || @argument_requirements[name]).map do |accessor|
223
- accessor.resolve(binding, framework, inst, args, @data, rv)
224
- end
225
- arguments = restrict(name, arguments) if @conditions.key?(name)
226
- Sqreen.log.debug { [name, arguments].inspect }
227
- if SQREEN_MINI_RACER
228
- mini_racer_context[:c] += 1
229
- begin
230
- ret = mini_racer_context[:r].eval_unsafe("#{name}.apply(this, #{::JSON.generate(arguments)})", nil, budget)
231
- rescue MiniRacer::ScriptTerminatedError
232
- ret = nil
233
- end
234
- else
235
- ret = @compiled.call(name, *arguments)
236
- end
237
- unless record_and_continue?(ret)
238
- return nil if ret.nil?
239
- return advise_action(ret[:status], ret)
240
- end
241
- name = ret[:call]
242
- rv = ret[:data]
243
- args_override = ret[:args]
244
- args_override = build_accessor(args_override) if args_override
245
- end
246
- rescue StandardError => e
247
- Sqreen.log.warn { "we catch a JScb exception: #{e.inspect}" }
248
- Sqreen.log.debug e.backtrace
249
- record_exception(e, :cb => name, :args => arguments)
250
- nil
251
- end
252
-
253
- def each_hash_val_include(condition, depth = 10)
254
- return if depth <= 0
255
- condition.each do |key, values|
256
- if key == ConditionEvaluator::HASH_INC_OPERATOR
257
- yield values
258
- else
259
- values.map do |v|
260
- each_hash_val_include(v, depth - 1) { |vals| yield vals } if v.is_a?(Hash)
261
- end
262
- end
263
- end
264
- end
265
-
266
- def restrict(cbname, arguments)
267
- condition = @conditions[cbname]
268
- return arguments if condition.nil? || @argument_requirements[cbname].nil?
269
-
270
- each_hash_val_include(condition) do |needle, haystack, min_length|
271
- # We could actually run the binding accessor expression here.
272
- needed_idx = @argument_requirements[cbname].map(&:expression).index(needle)
273
- next unless needed_idx
274
-
275
- haystack_idx = @argument_requirements[cbname].map(&:expression).index(haystack)
276
- next unless haystack_idx
277
-
278
- arguments[haystack_idx] = ExecJSCB.hash_val_included(
279
- arguments[needed_idx],
280
- arguments[haystack_idx],
281
- min_length.to_i,
282
- @restrict_max_depth
283
- )
284
- end
285
-
286
- arguments
287
- end
288
-
289
- def build_accessor(reqs)
290
- reqs.map do |req|
291
- BindingAccessor.new(req, true)
292
- end
293
- end
294
-
295
- def build_runnable(callbacks)
296
- @argument_requirements = {}
297
- @source = ''
298
- @js_pre = !callbacks['pre'].nil?
299
- @js_post = !callbacks['post'].nil?
300
- @js_failing = !callbacks['failing'].nil?
301
- callbacks.each do |name, args_or_func|
302
- @source << "var #{name} = "
303
- if args_or_func.is_a?(Array)
304
- @source << args_or_func.pop
305
- @argument_requirements[name] = build_accessor(args_or_func)
306
- else
307
- @source << args_or_func
308
- @argument_requirements[name] = []
309
- end
310
- @source << ";\n"
311
- end
312
- end
313
- end
314
- end
315
- end