immunio 1.1.1 → 1.1.2
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.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
|