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 +4 -4
- data/lib/sqreen.rb +0 -1
- data/lib/sqreen/events/request_record.rb +2 -2
- data/lib/sqreen/frameworks/generic.rb +3 -1
- data/lib/sqreen/js/mini_racer_adapter.rb +3 -0
- data/lib/sqreen/rules_callbacks/execjs.rb +1 -1
- data/lib/sqreen/version.rb +1 -1
- metadata +2 -3
- data/lib/sqreen/rules_callbacks/execjs_old.rb +0 -315
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 424c794c9315a7e1a0544fd6be427194ec7d7155e665ba86c1c3413306078941
|
4
|
+
data.tar.gz: 815fa9b893dd2577360a0408cc44194879c9fb1bbe5074cdce6c8c8629e82704
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9bc336364648476b1e6a0b6a3955215646c008a418b35f39abacc1cee9fccd5bab9374e8e90b444bc2a1482eebc25ddf463526154479acca14acc7605e438bdf
|
7
|
+
data.tar.gz: 53433d834097073f8ec98dd4396243029fb55e60c675bb6da379d12090000cbb31be0a23e736a9cc70615dd5fe7991559cc4a3c3c884d02cbbe6e5c787e5b415
|
data/lib/sqreen.rb
CHANGED
@@ -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
|
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
|
-
|
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
|
-
|
98
|
+
ba.resolve(binding, framework, inst, args, @data, rv)
|
99
99
|
end
|
100
100
|
arguments = @argument_filter.filter(cb_name, arguments)
|
101
101
|
|
data/lib/sqreen/version.rb
CHANGED
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.
|
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-
|
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
|