immunio 1.1.18 → 1.1.19
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/immunio/context.rb +7 -4
- data/lib/immunio/plugins/action_dispatch.rb +7 -3
- data/lib/immunio/plugins/action_view.rb +129 -52
- data/lib/immunio/plugins/active_record.rb +51 -25
- data/lib/immunio/plugins/active_record_relation.rb +89 -35
- data/lib/immunio/plugins/csrf.rb +21 -9
- data/lib/immunio/plugins/redirect.rb +3 -1
- data/lib/immunio/processor.rb +1 -1
- data/lib/immunio/version.rb +1 -1
- metadata +3 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f0cf95fe27e81261056bdc9388cb78021e3f3e33
|
4
|
+
data.tar.gz: 91d07872cd32dbc236299020a62337c1296691ce
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c4d6a75b2a7d974ccd9cfc3e3e7c6744f72330ae6f4f23c926021ba002635a4bf807b32e8b15be17c39a70d3cba90a4f4da67c4ab003c70b466e7240b152e9e8
|
7
|
+
data.tar.gz: fd8e3009626ddbb2a97b1b72ce542f37f5df6d6b7f59f291738de125ec6c8ee312926791dbcf5eda634198a718ca6f107a0daf1f5e771322c23d054950f0d13a
|
data/lib/immunio/context.rb
CHANGED
@@ -19,8 +19,12 @@ module Immunio
|
|
19
19
|
# Calculate context hashes and a stack trace. Additional data, in the form
|
20
20
|
# of a String, may be provided to mix into the strict context hash.
|
21
21
|
def self.context(additional_data=nil)
|
22
|
-
#
|
23
|
-
|
22
|
+
# Filter out agent stack frames. This includes string class_evals in `io`.
|
23
|
+
filtered_stack_frames = caller.reject do |frame|
|
24
|
+
frame =~ /lib\/immunio|^\(eval\):\d+:.+`.+_with_immunio'$/
|
25
|
+
end
|
26
|
+
|
27
|
+
stack = filtered_stack_frames.join "\n"
|
24
28
|
|
25
29
|
cache_key = Digest::SHA1.hexdigest stack
|
26
30
|
|
@@ -38,13 +42,12 @@ module Immunio
|
|
38
42
|
|
39
43
|
# drop the top frame as it's us, but retain the rest. Immunio frames
|
40
44
|
# are filtered by the Gem regex.
|
41
|
-
locations =
|
45
|
+
locations = filtered_stack_frames.map do |frame|
|
42
46
|
frame = frame.split(":", 3)
|
43
47
|
{ path: frame[0], line: frame[1], label: frame[2] }
|
44
48
|
end
|
45
49
|
|
46
50
|
locations.each do |frame|
|
47
|
-
|
48
51
|
# Filter frame names from template rendering to remove generated random bits
|
49
52
|
template_match = RAILS_TEMPLATE_FILTER.match(frame[:label])
|
50
53
|
frame[:label] = template_match[1] + template_match[3] if template_match
|
@@ -10,12 +10,12 @@ module Immunio
|
|
10
10
|
alias_method :lookup_without_immunio, :[]
|
11
11
|
alias_method :[], :lookup_with_immunio
|
12
12
|
end
|
13
|
-
|
14
13
|
end
|
15
14
|
|
16
15
|
def lookup_with_immunio(name)
|
17
16
|
Request.time "plugin", "#{Module.nesting[0]}::#{__method__}" do
|
18
|
-
|
17
|
+
cookie_name = (Rails::VERSION::MAJOR > 4) ? name.to_s : name
|
18
|
+
raw_cookie_value = @parent_jar[cookie_name]
|
19
19
|
|
20
20
|
cookie_value = Request.pause(
|
21
21
|
'plugin',
|
@@ -27,7 +27,7 @@ module Immunio
|
|
27
27
|
Immunio.run_hook!(
|
28
28
|
'action_dispatch',
|
29
29
|
'bad_cookie',
|
30
|
-
key:
|
30
|
+
key: cookie_name,
|
31
31
|
value: raw_cookie_value)
|
32
32
|
end
|
33
33
|
|
@@ -135,6 +135,10 @@ Immunio::Plugin.load(
|
|
135
135
|
if defined? UpgradeLegacyEncryptedCookieJar
|
136
136
|
UpgradeLegacyEncryptedCookieJar.send :include, Immunio::CookieHooks
|
137
137
|
end
|
138
|
+
|
139
|
+
if defined? PermanentCookieJar
|
140
|
+
PermanentCookieJar.send :include, Immunio::CookieHooks
|
141
|
+
end
|
138
142
|
end
|
139
143
|
|
140
144
|
plugin.loaded! ActionPack::VERSION::STRING
|
@@ -30,7 +30,8 @@ module Immunio
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def id
|
33
|
-
(@template.respond_to?(:virtual_path) && @template.virtual_path) ||
|
33
|
+
(@template.respond_to?(:virtual_path) && @template.virtual_path) ||
|
34
|
+
(@template.respond_to?(:source) && @template.source)
|
34
35
|
end
|
35
36
|
|
36
37
|
def ==(other)
|
@@ -146,7 +147,8 @@ module Immunio
|
|
146
147
|
content = "" if content.nil?
|
147
148
|
|
148
149
|
# See comment above
|
149
|
-
if content
|
150
|
+
if (content.respond_to? :=~) &&
|
151
|
+
(content =~ /\{immunio-var:\d+:#{nonce}\}/)
|
150
152
|
# don't add markers.
|
151
153
|
Immunio.logger.debug {"WARNING: ActionView not marking interpolation which already contains markers: \"#{content}\""}
|
152
154
|
return content.html_safe
|
@@ -349,61 +351,68 @@ module Immunio
|
|
349
351
|
end
|
350
352
|
|
351
353
|
private
|
352
|
-
def rendering_stack
|
353
|
-
self.class.rendering_stack
|
354
|
-
end
|
355
354
|
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
name: (@template.respond_to?(:virtual_path) && @template.virtual_path) || nil,
|
360
|
-
origin: @template.identifier,
|
361
|
-
nonce: Template.get_nonce
|
362
|
-
}
|
363
|
-
Immunio.run_hook! "action_view", name, default_meta.merge(meta)
|
364
|
-
end
|
355
|
+
def rendering_stack
|
356
|
+
self.class.rendering_stack
|
357
|
+
end
|
365
358
|
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
return
|
376
|
-
end
|
359
|
+
def run_hook!(name, meta={})
|
360
|
+
default_meta = {
|
361
|
+
template_sha: template_sha,
|
362
|
+
name: (@template.respond_to?(:virtual_path) && @template.virtual_path) || nil,
|
363
|
+
origin: @template.identifier,
|
364
|
+
nonce: Template.get_nonce
|
365
|
+
}
|
366
|
+
Immunio.run_hook! "action_view", name, default_meta.merge(meta)
|
367
|
+
end
|
377
368
|
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
controller.write_fragment_without_immunio key, output, options
|
387
|
-
output
|
388
|
-
end
|
389
|
-
end
|
390
|
-
# To be extra safe strip all markers from content
|
369
|
+
def write_and_remove_fragments!(context, content)
|
370
|
+
# Rails tests do use the context as the view context sometimes.
|
371
|
+
if context.is_a? ActionController::Base
|
372
|
+
controller = context
|
373
|
+
elsif context.respond_to? :controller
|
374
|
+
controller = context.controller
|
375
|
+
else
|
376
|
+
# Some rails unit tests don't have a controller...
|
391
377
|
remove_all_markers! content
|
378
|
+
return
|
392
379
|
end
|
393
380
|
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
381
|
+
# Iterate to handle nested fragments. Child fragments have lower ids than their parents.
|
382
|
+
nonce = Template.get_nonce
|
383
|
+
@scheduled_fragments_writes.each_with_index do |(key, _, options), id|
|
384
|
+
# Remove the markers ...
|
385
|
+
content.sub!(/\{immunio-fragment:#{id}:#{nonce}\}(.*)\{\/immunio-fragment:#{id}:#{nonce}\}/m) do
|
386
|
+
# The escaped content inside the markers ($1), is written to cache.
|
387
|
+
output = $1
|
388
|
+
remove_all_markers! output
|
389
|
+
controller.write_fragment_without_immunio key, output, options
|
390
|
+
output
|
391
|
+
end
|
398
392
|
end
|
393
|
+
# To be extra safe strip all markers from content
|
394
|
+
remove_all_markers! content
|
395
|
+
end
|
399
396
|
|
397
|
+
def remove_var_markers!(input)
|
398
|
+
nonce = Template.get_nonce
|
399
|
+
# TODO is this the fastest way to remove the markers? Needs benchmarking ...
|
400
|
+
input.gsub!(/\{\/?immunio-var:\d+:#{nonce}\}/, "")
|
401
|
+
end
|
402
|
+
|
403
|
+
def remove_all_markers!(input)
|
404
|
+
self.class.remove_all_markers!(input)
|
405
|
+
end
|
406
|
+
|
407
|
+
class << self
|
400
408
|
def remove_all_markers!(input)
|
401
409
|
input.gsub!(/\{\/?immunio-(fragment|var):\d+:[a-zA-Z0-9]+\}/, "")
|
402
410
|
end
|
411
|
+
end
|
403
412
|
end
|
404
413
|
|
405
414
|
# Hooks for the ERB template engine.
|
406
|
-
# (Default one used in Rails).
|
415
|
+
# (Default one used in Rails < 5).
|
407
416
|
module ErubisHooks
|
408
417
|
extend ActiveSupport::Concern
|
409
418
|
|
@@ -428,6 +437,30 @@ module Immunio
|
|
428
437
|
end
|
429
438
|
end
|
430
439
|
|
440
|
+
module ErubiHooks
|
441
|
+
extend ActiveSupport::Concern
|
442
|
+
|
443
|
+
included do
|
444
|
+
Immunio::Utils.alias_method_chain self, :add_expression, :immunio
|
445
|
+
end
|
446
|
+
|
447
|
+
def add_expression_with_immunio(indicator, code)
|
448
|
+
# Wrap expressions in the templates to track their rendered value.
|
449
|
+
# Do not wrap expressions with blocks, eg.: <%= form_tag do %>
|
450
|
+
# TODO should we support blocks?
|
451
|
+
Request.time "plugin", "#{Module.nesting[0]}::#{__method__}" do
|
452
|
+
unless code =~ ActionView::Template::Handlers::ERB::Erubi::BLOCK_EXPR
|
453
|
+
# escape unless we see the == indicator
|
454
|
+
escape = !(indicator == '==')
|
455
|
+
code = Immunio::Template.generate_render_var_code(code, escape)
|
456
|
+
end
|
457
|
+
Request.pause "plugin", "#{Module.nesting[0]}::#{__method__}" do
|
458
|
+
add_expression_without_immunio(indicator, code)
|
459
|
+
end
|
460
|
+
end
|
461
|
+
end
|
462
|
+
end
|
463
|
+
|
431
464
|
# Hooks for the HAML template engine.
|
432
465
|
module HamlHooks
|
433
466
|
extend ActiveSupport::Concern
|
@@ -439,7 +472,13 @@ module Immunio
|
|
439
472
|
def push_script_with_immunio(code, opts = {}, &block)
|
440
473
|
# Wrap expressions in the templates to track their rendered value.
|
441
474
|
Request.time "plugin", "#{Module.nesting[0]}::#{__method__}" do
|
442
|
-
|
475
|
+
block_expr = if Rails::VERSION::MAJOR == 5 && Rails::VERSION::MINOR > 0
|
476
|
+
ActionView::Template::Handlers::ERB::Erubi::BLOCK_EXPR
|
477
|
+
else
|
478
|
+
ActionView::Template::Handlers::Erubis::BLOCK_EXPR
|
479
|
+
end
|
480
|
+
|
481
|
+
if code !~ block_expr
|
443
482
|
# escape if we're told to by HAML
|
444
483
|
code = Immunio::Template.generate_render_var_code(code, opts[:escape_html])
|
445
484
|
end
|
@@ -519,6 +558,29 @@ module Immunio
|
|
519
558
|
end
|
520
559
|
end
|
521
560
|
|
561
|
+
module CacheStoreHooks
|
562
|
+
extend ActiveSupport::Concern
|
563
|
+
|
564
|
+
included do
|
565
|
+
Immunio::Utils.alias_method_chain self, :write, :immunio
|
566
|
+
end
|
567
|
+
|
568
|
+
# Rails 5 adds CollectionCaching. When used in the context of
|
569
|
+
# rendering a collection of items with a partial template, we
|
570
|
+
# need to remove our markers before writing to the cache store.
|
571
|
+
# See this blog post for more:
|
572
|
+
# http://blog.bigbinary.com/2016/03/09/rails-5-makes-partial-redering-from-cache-substantially-faster.html
|
573
|
+
def write_with_immunio(name, value, options = nil)
|
574
|
+
Request.time "plugin", "#{Module.nesting[0]}::#{__method__}" do
|
575
|
+
Template.remove_all_markers! value if value.is_a? String
|
576
|
+
|
577
|
+
Request.pause "plugin", "#{Module.nesting[0]}::#{__method__}" do
|
578
|
+
write_without_immunio(name, value, options)
|
579
|
+
end
|
580
|
+
end
|
581
|
+
end
|
582
|
+
end
|
583
|
+
|
522
584
|
# Hook for the `ActiveSupport::Hash#to_query`.
|
523
585
|
# Use case: building a url within a decorator that renders a partial with an interpolation.
|
524
586
|
module ActiveSupportHooks
|
@@ -539,18 +601,32 @@ module Immunio
|
|
539
601
|
escaped_string
|
540
602
|
end
|
541
603
|
end
|
604
|
+
|
605
|
+
XSS_HOOKS = %w[template_render_done template_render_var]
|
542
606
|
end
|
543
607
|
|
544
608
|
# Load the plugins
|
545
609
|
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
610
|
+
if Rails::VERSION::MAJOR == 5 && Rails::VERSION::MINOR > 0
|
611
|
+
Immunio::Plugin.load(
|
612
|
+
'Erubi',
|
613
|
+
feature: 'xss',
|
614
|
+
hooks: Immunio::XSS_HOOKS) do |plugin|
|
550
615
|
|
551
|
-
|
616
|
+
ActionView::Template::Handlers::ERB::Erubi.send :include, Immunio::ErubiHooks
|
552
617
|
|
553
|
-
|
618
|
+
plugin.loaded! Rails.version
|
619
|
+
end
|
620
|
+
else
|
621
|
+
Immunio::Plugin.load(
|
622
|
+
'Erubis',
|
623
|
+
feature: 'xss',
|
624
|
+
hooks: Immunio::XSS_HOOKS) do |plugin|
|
625
|
+
|
626
|
+
ActionView::Template::Handlers::Erubis.send :include, Immunio::ErubisHooks
|
627
|
+
|
628
|
+
plugin.loaded! Rails.version
|
629
|
+
end
|
554
630
|
end
|
555
631
|
|
556
632
|
ActiveSupport.on_load(:after_initialize) do
|
@@ -558,7 +634,7 @@ ActiveSupport.on_load(:after_initialize) do
|
|
558
634
|
Immunio::Plugin.load(
|
559
635
|
'Haml',
|
560
636
|
feature: 'xss',
|
561
|
-
hooks:
|
637
|
+
hooks: Immunio::XSS_HOOKS) do |plugin|
|
562
638
|
|
563
639
|
if defined? Haml::Compiler
|
564
640
|
Haml::Compiler.send :include, Immunio::HamlHooks
|
@@ -574,7 +650,7 @@ end
|
|
574
650
|
Immunio::Plugin.load(
|
575
651
|
'ActionView',
|
576
652
|
feature: 'xss',
|
577
|
-
hooks:
|
653
|
+
hooks: Immunio::XSS_HOOKS) do |plugin|
|
578
654
|
|
579
655
|
ActionView::TemplateRenderer.send :include, Immunio::TemplateRendererHooks
|
580
656
|
ActionView::Template.send :include, Immunio::TemplateHooks
|
@@ -585,6 +661,7 @@ Immunio::Plugin.load(
|
|
585
661
|
Immunio::FragmentCachingHooks)
|
586
662
|
else
|
587
663
|
AbstractController::Caching.send(:include, Immunio::FragmentCachingHooks)
|
664
|
+
ActiveSupport::Cache::Store.send(:include, Immunio::CacheStoreHooks)
|
588
665
|
end
|
589
666
|
|
590
667
|
plugin.loaded! Rails.version
|
@@ -15,21 +15,37 @@ module Immunio
|
|
15
15
|
|
16
16
|
IGNORED_TYPES = [TrueClass, FalseClass, NilClass, Fixnum, Bignum, Float].freeze
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
18
|
+
if Rails::VERSION::MAJOR == 5 && Rails::VERSION::MINOR > 0
|
19
|
+
# Passing a column to `quote` has been deprecated in 5.0.
|
20
|
+
def quote_with_immunio(value)
|
21
|
+
Request.time "plugin", "#{Module.nesting[0]}::#{__method__}" do
|
22
|
+
# Ignored empty strings and values that can't contain injections.
|
23
|
+
unless value.blank? || IGNORED_TYPES.include?(value.class)
|
24
|
+
QueryTracker.instance.add_param nil, value.to_s, object_id
|
25
|
+
end
|
25
26
|
|
26
|
-
|
27
|
-
|
28
|
-
|
27
|
+
Request.pause "plugin", "#{Module.nesting[0]}::#{__method__}" do
|
28
|
+
quote_without_immunio(value)
|
29
|
+
end
|
29
30
|
end
|
31
|
+
end
|
32
|
+
else
|
33
|
+
def quote_with_immunio(value, column = nil)
|
34
|
+
Request.time "plugin", "#{Module.nesting[0]}::#{__method__}" do
|
35
|
+
if column
|
36
|
+
column_name = column.name
|
37
|
+
else
|
38
|
+
column_name = nil
|
39
|
+
end
|
40
|
+
|
41
|
+
# Ignored empty strings and values that can't contain injections.
|
42
|
+
unless value.blank? || IGNORED_TYPES.include?(value.class)
|
43
|
+
QueryTracker.instance.add_param column_name, value.to_s, object_id
|
44
|
+
end
|
30
45
|
|
31
|
-
|
32
|
-
|
46
|
+
Request.pause "plugin", "#{Module.nesting[0]}::#{__method__}" do
|
47
|
+
quote_without_immunio(value, column)
|
48
|
+
end
|
33
49
|
end
|
34
50
|
end
|
35
51
|
end
|
@@ -629,21 +645,26 @@ module Immunio
|
|
629
645
|
# When using the activerecord-sqlserver-adapter gem, the "column" is
|
630
646
|
# the actual param name.
|
631
647
|
name = column.respond_to?(:name) ? column.name : column.to_s
|
632
|
-
|
648
|
+
|
649
|
+
# Some AR tests (sqlite3 in particular) initialize a QueryAttribute
|
650
|
+
# with a nil `name`. This guards againt passing a nil key to Lua.
|
651
|
+
params[name] = value.to_s if name
|
633
652
|
end
|
634
653
|
end
|
635
654
|
|
636
655
|
strict_context, loose_context, stack = Immunio::Context.context context_data
|
637
656
|
|
638
657
|
# Send in additional_context_data for debugging purposes
|
639
|
-
Immunio.run_hook! "active_record",
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
|
658
|
+
Immunio.run_hook! "active_record",
|
659
|
+
"sql_execute",
|
660
|
+
sql: payload[:sql],
|
661
|
+
connection_uuid: connection_id.to_s,
|
662
|
+
params: params,
|
663
|
+
modifiers: modifiers,
|
664
|
+
context_key: strict_context,
|
665
|
+
loose_context_key: loose_context,
|
666
|
+
stack: stack,
|
667
|
+
additional_context_data: context_data
|
647
668
|
|
648
669
|
reset relation_id
|
649
670
|
end
|
@@ -673,13 +694,18 @@ module Immunio
|
|
673
694
|
extend ActiveSupport::Concern
|
674
695
|
|
675
696
|
included do
|
676
|
-
|
697
|
+
# As of Rails 5.1, :log is now private
|
698
|
+
if method_defined?(:log) || private_instance_methods.include?(:log)
|
699
|
+
Immunio::Utils.alias_method_chain self, :log, :immunio
|
700
|
+
end
|
677
701
|
end
|
678
702
|
|
679
703
|
def log_with_immunio(sql, name = "SQL", binds = [], *args)
|
680
|
-
|
681
|
-
|
682
|
-
|
704
|
+
# Some rails tests (in particular postresql) call :log with nil `sql`.
|
705
|
+
QueryTracker.instance.call(
|
706
|
+
sql: sql,
|
707
|
+
connection_id: object_id,
|
708
|
+
binds: binds) if sql
|
683
709
|
|
684
710
|
# Log and execute the query
|
685
711
|
log_without_immunio(sql, name, binds, *args) { yield }
|
@@ -211,6 +211,9 @@ module Immunio
|
|
211
211
|
:where!,
|
212
212
|
:build_where
|
213
213
|
]
|
214
|
+
|
215
|
+
# Prevent infinite recursion!
|
216
|
+
self.methods_to_wrap.delete :merge
|
214
217
|
end
|
215
218
|
|
216
219
|
self.methods_to_wrap.each do |method|
|
@@ -267,13 +270,13 @@ module Immunio
|
|
267
270
|
|
268
271
|
# When a statement is executed, push the original relation onto the
|
269
272
|
# connection relation stack.
|
270
|
-
def execute_with_immunio(*args)
|
273
|
+
def execute_with_immunio(*args, &block)
|
271
274
|
Request.time "plugin", "Immunio::RelationTracking" do
|
272
275
|
QueryTracker.instance.push_relation @__immunio_relation
|
273
276
|
end
|
274
277
|
|
275
278
|
begin
|
276
|
-
execute_without_immunio(*args)
|
279
|
+
execute_without_immunio(*args, &block)
|
277
280
|
ensure
|
278
281
|
Request.time "plugin", "Immunio::RelationTracking" do
|
279
282
|
QueryTracker.instance.pop_relation @__immunio_relation
|
@@ -300,60 +303,111 @@ module Immunio
|
|
300
303
|
module HasManyThroughAssociationHooks
|
301
304
|
extend ActiveSupport::Concern
|
302
305
|
|
303
|
-
|
306
|
+
private
|
307
|
+
|
304
308
|
# One off, non-ActiveRecord::Relation method that under one condition
|
305
309
|
# executes a query in Rails 4.1 and up. Unfortunately, wrapping won't work
|
306
310
|
# as the relation used to generate the query is a temporary relation that is
|
307
311
|
# created in the method. The easiest way to deal with it, though very hacky,
|
308
312
|
# is to copy the method from upstream Rails and push the temporary relation
|
309
313
|
# onto the stack for the connection right before the query is executed.
|
310
|
-
|
311
|
-
|
314
|
+
if Rails::VERSION::MAJOR == 4 && Rails::VERSION::MINOR >= 1
|
315
|
+
def delete_records_with_immunio(records, method, *args)
|
316
|
+
scope = through_association.scope
|
312
317
|
|
313
|
-
|
314
|
-
|
315
|
-
|
318
|
+
unless method == :destroy && !scope.klass.primary_key
|
319
|
+
return delete_records_without_immunio(records, method, *args)
|
320
|
+
end
|
316
321
|
|
317
|
-
|
318
|
-
|
319
|
-
|
322
|
+
# From here on down, copied from upstream Rails 4.2. Verified to work on
|
323
|
+
# Rails 4.1, too.
|
324
|
+
ensure_not_nested
|
320
325
|
|
321
|
-
|
326
|
+
scope.where! construct_join_attributes(*records)
|
322
327
|
|
323
|
-
|
324
|
-
|
325
|
-
|
328
|
+
scope.each do |record|
|
329
|
+
record.run_callbacks :destroy
|
330
|
+
end
|
326
331
|
|
327
|
-
|
332
|
+
arel = scope.arel
|
328
333
|
|
329
|
-
|
330
|
-
|
331
|
-
|
334
|
+
stmt = Arel::DeleteManager.new arel.engine
|
335
|
+
stmt.from scope.klass.arel_table
|
336
|
+
stmt.wheres = arel.constraints
|
332
337
|
|
333
|
-
|
334
|
-
|
338
|
+
Request.time "plugin", "Immunio::RelationTracking" do
|
339
|
+
QueryTracker.instance.push_relation scope
|
340
|
+
end
|
341
|
+
|
342
|
+
begin
|
343
|
+
count = scope.klass.connection.delete(stmt, 'SQL', scope.bind_values)
|
344
|
+
ensure
|
345
|
+
Request.time "plugin", "Immunio::RelationTracking" do
|
346
|
+
QueryTracker.instance.pop_relation scope
|
347
|
+
end
|
348
|
+
end
|
349
|
+
|
350
|
+
delete_through_records(records)
|
351
|
+
|
352
|
+
if source_reflection.options[:counter_cache] && method != :destroy
|
353
|
+
counter = source_reflection.counter_cache_column
|
354
|
+
klass.decrement_counter counter, records.map(&:id)
|
355
|
+
end
|
356
|
+
|
357
|
+
if through_reflection.collection? && update_through_counter?(method)
|
358
|
+
update_counter(-count, through_reflection)
|
359
|
+
end
|
360
|
+
|
361
|
+
update_counter(-count)
|
335
362
|
end
|
363
|
+
end
|
364
|
+
|
365
|
+
if Rails::VERSION::MAJOR == 5
|
366
|
+
def delete_records_with_immunio(records, method)
|
367
|
+
scope = through_association.scope
|
368
|
+
|
369
|
+
unless method == :destroy && !scope.klass.primary_key
|
370
|
+
return delete_records_without_immunio(records, method)
|
371
|
+
end
|
372
|
+
|
373
|
+
# From here on down, copied from upstream Rails 5.1.
|
374
|
+
ensure_not_nested
|
375
|
+
|
376
|
+
scope.where! construct_join_attributes(*records)
|
377
|
+
|
378
|
+
scope.each(&:_run_destroy_callbacks)
|
379
|
+
|
380
|
+
arel = scope.arel
|
381
|
+
|
382
|
+
stmt = Arel::DeleteManager.new
|
383
|
+
stmt.from scope.klass.arel_table
|
384
|
+
stmt.wheres = arel.constraints
|
336
385
|
|
337
|
-
begin
|
338
|
-
count = scope.klass.connection.delete(stmt, 'SQL', scope.bind_values)
|
339
|
-
ensure
|
340
386
|
Request.time "plugin", "Immunio::RelationTracking" do
|
341
|
-
QueryTracker.instance.
|
387
|
+
QueryTracker.instance.push_relation scope
|
342
388
|
end
|
343
|
-
end
|
344
389
|
|
345
|
-
|
390
|
+
begin
|
391
|
+
count = scope.klass.connection.delete(stmt, "SQL", scope.bound_attributes)
|
392
|
+
ensure
|
393
|
+
Request.time "plugin", "Immunio::RelationTracking" do
|
394
|
+
QueryTracker.instance.pop_relation scope
|
395
|
+
end
|
396
|
+
end
|
346
397
|
|
347
|
-
|
348
|
-
counter = source_reflection.counter_cache_column
|
349
|
-
klass.decrement_counter counter, records.map(&:id)
|
350
|
-
end
|
398
|
+
delete_through_records(records)
|
351
399
|
|
352
|
-
|
353
|
-
|
354
|
-
|
400
|
+
if source_reflection.options[:counter_cache] && method != :destroy
|
401
|
+
counter = source_reflection.counter_cache_column
|
402
|
+
klass.decrement_counter counter, records.map(&:id)
|
403
|
+
end
|
355
404
|
|
356
|
-
|
405
|
+
if through_reflection.collection? && update_through_counter?(method)
|
406
|
+
update_counter(-count, through_reflection)
|
407
|
+
else
|
408
|
+
update_counter(-count)
|
409
|
+
end
|
410
|
+
end
|
357
411
|
end
|
358
412
|
|
359
413
|
included do
|
data/lib/immunio/plugins/csrf.rb
CHANGED
@@ -3,23 +3,35 @@ module Immunio
|
|
3
3
|
extend ActiveSupport::Concern
|
4
4
|
|
5
5
|
included do
|
6
|
-
|
7
|
-
|
6
|
+
# As of Rails 5.1, :verify_authenticity_token is now private
|
7
|
+
if method_defined?(:verify_authenticity_token) ||
|
8
|
+
private_instance_methods.include?(:verify_authenticity_token)
|
9
|
+
|
10
|
+
Immunio::Utils.alias_method_chain(
|
11
|
+
self,
|
12
|
+
:verify_authenticity_token,
|
13
|
+
:immunio
|
14
|
+
)
|
8
15
|
end
|
9
16
|
end
|
10
17
|
|
11
18
|
protected
|
12
|
-
def verify_authenticity_token_with_immunio
|
13
|
-
Request.time "plugin", "#{Module.nesting[0]}::#{__method__}" do
|
14
|
-
Immunio.logger.debug { "ActiveSupport checking CSRF token" }
|
15
19
|
|
16
|
-
|
20
|
+
def verify_authenticity_token_with_immunio
|
21
|
+
Request.time "plugin", "#{Module.nesting[0]}::#{__method__}" do
|
22
|
+
Immunio.logger.debug { "ActiveSupport checking CSRF token" }
|
23
|
+
|
24
|
+
Immunio.run_hook!(
|
25
|
+
"csrf",
|
26
|
+
"framework_csrf_check",
|
27
|
+
valid: verified_request?
|
28
|
+
)
|
17
29
|
|
18
|
-
|
19
|
-
|
20
|
-
end
|
30
|
+
Request.pause "plugin", "#{Module.nesting[0]}::#{__method__}" do
|
31
|
+
verify_authenticity_token_without_immunio
|
21
32
|
end
|
22
33
|
end
|
34
|
+
end
|
23
35
|
end
|
24
36
|
end
|
25
37
|
|
@@ -5,7 +5,9 @@ module Immunio
|
|
5
5
|
extend ActiveSupport::Concern
|
6
6
|
|
7
7
|
included do
|
8
|
-
|
8
|
+
if method_defined? :redirect_to
|
9
|
+
Immunio::Utils.alias_method_chain self, :redirect_to, :immunio
|
10
|
+
end
|
9
11
|
end
|
10
12
|
|
11
13
|
protected
|
data/lib/immunio/processor.rb
CHANGED
@@ -135,7 +135,7 @@ module Immunio
|
|
135
135
|
def run_hook(plugin, hook, meta={})
|
136
136
|
request = Request.current
|
137
137
|
|
138
|
-
|
138
|
+
# Hooks called outside of a request are ignored since they are triggered while the framework is loaded.
|
139
139
|
return {} unless request
|
140
140
|
|
141
141
|
# Notify about the hook. This has no perf cost if there are no subscribers.
|
data/lib/immunio/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: immunio
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.19
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Immunio
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-07-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -464,9 +464,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
464
464
|
version: '0'
|
465
465
|
requirements: []
|
466
466
|
rubyforge_project:
|
467
|
-
rubygems_version: 2.6.
|
467
|
+
rubygems_version: 2.6.12
|
468
468
|
signing_key:
|
469
469
|
specification_version: 4
|
470
470
|
summary: Immunio Ruby agent
|
471
471
|
test_files: []
|
472
|
-
has_rdoc:
|