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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6055543c258054ef2deee718998ada2e1ee72b22
4
- data.tar.gz: cd78217a6233a81e01126f5a15f523e89325150f
3
+ metadata.gz: f0cf95fe27e81261056bdc9388cb78021e3f3e33
4
+ data.tar.gz: 91d07872cd32dbc236299020a62337c1296691ce
5
5
  SHA512:
6
- metadata.gz: a361784ac3f389ebbfe6c9e5511ebf422ab171a54a28f72fc30eeb8efab108b63ddc78ea2e2b912358a7c876dcd79b7f390cea9e96bbb42db11881e1123961e3
7
- data.tar.gz: 3811d95d95a73a07e0635061a110a3564e043fab77bfc5cb76c895fb927f7f07def36e445441246143f1b4054d53e146cf4311002d929491db5099009c6b327c
6
+ metadata.gz: c4d6a75b2a7d974ccd9cfc3e3e7c6744f72330ae6f4f23c926021ba002635a4bf807b32e8b15be17c39a70d3cba90a4f4da67c4ab003c70b466e7240b152e9e8
7
+ data.tar.gz: fd8e3009626ddbb2a97b1b72ce542f37f5df6d6b7f59f291738de125ec6c8ee312926791dbcf5eda634198a718ca6f107a0daf1f5e771322c23d054950f0d13a
@@ -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
- # We can filter out at least the top two frames
23
- stack = caller(2).join "\n"
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 = caller(1).map do |frame|
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
- raw_cookie_value = @parent_jar[name]
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: name,
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) || (@template.respond_to?(:source) && @template.source)
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 =~ /\{immunio-var:\d+:#{nonce}\}/ then
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
- def run_hook!(name, meta={})
357
- default_meta = {
358
- template_sha: template_sha,
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
- def write_and_remove_fragments!(context, content)
367
- # Rails tests do use the context as the view context sometimes.
368
- if context.is_a? ActionController::Base
369
- controller = context
370
- elsif context.respond_to? :controller
371
- controller = context.controller
372
- else
373
- # Some rails unit tests don't have a controller...
374
- remove_all_markers! content
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
- # Iterate to handle nested fragments. Child fragments have lower ids than their parents.
379
- nonce = Template.get_nonce
380
- @scheduled_fragments_writes.each_with_index do |(key, _, options), id|
381
- # Remove the markers ...
382
- content.sub!(/\{immunio-fragment:#{id}:#{nonce}\}(.*)\{\/immunio-fragment:#{id}:#{nonce}\}/m) do
383
- # The escaped content inside the markers ($1), is written to cache.
384
- output = $1
385
- remove_all_markers! output
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
- def remove_var_markers!(input)
395
- nonce = Template.get_nonce
396
- # TODO is this the fastest way to remove the markers? Needs benchmarking ...
397
- input.gsub!(/\{\/?immunio-var:\d+:#{nonce}\}/, "")
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
- if code !~ ActionView::Template::Handlers::Erubis::BLOCK_EXPR
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
- Immunio::Plugin.load(
547
- 'Erubis',
548
- feature: 'xss',
549
- hooks: %w( template_render_done template_render_var )) do |plugin|
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
- ActionView::Template::Handlers::Erubis.send :include, Immunio::ErubisHooks
616
+ ActionView::Template::Handlers::ERB::Erubi.send :include, Immunio::ErubiHooks
552
617
 
553
- plugin.loaded! Rails.version
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: %w( template_render_done template_render_var )) do |plugin|
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: %w( template_render_done template_render_var )) do |plugin|
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
- def quote_with_immunio(value, column = nil)
19
- Request.time "plugin", "#{Module.nesting[0]}::#{__method__}" do
20
- if column
21
- column_name = column.name
22
- else
23
- column_name = nil
24
- end
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
- # Ignored empty strings and values that can't contain injections.
27
- unless value.blank? || IGNORED_TYPES.include?(value.class)
28
- QueryTracker.instance.add_param column_name, value.to_s, object_id
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
- Request.pause "plugin", "#{Module.nesting[0]}::#{__method__}" do
32
- quote_without_immunio(value, column)
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
- params[name] = value.to_s
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", "sql_execute", sql: payload[:sql],
640
- connection_uuid: connection_id.to_s,
641
- params: params,
642
- modifiers: modifiers,
643
- context_key: strict_context,
644
- loose_context_key: loose_context,
645
- stack: stack,
646
- additional_context_data: context_data
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
- Immunio::Utils.alias_method_chain self, :log, :immunio if method_defined? :log
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
- QueryTracker.instance.call sql: sql,
681
- connection_id: object_id,
682
- binds: binds
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
- private
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
- def delete_records_with_immunio(records, method, *args)
311
- scope = through_association.scope
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
- unless method == :destroy && !scope.klass.primary_key
314
- return delete_records_without_immunio(records, method, *args)
315
- end
318
+ unless method == :destroy && !scope.klass.primary_key
319
+ return delete_records_without_immunio(records, method, *args)
320
+ end
316
321
 
317
- # From here on down, copied from upstream Rails 4.2. Verified to work on
318
- # Rails 4.1, too.
319
- ensure_not_nested
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
- scope.where! construct_join_attributes(*records)
326
+ scope.where! construct_join_attributes(*records)
322
327
 
323
- scope.each do |record|
324
- record.run_callbacks :destroy
325
- end
328
+ scope.each do |record|
329
+ record.run_callbacks :destroy
330
+ end
326
331
 
327
- arel = scope.arel
332
+ arel = scope.arel
328
333
 
329
- stmt = Arel::DeleteManager.new arel.engine
330
- stmt.from scope.klass.arel_table
331
- stmt.wheres = arel.constraints
334
+ stmt = Arel::DeleteManager.new arel.engine
335
+ stmt.from scope.klass.arel_table
336
+ stmt.wheres = arel.constraints
332
337
 
333
- Request.time "plugin", "Immunio::RelationTracking" do
334
- QueryTracker.instance.push_relation scope
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.pop_relation scope
387
+ QueryTracker.instance.push_relation scope
342
388
  end
343
- end
344
389
 
345
- delete_through_records(records)
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
- if source_reflection.options[:counter_cache] && method != :destroy
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
- if through_reflection.collection? && update_through_counter?(method)
353
- update_counter(-count, through_reflection)
354
- end
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
- update_counter(-count)
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
@@ -3,23 +3,35 @@ module Immunio
3
3
  extend ActiveSupport::Concern
4
4
 
5
5
  included do
6
- if method_defined? :verify_authenticity_token
7
- Immunio::Utils.alias_method_chain self, :verify_authenticity_token, :immunio
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
- Immunio.run_hook! "csrf", "framework_csrf_check", valid: verified_request?
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
- Request.pause "plugin", "#{Module.nesting[0]}::#{__method__}" do
19
- verify_authenticity_token_without_immunio
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
- Immunio::Utils.alias_method_chain self, :redirect_to, :immunio if method_defined? :redirect_to
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
@@ -135,7 +135,7 @@ module Immunio
135
135
  def run_hook(plugin, hook, meta={})
136
136
  request = Request.current
137
137
 
138
- # Hooks called outside of a request are ignored since they are triggered while the framework is loaded.
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.
@@ -1,5 +1,5 @@
1
1
  module Immunio
2
2
  AGENT_TYPE = "agent-ruby"
3
- VERSION = "1.1.18"
3
+ VERSION = "1.1.19"
4
4
  VM_VERSION = "2.2.0"
5
5
  end
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.18
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-06-18 00:00:00.000000000 Z
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.11
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: