immunio 1.1.1 → 1.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/immunio.rb +1 -0
- data/lib/immunio/agent.rb +0 -73
- data/lib/immunio/plugin.rb +94 -0
- data/lib/immunio/plugins/action_dispatch.rb +15 -28
- data/lib/immunio/plugins/action_view.rb +15 -33
- data/lib/immunio/plugins/active_record.rb +3 -34
- data/lib/immunio/plugins/active_record_relation.rb +2 -20
- data/lib/immunio/plugins/authlogic.rb +57 -57
- data/lib/immunio/plugins/csrf.rb +4 -5
- data/lib/immunio/plugins/devise.rb +27 -25
- data/lib/immunio/plugins/environment_reporter.rb +5 -1
- data/lib/immunio/plugins/eval.rb +2 -3
- data/lib/immunio/plugins/http_finisher.rb +0 -1
- data/lib/immunio/plugins/http_tracker.rb +0 -1
- data/lib/immunio/plugins/io.rb +4 -7
- data/lib/immunio/plugins/redirect.rb +2 -5
- data/lib/immunio/plugins/warden.rb +51 -49
- data/lib/immunio/rails.rb +9 -5
- data/lib/immunio/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 877a290ccd60b4a6e46fff24968cd223fae6ac56
|
4
|
+
data.tar.gz: 5e4c68c451a27e7de6590499dd427485d05ab577
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 88c2d9d8c86bd24fa028e1c092524617f3bbc2e271f3fae53c50c8ae45f3ab6d5b1f5b8c1846be8fa7ede95441121426355b5960ed174269712a14f06883c9e6
|
7
|
+
data.tar.gz: 7a7bdc7a6cc3d85f5f226a8017061d22dda0bd9f9a6aeaae146f5f8df80b6f8d1e79b533bba2525e2ce8b245ebf52d9cb85e46d3221af0107b427114c1f421ea
|
data/lib/immunio.rb
CHANGED
data/lib/immunio/agent.rb
CHANGED
@@ -70,8 +70,6 @@ module Immunio
|
|
70
70
|
# purposes.
|
71
71
|
config_accessor :vm_data
|
72
72
|
|
73
|
-
attr_reader :plugins
|
74
|
-
|
75
73
|
def initialize
|
76
74
|
Immunio.logger.info { "Initializing agent version #{VERSION} for process #{Process.pid}" }
|
77
75
|
|
@@ -104,8 +102,6 @@ module Immunio
|
|
104
102
|
# Be sure all config attributes have a type before this call:
|
105
103
|
load_config
|
106
104
|
|
107
|
-
setup_plugin_registry
|
108
|
-
|
109
105
|
Immunio::switch_to_real_logger(config.log_file, config.log_level)
|
110
106
|
|
111
107
|
if !config.agent_enabled then
|
@@ -235,75 +231,6 @@ module Immunio
|
|
235
231
|
def environment=(environment)
|
236
232
|
@processor.environment = environment
|
237
233
|
end
|
238
|
-
|
239
|
-
def register_plugin(name, version = nil)
|
240
|
-
@plugins[name] = {} unless @plugins.has_key?(name)
|
241
|
-
@plugins[name]['status'] = 'loaded'
|
242
|
-
@plugins[name]['version'] = version if version
|
243
|
-
|
244
|
-
Immunio.logger.info do
|
245
|
-
"Registering plugin '#{name}' => '#{@plugins[name]}'"
|
246
|
-
end
|
247
|
-
end
|
248
|
-
|
249
|
-
RECOGNIZED_PLUGINS = [
|
250
|
-
## action_dispatch
|
251
|
-
'ActionDispatch::Cookies::SignedCookieJar',
|
252
|
-
'ActionDispatch::Cookies::UpgradeLegacySignedCookieJar',
|
253
|
-
'ActionDispatch::Cookies::EncryptedCookieJar',
|
254
|
-
'ActionDispatch::Cookies::UpgradeLegacyEncryptedCookieJar',
|
255
|
-
|
256
|
-
## action_view
|
257
|
-
'ActionView::Template::Handlers::Erubis',
|
258
|
-
'Haml::Compiler',
|
259
|
-
'Hash',
|
260
|
-
'ActionView::TemplateRenderer',
|
261
|
-
'ActionView::Template',
|
262
|
-
'ActionController::Caching::Fragments',
|
263
|
-
|
264
|
-
## active_record
|
265
|
-
'ActiveRecord',
|
266
|
-
'ActiveRecord::ConnectionAdapters::Mysql2Adapter',
|
267
|
-
'ActiveRecord::ConnectionAdapters::MysqlAdapter',
|
268
|
-
'ActiveRecord::ConnectionAdapters::PostgreSQLAdapter',
|
269
|
-
'ActiveRecord::ConnectionAdapters::SQLite3Adapter',
|
270
|
-
'ActiveRecord::ConnectionAdapters::SQLiteAdapter',
|
271
|
-
'ActiveRecord::Sanitization',
|
272
|
-
'Arel::Visitors::ToSql',
|
273
|
-
'ActiveRecord::ConnectionAdapters::AbstractAdapter',
|
274
|
-
|
275
|
-
## active_record_relation
|
276
|
-
'ActiveRecord::Relation',
|
277
|
-
'ActiveRecord::SpawnMethods',
|
278
|
-
'ActiveRecord::Querying',
|
279
|
-
'ActiveRecord::StatementCache',
|
280
|
-
'ActiveRecord::Associations::HasManyThroughAssociation',
|
281
|
-
|
282
|
-
'Authlogic',
|
283
|
-
'ActionController (CSRF)',
|
284
|
-
'Devise',
|
285
|
-
'Kernel (Eval)',
|
286
|
-
'Immunio::HTTPFinisher',
|
287
|
-
'Immunio::HTTPTracker',
|
288
|
-
|
289
|
-
## io
|
290
|
-
'IO',
|
291
|
-
'File',
|
292
|
-
'Kernel (Module)',
|
293
|
-
|
294
|
-
'ActionController (Redirect)',
|
295
|
-
'Warden'
|
296
|
-
].freeze
|
297
|
-
|
298
|
-
private
|
299
|
-
|
300
|
-
def setup_plugin_registry
|
301
|
-
@plugins = {}
|
302
|
-
|
303
|
-
RECOGNIZED_PLUGINS.each do |name|
|
304
|
-
@plugins[name] = { 'status' => 'pending' }
|
305
|
-
end
|
306
|
-
end
|
307
234
|
end
|
308
235
|
|
309
236
|
AGENT_INIT_MUTEX = Mutex.new
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require "msgpack"
|
2
|
+
|
3
|
+
module Immunio
|
4
|
+
# Holds the status of a plugin.
|
5
|
+
#
|
6
|
+
# A plugin can have one of four statuses:
|
7
|
+
#
|
8
|
+
# - pending: initial state, waiting to be loaded
|
9
|
+
# - loaded: successfully loaded
|
10
|
+
# - failed: error while loading
|
11
|
+
# - disabled: disabled in config, will never be loaded
|
12
|
+
#
|
13
|
+
# Each registered plugin is reported to the backend via the `EnvironmentReporter`.
|
14
|
+
class Plugin
|
15
|
+
attr_reader :status
|
16
|
+
attr_accessor :version
|
17
|
+
|
18
|
+
def initialize(name)
|
19
|
+
@name = name
|
20
|
+
@status = 'pending'
|
21
|
+
@version = nil
|
22
|
+
end
|
23
|
+
|
24
|
+
def loaded!(version)
|
25
|
+
@status = 'loaded'
|
26
|
+
@version = version
|
27
|
+
Immunio.logger.debug "Plugin #{@name} v#{version} loaded successfully"
|
28
|
+
end
|
29
|
+
|
30
|
+
def disabled!
|
31
|
+
@status = 'disabled'
|
32
|
+
Immunio.logger.debug "Plugin #{@name} is disabled"
|
33
|
+
end
|
34
|
+
|
35
|
+
def failed!(error)
|
36
|
+
@status = 'failed'
|
37
|
+
Immunio.logger.error "Plugin #{@name} failed to load: #{error}"
|
38
|
+
end
|
39
|
+
|
40
|
+
def inspect
|
41
|
+
"<#{self.class} name=#{@name.inspect} status=#{@status.inspect} version=#{@version.inspect}>"
|
42
|
+
end
|
43
|
+
|
44
|
+
def to_msgpack(packer)
|
45
|
+
packer.write_map_header 2
|
46
|
+
# `name` is provided as the key in `registered`
|
47
|
+
packer.write('status').write(@status)
|
48
|
+
packer.write('version').write(@version)
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.registered
|
52
|
+
@registered ||= {}
|
53
|
+
end
|
54
|
+
|
55
|
+
# DSL to register a plugin, its status and version.
|
56
|
+
#
|
57
|
+
# A `feature` name can be passed to determine if the plugin should be enabled. If the
|
58
|
+
# plugin is disabled, the block will not run.
|
59
|
+
#
|
60
|
+
# You MUST explicitly call `plugin.loaded!` in the block to indicate that the plugin was
|
61
|
+
# loaded successfully, or else it will be kept as 'pending'.
|
62
|
+
#
|
63
|
+
# Eg.:
|
64
|
+
#
|
65
|
+
# Immunio::Plugin.load 'SomePluginName', feature: 'xss' do |plugin|
|
66
|
+
# if defined? SomePlugin
|
67
|
+
# # Your loading code here ...
|
68
|
+
# plugin.loaded! SomePluginName::VERSION
|
69
|
+
# end
|
70
|
+
# end
|
71
|
+
#
|
72
|
+
def self.load(name, options = {})
|
73
|
+
if options.key? :feature
|
74
|
+
enabled = Immunio.agent.plugin_enabled?(options[:feature])
|
75
|
+
else
|
76
|
+
enabled = true
|
77
|
+
end
|
78
|
+
|
79
|
+
plugin = registered[name] = new(name)
|
80
|
+
|
81
|
+
unless enabled # plugin is disabled
|
82
|
+
plugin.disabled!
|
83
|
+
return
|
84
|
+
end
|
85
|
+
|
86
|
+
Immunio.logger.debug "Loading plugin #{name} ..."
|
87
|
+
begin
|
88
|
+
yield plugin
|
89
|
+
rescue StandardError, LoadError => e
|
90
|
+
plugin.failed! e
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -29,36 +29,23 @@ module Immunio
|
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
'ActionDispatch::Cookies::SignedCookieJar',
|
38
|
-
ActionPack::VERSION::STRING)
|
39
|
-
end
|
40
|
-
|
41
|
-
if defined? UpgradeLegacySignedCookieJar
|
42
|
-
UpgradeLegacySignedCookieJar.send :include, Immunio::CookieHooks
|
43
|
-
|
44
|
-
Immunio.agent.register_plugin(
|
45
|
-
'ActionDispatch::Cookies::UpgradeLegacySignedCookieJar',
|
46
|
-
ActionPack::VERSION::STRING)
|
47
|
-
end
|
48
|
-
|
49
|
-
if defined? EncryptedCookieJar
|
50
|
-
EncryptedCookieJar.send :include, Immunio::CookieHooks
|
32
|
+
Immunio::Plugin.load 'ActionDispatch (Cookie)' do |plugin|
|
33
|
+
class ActionDispatch::Cookies
|
34
|
+
if defined? SignedCookieJar
|
35
|
+
SignedCookieJar.send :include, Immunio::CookieHooks
|
36
|
+
end
|
51
37
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
end
|
38
|
+
if defined? UpgradeLegacySignedCookieJar
|
39
|
+
UpgradeLegacySignedCookieJar.send :include, Immunio::CookieHooks
|
40
|
+
end
|
56
41
|
|
57
|
-
|
58
|
-
|
42
|
+
if defined? EncryptedCookieJar
|
43
|
+
EncryptedCookieJar.send :include, Immunio::CookieHooks
|
44
|
+
end
|
59
45
|
|
60
|
-
|
61
|
-
|
62
|
-
|
46
|
+
if defined? UpgradeLegacyEncryptedCookieJar
|
47
|
+
UpgradeLegacyEncryptedCookieJar.send :include, Immunio::CookieHooks
|
48
|
+
end
|
63
49
|
end
|
50
|
+
plugin.loaded! ActionPack::VERSION::STRING
|
64
51
|
end
|
@@ -531,51 +531,33 @@ module Immunio
|
|
531
531
|
end
|
532
532
|
end
|
533
533
|
|
534
|
-
#
|
535
|
-
if Immunio::agent.plugin_enabled?("xss") then
|
536
|
-
action_view_version =
|
537
|
-
if ActionView.respond_to?(:version)
|
538
|
-
ActionView.version.to_s
|
539
|
-
else
|
540
|
-
Rails.version
|
541
|
-
end
|
534
|
+
# Load the plugins
|
542
535
|
|
543
|
-
|
536
|
+
Immunio::Plugin.load 'Erubis', feature: 'xss' do |plugin|
|
544
537
|
ActionView::Template::Handlers::Erubis.send :include, Immunio::ErubisHooks
|
538
|
+
plugin.loaded! Rails.version
|
539
|
+
end
|
545
540
|
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
ActiveSupport.on_load(:after_initialize) do
|
551
|
-
# Wait after Rails initialization to patch custom template engines.
|
541
|
+
ActiveSupport.on_load(:after_initialize) do
|
542
|
+
# Wait after Rails initialization to patch custom template engines.
|
543
|
+
Immunio::Plugin.load 'Haml', feature: 'xss' do |plugin|
|
552
544
|
if defined? Haml::Compiler
|
553
545
|
Haml::Compiler.send :include, Immunio::HamlHooks
|
554
|
-
|
546
|
+
plugin.loaded! Haml::VERSION
|
555
547
|
end
|
556
|
-
|
557
|
-
Hash.send :include, Immunio::ActiveSupportHooks
|
558
|
-
Immunio.agent.register_plugin('Hash', RUBY_VERSION)
|
559
548
|
end
|
560
549
|
|
561
|
-
#
|
562
|
-
|
563
|
-
|
564
|
-
Immunio.agent.register_plugin(
|
565
|
-
'ActionView::TemplateRenderer',
|
566
|
-
action_view_version)
|
550
|
+
# Wait for ActiveSupport core ext to load
|
551
|
+
Hash.send :include, Immunio::ActiveSupportHooks
|
552
|
+
end
|
567
553
|
|
554
|
+
# Hook into rendering process of Rails.
|
555
|
+
Immunio::Plugin.load 'ActionView', feature: 'xss' do |plugin|
|
556
|
+
ActionView::TemplateRenderer.send :include, Immunio::TemplateRendererHooks
|
568
557
|
ActionView::Template.send :include, Immunio::TemplateHooks
|
569
|
-
|
570
|
-
Immunio.agent.register_plugin(
|
571
|
-
'ActionView::Template',
|
572
|
-
action_view_version)
|
573
|
-
|
574
558
|
ActionController::Caching::Fragments.send(
|
575
559
|
:include,
|
576
560
|
Immunio::FragmentCachingHooks)
|
577
561
|
|
578
|
-
|
579
|
-
'ActionController::Caching::Fragments',
|
580
|
-
action_view_version)
|
562
|
+
plugin.loaded! Rails.version
|
581
563
|
end
|
@@ -681,66 +681,35 @@ module Immunio
|
|
681
681
|
end
|
682
682
|
end
|
683
683
|
|
684
|
-
Immunio.agent.register_plugin('ActiveRecord', ActiveRecord::VERSION::STRING)
|
685
|
-
|
686
684
|
# Hook into quoting methods at the highest level possible in the ancestors chain.
|
687
685
|
# In case the quote methods were overridden in a child class.
|
686
|
+
#
|
687
|
+
# NOTE: ActiveRecord plugin status is set in lib/immunio/rails.rb where this file is required.
|
688
|
+
#
|
688
689
|
module ActiveRecord::ConnectionAdapters
|
689
690
|
if defined? Mysql2Adapter
|
690
691
|
Mysql2Adapter.send :include, Immunio::QuotingHooks
|
691
|
-
|
692
|
-
Immunio.agent.register_plugin(
|
693
|
-
'ActiveRecord::ConnectionAdapters::Mysql2Adapter',
|
694
|
-
ActiveRecord::VERSION::STRING)
|
695
692
|
elsif defined? MysqlAdapter
|
696
693
|
MysqlAdapter.send :include, Immunio::QuotingHooks
|
697
|
-
|
698
|
-
Immunio.agent.register_plugin(
|
699
|
-
'ActiveRecord::ConnectionAdapters::MysqlAdapter',
|
700
|
-
ActiveRecord::VERSION::STRING)
|
701
694
|
end
|
702
695
|
|
703
696
|
if defined? PostgreSQLAdapter
|
704
697
|
PostgreSQLAdapter.send :include, Immunio::QuotingHooks
|
705
|
-
|
706
|
-
Immunio.agent.register_plugin(
|
707
|
-
'ActiveRecord::ConnectionAdapters::PostgreSQLAdapter',
|
708
|
-
ActiveRecord::VERSION::STRING)
|
709
698
|
end
|
710
699
|
|
711
700
|
if defined? SQLite3Adapter
|
712
701
|
SQLite3Adapter.send :include, Immunio::QuotingHooks
|
713
|
-
|
714
|
-
Immunio.agent.register_plugin(
|
715
|
-
'ActiveRecord::ConnectionAdapters::SQLite3Adapter',
|
716
|
-
ActiveRecord::VERSION::STRING)
|
717
702
|
elsif defined? SQLiteAdapter
|
718
703
|
SQLiteAdapter.send :include, Immunio::QuotingHooks
|
719
|
-
|
720
|
-
Immunio.agent.register_plugin(
|
721
|
-
'ActiveRecord::ConnectionAdapters::SQLiteAdapter',
|
722
|
-
ActiveRecord::VERSION::STRING)
|
723
704
|
end
|
724
705
|
end
|
725
706
|
|
726
707
|
module ActiveRecord::Sanitization
|
727
708
|
ClassMethods.send :include, Immunio::SanitizeHooks
|
728
|
-
|
729
|
-
Immunio.agent.register_plugin(
|
730
|
-
'ActiveRecord::Sanitization',
|
731
|
-
ActiveRecord::VERSION::STRING)
|
732
709
|
end
|
733
710
|
|
734
711
|
Arel::Visitors::ToSql.send :include, Immunio::ArelToSqlHooks
|
735
712
|
|
736
|
-
Immunio.agent.register_plugin(
|
737
|
-
'Arel::Visitors::ToSql',
|
738
|
-
ActiveRecord::VERSION::STRING)
|
739
|
-
|
740
713
|
ActiveRecord::ConnectionAdapters::AbstractAdapter.send(
|
741
714
|
:include,
|
742
715
|
Immunio::QueryExecutionHooks)
|
743
|
-
|
744
|
-
Immunio.agent.register_plugin(
|
745
|
-
'ActiveRecord::ConnectionAdapters::AbstractAdapter',
|
746
|
-
ActiveRecord::VERSION::STRING)
|
@@ -365,34 +365,24 @@ module Immunio
|
|
365
365
|
end
|
366
366
|
end
|
367
367
|
|
368
|
+
# NOTE: ActiveRecord plugin status is set in lib/immunio/rails.rb
|
369
|
+
|
368
370
|
module ActiveRecord
|
369
371
|
if defined? Relation
|
370
372
|
Relation.send(
|
371
373
|
:include,
|
372
374
|
Immunio::RelationHooks)
|
373
375
|
|
374
|
-
Immunio.agent.register_plugin(
|
375
|
-
'ActiveRecord::Relation',
|
376
|
-
ActiveRecord::VERSION::STRING)
|
377
|
-
|
378
376
|
if defined? SpawnMethods
|
379
377
|
Relation.send(
|
380
378
|
:include,
|
381
379
|
Immunio::SpawnHooks)
|
382
|
-
|
383
|
-
Immunio.agent.register_plugin(
|
384
|
-
'ActiveRecord::SpawnMethods',
|
385
|
-
ActiveRecord::VERSION::STRING)
|
386
380
|
end
|
387
381
|
|
388
382
|
if defined? Querying
|
389
383
|
Relation.send(
|
390
384
|
:include,
|
391
385
|
Immunio::QueryingHooks)
|
392
|
-
|
393
|
-
Immunio.agent.register_plugin(
|
394
|
-
'ActiveRecord::Querying',
|
395
|
-
ActiveRecord::VERSION::STRING)
|
396
386
|
end
|
397
387
|
end
|
398
388
|
|
@@ -400,10 +390,6 @@ module ActiveRecord
|
|
400
390
|
StatementCache.send(
|
401
391
|
:include,
|
402
392
|
Immunio::StatementCacheHooks)
|
403
|
-
|
404
|
-
Immunio.agent.register_plugin(
|
405
|
-
'ActiveRecord::StatementCache',
|
406
|
-
ActiveRecord::VERSION::STRING)
|
407
393
|
end
|
408
394
|
|
409
395
|
module Associations
|
@@ -411,10 +397,6 @@ module ActiveRecord
|
|
411
397
|
HasManyThroughAssociation.send(
|
412
398
|
:include,
|
413
399
|
Immunio::HasManyThroughAssociationHooks)
|
414
|
-
|
415
|
-
Immunio.agent.register_plugin(
|
416
|
-
'ActiveRecord::Associations::HasManyThroughAssociation',
|
417
|
-
ActiveRecord::VERSION::STRING)
|
418
400
|
end
|
419
401
|
end
|
420
402
|
end
|
@@ -6,79 +6,79 @@ rescue LoadError # rubocop:disable Lint/HandleExceptions
|
|
6
6
|
# Ignore
|
7
7
|
end
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
module
|
12
|
-
module
|
13
|
-
|
14
|
-
klass
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
9
|
+
Immunio::Plugin.load 'Authlogic' do |plugin|
|
10
|
+
if defined? Authlogic
|
11
|
+
module Immunio
|
12
|
+
module Authlogic
|
13
|
+
module SessionHooks
|
14
|
+
def self.included(klass)
|
15
|
+
klass.class_eval do
|
16
|
+
include InstanceMethods
|
17
|
+
after_create :immunio_login
|
18
|
+
validate :immunio_check_failed_login
|
19
|
+
before_destroy :immunio_logout
|
20
|
+
after_persisting :immunio_set_user
|
21
|
+
end
|
20
22
|
end
|
21
|
-
end
|
22
|
-
|
23
|
-
module InstanceMethods
|
24
|
-
private
|
25
|
-
def opts
|
26
|
-
info = {plugin: "authlogic"}
|
27
23
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
# attempted_record is set when attempting to log in and the user record has been fetched
|
33
|
-
info[:user_record] = attempted_record
|
34
|
-
end
|
24
|
+
module InstanceMethods
|
25
|
+
private
|
26
|
+
def opts
|
27
|
+
info = {plugin: "authlogic"}
|
35
28
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
29
|
+
if defined?(:record) && record
|
30
|
+
# record is set when already logged in, e.g. you are now logging out
|
31
|
+
info[:user_record] = record
|
32
|
+
elsif defined?(:attempted_record) && attempted_record
|
33
|
+
# attempted_record is set when attempting to log in and the user record has been fetched
|
34
|
+
info[:user_record] = attempted_record
|
35
|
+
end
|
41
36
|
|
42
|
-
|
43
|
-
|
37
|
+
# credentials are set when the user attempts to log in
|
38
|
+
if defined?(:credentials) && defined?(:login_field)
|
39
|
+
login = credentials[login_field.to_sym]
|
40
|
+
info[:username] = login if login
|
41
|
+
end
|
44
42
|
|
45
|
-
|
46
|
-
Immunio::Request.time "plugin", "#{Module.nesting[0]}::#{__method__}" do
|
47
|
-
Immunio.logger.debug {"Authlogic instrumentation fired for login with opts #{opts}"}
|
48
|
-
Immunio.login opts
|
43
|
+
info
|
49
44
|
end
|
50
|
-
end
|
51
45
|
|
52
|
-
|
53
|
-
if errors.any?
|
46
|
+
def immunio_login
|
54
47
|
Immunio::Request.time "plugin", "#{Module.nesting[0]}::#{__method__}" do
|
55
|
-
Immunio.logger.debug {
|
56
|
-
Immunio.
|
48
|
+
Immunio.logger.debug {"Authlogic instrumentation fired for login with opts #{opts}"}
|
49
|
+
Immunio.login opts
|
57
50
|
end
|
58
51
|
end
|
59
|
-
end
|
60
52
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
53
|
+
def immunio_check_failed_login
|
54
|
+
if errors.any?
|
55
|
+
Immunio::Request.time "plugin", "#{Module.nesting[0]}::#{__method__}" do
|
56
|
+
Immunio.logger.debug { "Authlogic instrumentation fired for before_failure with opts #{opts}" }
|
57
|
+
Immunio.failed_login opts
|
58
|
+
end
|
59
|
+
end
|
65
60
|
end
|
66
|
-
end
|
67
61
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
62
|
+
def immunio_logout
|
63
|
+
Immunio::Request.time "plugin", "#{Module.nesting[0]}::#{__method__}" do
|
64
|
+
Immunio.logger.debug { "Authlogic instrumentation fired for logout with opts #{opts}" }
|
65
|
+
Immunio.logout opts
|
66
|
+
end
|
72
67
|
end
|
73
|
-
|
68
|
+
|
69
|
+
def immunio_set_user
|
70
|
+
Immunio::Request.time "plugin", "#{Module.nesting[0]}::#{__method__}" do
|
71
|
+
Immunio.logger.debug { "Authlogic instrumentation fired for after_set_user with opts #{opts}" }
|
72
|
+
Immunio.set_user opts
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
74
76
|
end
|
75
77
|
end
|
76
78
|
end
|
77
|
-
end
|
78
79
|
|
79
|
-
|
80
|
+
Authlogic::Session::Base.send :include, Immunio::Authlogic::SessionHooks
|
80
81
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
end
|
82
|
+
plugin.loaded! Gem.loaded_specs['authlogic'].version.to_s
|
83
|
+
end
|
84
|
+
end
|
data/lib/immunio/plugins/csrf.rb
CHANGED
@@ -23,8 +23,7 @@ module Immunio
|
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
ActionPack::VERSION::STRING)
|
26
|
+
Immunio::Plugin.load 'ActionController (CSRF)' do |plugin|
|
27
|
+
ActionController::Base.send :include, Immunio::CsrfHook
|
28
|
+
plugin.loaded! ActionPack::VERSION::STRING
|
29
|
+
end
|
@@ -6,38 +6,40 @@ rescue LoadError # rubocop:disable Lint/HandleExceptions
|
|
6
6
|
# Ignore
|
7
7
|
end
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
9
|
+
Immunio::Plugin.load 'Devise' do |plugin|
|
10
|
+
if defined? Devise
|
11
|
+
module Immunio
|
12
|
+
# Hook into password recovery feature to trigger the `framework_password_reset` hook.
|
13
|
+
module DeviseRecoverableHooks
|
14
|
+
extend ActiveSupport::Concern
|
15
|
+
|
16
|
+
included do
|
17
|
+
Immunio::Utils.alias_method_chain self, :send_reset_password_instructions, :immunio
|
18
|
+
end
|
18
19
|
|
19
|
-
|
20
|
-
|
21
|
-
|
20
|
+
def send_reset_password_instructions_with_immunio(attributes={})
|
21
|
+
Request.time "plugin", "#{Module.nesting[0]}::#{__method__}" do
|
22
|
+
Immunio.logger.debug { "Devise instrumentation fired for send_reset_password_instructions" }
|
22
23
|
|
23
|
-
|
24
|
+
recoverable = find_or_initialize_with_errors(reset_password_keys, attributes, :not_found)
|
24
25
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
26
|
+
if recoverable.persisted? # Found
|
27
|
+
Immunio.password_reset user_record: recoverable, plugin: 'devise'
|
28
|
+
else
|
29
|
+
Immunio.failed_password_reset email: recoverable.email, plugin: 'devise'
|
30
|
+
end
|
30
31
|
|
31
|
-
|
32
|
-
|
32
|
+
Request.pause "plugin", "#{Module.nesting[0]}::#{__method__}" do
|
33
|
+
send_reset_password_instructions_without_immunio(attributes)
|
34
|
+
end
|
33
35
|
end
|
34
36
|
end
|
35
37
|
end
|
36
38
|
end
|
37
|
-
end
|
38
39
|
|
39
|
-
|
40
|
+
Devise::Models::Recoverable::ClassMethods.send :include, Immunio::DeviseRecoverableHooks
|
40
41
|
|
41
|
-
|
42
|
-
|
43
|
-
end
|
42
|
+
require 'devise/version'
|
43
|
+
plugin.loaded! Devise::VERSION
|
44
|
+
end
|
45
|
+
end
|
@@ -56,6 +56,10 @@ module Immunio
|
|
56
56
|
Addrinfo.getaddrinfo(hostname, nil).first.ip_address rescue SocketError
|
57
57
|
end
|
58
58
|
|
59
|
+
def plugins
|
60
|
+
Immunio::Plugin.registered
|
61
|
+
end
|
62
|
+
|
59
63
|
def report
|
60
64
|
@reported = true
|
61
65
|
|
@@ -76,7 +80,7 @@ module Immunio
|
|
76
80
|
hostname_ip: hostname_ip,
|
77
81
|
ips: ips
|
78
82
|
},
|
79
|
-
plugins:
|
83
|
+
plugins: plugins
|
80
84
|
}
|
81
85
|
|
82
86
|
Immunio.agent.environment = info
|
data/lib/immunio/plugins/eval.rb
CHANGED
@@ -37,9 +37,8 @@ module Immunio
|
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
40
|
-
|
40
|
+
Immunio::Plugin.load 'Kernel (Eval)', feature: 'eval' do |plugin|
|
41
41
|
Kernel.send :include, Immunio::KernelEvalHook
|
42
42
|
Kernel.extend Immunio::KernelEvalHook
|
43
|
-
|
44
|
-
Immunio.agent.register_plugin('Kernel (Eval)', RUBY_VERSION)
|
43
|
+
plugin.loaded! RUBY_VERSION
|
45
44
|
end
|
data/lib/immunio/plugins/io.rb
CHANGED
@@ -100,19 +100,16 @@ module Immunio
|
|
100
100
|
end
|
101
101
|
|
102
102
|
# Add FileIO hooks if enabled
|
103
|
-
|
103
|
+
Immunio::Plugin.load 'IO', feature: 'file_io' do |plugin|
|
104
104
|
IO.extend Immunio::IOClassHooks
|
105
105
|
File.extend Immunio::FileClassHooks
|
106
|
-
|
107
|
-
Immunio.agent.register_plugin('IO', RUBY_VERSION)
|
108
|
-
Immunio.agent.register_plugin('File', RUBY_VERSION)
|
106
|
+
plugin.loaded! RUBY_VERSION
|
109
107
|
end
|
110
108
|
|
111
109
|
# Add Kernel hooks if enabled
|
112
|
-
|
110
|
+
Immunio::Plugin.load 'Kernel (shell_command)', feature: 'shell_command' do |plugin|
|
113
111
|
# Both are necessary to hook calling both Kernel.open() and open() etc.
|
114
112
|
Kernel.send :include, Immunio::KernelModuleHooks
|
115
113
|
Kernel.extend Immunio::KernelModuleHooks
|
116
|
-
|
117
|
-
Immunio.agent.register_plugin('Kernel (Module)', RUBY_VERSION)
|
114
|
+
plugin.loaded! RUBY_VERSION
|
118
115
|
end
|
@@ -36,11 +36,8 @@ module Immunio
|
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
|
-
|
39
|
+
Immunio::Plugin.load 'ActionController (Redirect)', feature: 'redirect' do |plugin|
|
40
40
|
ActionController::Base.send :include, Immunio::RedirectHook
|
41
|
-
Immunio.logger.debug { "Redirect: All hooks installed." }
|
42
41
|
|
43
|
-
|
44
|
-
'ActionController (Redirect)',
|
45
|
-
ActionPack::VERSION::STRING)
|
42
|
+
plugin.loaded! ActionPack::VERSION::STRING
|
46
43
|
end
|
@@ -6,67 +6,69 @@ rescue LoadError # rubocop:disable Lint/HandleExceptions
|
|
6
6
|
# Ignore
|
7
7
|
end
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
Immunio.
|
14
|
-
|
9
|
+
Immunio::Plugin.load 'Warden' do |plugin|
|
10
|
+
if defined?(Warden::Manager)
|
11
|
+
class Warden::Manager
|
12
|
+
after_authentication do |user|
|
13
|
+
Immunio::Request.time "plugin", "Warden::Manager.after_authentication" do
|
14
|
+
Immunio.logger.debug { "Warden instrumentation fired for after_authentication" }
|
15
|
+
Immunio.login user_record: user, plugin: "warden"
|
16
|
+
end
|
15
17
|
end
|
16
|
-
end
|
17
18
|
|
18
|
-
|
19
|
-
|
20
|
-
|
19
|
+
before_failure do |env|
|
20
|
+
Immunio::Request.time "plugin", "Warden::Manager.before_failure" do
|
21
|
+
info = {plugin: "warden"}
|
21
22
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
23
|
+
# Devise uses these specific form fields for authentication by default
|
24
|
+
user_found = false
|
25
|
+
[:username, :email].each do |attr|
|
26
|
+
value = env.fetch("rack.request.form_hash", {}).fetch("user", {})[attr.to_s]
|
27
|
+
if value
|
28
|
+
info[attr] = value
|
29
|
+
user_found = true
|
30
|
+
end
|
29
31
|
end
|
30
|
-
end
|
31
32
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
33
|
+
# before_failure is called under many circumstances, but unfortunately
|
34
|
+
# there's no easy way to tell why. If we can't figure out who the
|
35
|
+
# attempted user was, don't report it as a failed login.
|
36
|
+
if user_found
|
37
|
+
Immunio.logger.debug { "Warden instrumentation fired for before_failure" }
|
38
|
+
Immunio.failed_login info
|
39
|
+
else
|
40
|
+
Immunio.logger.debug { "Failed to find user info for Warden failure, ignoring instead of reporting as failed login" }
|
41
|
+
end
|
40
42
|
end
|
41
43
|
end
|
42
|
-
end
|
43
44
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
45
|
+
after_set_user do |user|
|
46
|
+
Immunio::Request.time "plugin", "Warden::Manager.after_set_user" do
|
47
|
+
Immunio.logger.debug { "Warden instrumentation fired for after_set_user" }
|
48
|
+
Immunio.set_user user_record: user, plugin: "warden"
|
49
|
+
end
|
48
50
|
end
|
49
|
-
end
|
50
51
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
52
|
+
before_logout do |user|
|
53
|
+
Immunio::Request.time "plugin", "Warden::Manager.before_logout" do
|
54
|
+
Immunio.logger.debug { "Warden instrumentation fired for before_logout" }
|
55
|
+
Immunio.logout user_record: user, plugin: "warden"
|
56
|
+
end
|
55
57
|
end
|
56
|
-
end
|
57
58
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
59
|
+
# Force lookup of user info for all requests.
|
60
|
+
def call_with_immunio(env)
|
61
|
+
call_without_immunio(env)
|
62
|
+
ensure
|
63
|
+
Immunio::Request.time "plugin", "#{Module.nesting[0]}::#{__method__}" do
|
64
|
+
env['warden'].user if env['warden']
|
65
|
+
end
|
64
66
|
end
|
67
|
+
alias :call_without_immunio :call
|
68
|
+
alias :call :call_with_immunio
|
65
69
|
end
|
66
|
-
alias :call_without_immunio :call
|
67
|
-
alias :call :call_with_immunio
|
68
|
-
end
|
69
70
|
|
70
|
-
|
71
|
-
|
72
|
-
end
|
71
|
+
require 'warden/version'
|
72
|
+
plugin.loaded! Warden::VERSION
|
73
|
+
end
|
74
|
+
end
|
data/lib/immunio/rails.rb
CHANGED
@@ -7,17 +7,21 @@ require_relative "plugins/warden"
|
|
7
7
|
|
8
8
|
module Immunio
|
9
9
|
class Engine < ::Rails::Engine
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
10
|
+
Immunio::Plugin.load 'Middlewares' do |plugin|
|
11
|
+
config.app_middleware.insert 0, HTTPFinisher
|
12
|
+
config.app_middleware.insert_before ActionDispatch::ShowExceptions, HTTPTracker
|
13
|
+
config.app_middleware.insert_after ActionDispatch::DebugExceptions, ExceptionHandler
|
14
|
+
config.app_middleware.use EnvironmentReporter
|
15
|
+
plugin.loaded! Rails.version
|
16
|
+
end
|
14
17
|
|
15
18
|
config.action_dispatch.rescue_responses.merge!('Immunio::RequestBlocked' => :forbidden)
|
16
19
|
|
17
|
-
|
20
|
+
Immunio::Plugin.load 'ActionRecord', feature: 'sqli' do |plugin|
|
18
21
|
initializer "immunio.active_record", after: "active_record.initialize_database" do
|
19
22
|
ActiveSupport.on_load(:active_record) do
|
20
23
|
require_relative "plugins/active_record"
|
24
|
+
plugin.loaded! ActiveRecord::VERSION::STRING
|
21
25
|
end
|
22
26
|
end
|
23
27
|
end
|
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.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Immunio
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-10-
|
11
|
+
date: 2016-10-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -138,6 +138,7 @@ files:
|
|
138
138
|
- lib/immunio/errors.rb
|
139
139
|
- lib/immunio/immunio_ca.crt
|
140
140
|
- lib/immunio/logger.rb
|
141
|
+
- lib/immunio/plugin.rb
|
141
142
|
- lib/immunio/plugins/action_dispatch.rb
|
142
143
|
- lib/immunio/plugins/action_view.rb
|
143
144
|
- lib/immunio/plugins/active_record.rb
|