immunio 1.1.18 → 1.1.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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:
|