immunio 1.1.7 → 1.1.10

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: b00b1a9669f4e9f0ec6b571a88b2d1df883cbf94
4
- data.tar.gz: 6fdf549ca4de7c8bf912a1fdcaf7bc00521c4e4b
3
+ metadata.gz: 8c73cecf0da251ae6c4e8fc65c1215a84cca2a9a
4
+ data.tar.gz: cc1742b1789f90dce3c6a2ad8a698c7e4e4730da
5
5
  SHA512:
6
- metadata.gz: d947098d70f20d0a073789d8742570bb64373fce01429f2207133ac603d612d25534dd362dad87ebfacb57ed0bde6c34038355e336238b28b42a0678bed42f7d
7
- data.tar.gz: f4a9b98cce16ba098561bb64bafcadf5fe50f1f9becbbc87549c5df9234f1f55062715274a59c44eadcb37088dc60a19bfe61ce44d59214f5056e9d733579b62
6
+ metadata.gz: 6ba46ef732b848a7bddce203578b91b801ad5c8571b5b49443c300b9f74bcbba3519ecffac8e0bd25476e2de40d7d8b8f16ae4a4bc45cf4aa93f3d26270c7291
7
+ data.tar.gz: d127335b24855d7b3cdd4725bca45b946e13d5712bc203fa972d0c79b16e719986b3d1c114bcb12df6ece8524c0af032c79f7fffd4ec46208dd03bb90d738c43
data/README.md CHANGED
@@ -39,6 +39,25 @@ gem immunio', group: :production
39
39
 
40
40
  You can also modify the secret and key for different environments to report to different apps, or you can disable the agent by setting `agent_enabled: false` in the configuration or `IMMUNIO_AGENT_ENABLED=0` in the environment.
41
41
 
42
+
43
+ ### Unicorn configuration
44
+
45
+ In order for the agent to function correctly in a pre-forked environment, use the `Immunio.reset!` method.
46
+ For example, in your `config/unicorn.rb`:
47
+
48
+ ```
49
+ after_fork do |server, worker|
50
+ Signal.trap 'TERM' do
51
+ puts 'Unicorn worker intercepting TERM and doing nothing. Wait for master to send QUIT'
52
+ end
53
+
54
+ defined?(ActiveRecord::Base) and ActiveRecord::Base.establish_connection
55
+
56
+ Immunio.reset!
57
+ end
58
+ ```
59
+
60
+
42
61
  ## Handling blocked requests
43
62
 
44
63
  By default, Immunio will return a plain text *403 Forbidden* response whenever it blocks a request for security reasons.
@@ -55,6 +74,7 @@ Immunio.blocked_app = -> env do
55
74
  end
56
75
  ```
57
76
 
77
+
58
78
  ## Authentication API
59
79
 
60
80
  If you're using [Devise](https://github.com/plataformatec/devise) or [Authlogic](https://github.com/binarylogic/authlogic), Immunio will automatically hook into your authentication system to protect you against attacks.
@@ -26,6 +26,10 @@ module Immunio
26
26
  # Load and activate Rails engine
27
27
  require_relative "immunio/rails"
28
28
  end
29
+
30
+ def self.reset!
31
+ agent.reset if agent
32
+ end
29
33
  end
30
34
 
31
35
  Immunio.activate!
@@ -153,6 +153,7 @@ module Immunio
153
153
  end
154
154
 
155
155
  @processor = Processor.new(@channel, @vmfactory, config)
156
+ @process_id = Process.pid
156
157
  end
157
158
 
158
159
  def load_config
@@ -17,6 +17,7 @@ module Immunio
17
17
  attr_reader :rejected_message_count
18
18
 
19
19
  def initialize(config)
20
+ Immunio.logger.debug { "Creating channel" }
20
21
  @config = config
21
22
 
22
23
  @agent_uuid = nil
@@ -42,6 +43,13 @@ module Immunio
42
43
  @started = false
43
44
  @ready = false
44
45
 
46
+ # In the case of a forking web server like Unicorn,
47
+ # we need to remember the process id because it may
48
+ # happen that the master process starts its polling
49
+ # thread first, for example when a request is sent
50
+ # before forking the workers.
51
+ @process_id = Process.pid
52
+
45
53
  @callbacks = []
46
54
 
47
55
  # Anything looking to add to the messages sent to the server:
@@ -67,8 +75,18 @@ module Immunio
67
75
  def start
68
76
  return if @started
69
77
 
78
+ Immunio.logger.debug { "Starting channel" }
79
+
80
+ Immunio.logger.trace { "Thread count is: #{Thread.list.size}" }
81
+ Immunio.logger.trace { "Threads: #{Thread.list.map(&:object_id)}" }
82
+ Immunio.logger.trace { "@thread in thread list?: #{Thread.list.include? @thread}" }
83
+ Immunio.logger.trace { "@process_id is: #{@process_id}" }
84
+ Immunio.logger.trace { "@thread is: #{@thread.inspect}" }
85
+
70
86
  @started = true
71
87
  @thread = Thread.new { run }
88
+
89
+ Immunio.logger.trace { "Thread count is now: #{Thread.list.size}" }
72
90
  end
73
91
 
74
92
  # Stop and wait for the last messages to be sent.
@@ -86,22 +104,45 @@ module Immunio
86
104
  end
87
105
  end
88
106
 
107
+ def needs_reset?
108
+ @process_id != Process.pid
109
+ end
110
+
111
+ def reset
112
+ Immunio.logger.debug { "Resetting channel" }
113
+
114
+ stop
115
+
116
+ @process_id = Process.pid
117
+ @message_queue.clear
118
+ end
119
+
89
120
  def send_message(message)
90
121
  send_encoded_message message.to_msgpack
91
122
  end
92
123
 
93
124
  def send_encoded_message(message)
125
+ Immunio.logger.debug do
126
+ "Queueing message: (queue size: #{@message_queue.size}, max: #{@config.max_send_queue_size})"
127
+ end
128
+
94
129
  if @message_queue.size > @config.max_send_queue_size
95
130
  Immunio.logger.warn { "Dropping message for agent manager due to queue overflow (#{@message_queue.size} > #{@config.max_send_queue_size})" }
96
- Immunio.logger.debug { "Dropped message: (#{message})" }
97
131
  # No room for this message on the queue. Discard.
98
132
  @dropped_message_count += 1
133
+ Immunio.logger.debug { "Dropped message: (#{message}, dropped count: #{@dropped_message_count})" }
99
134
  return
100
135
  end
101
136
 
102
- Immunio.logger.debug {"Sending message to backend: #{MessagePack.unpack(message)}"}
137
+ Immunio.logger.debug do
138
+ "Queueing message: message.size: #{message.size}, #{MessagePack.unpack(message)}"
139
+ end
103
140
 
104
141
  @message_queue << message
142
+
143
+ Immunio.logger.debug do
144
+ "Queueing message: (queue size now: #{@message_queue.size}, max: #{@config.max_send_queue_size})"
145
+ end
105
146
  end
106
147
 
107
148
  def on_message(&block)
@@ -140,6 +181,7 @@ module Immunio
140
181
  # Core method running in a thread
141
182
  def run
142
183
  Immunio.logger.debug { "Starting channel on thread #{Thread.current.object_id}" }
184
+
143
185
  # Create an empty cert_store to prevent Faraday from using the system default OpenSSL store.
144
186
  cert_store = OpenSSL::X509::Store.new
145
187
  # Setup the connection for making requests to the server.
@@ -263,8 +305,10 @@ module Immunio
263
305
  end
264
306
 
265
307
  def add_to_send_buffer(message)
308
+ Immunio.logger.debug { "Adding message to send buffer (bytesize: #{message.bytesize})" }
266
309
  @send_buffer_bytes += message.bytesize
267
310
  @send_buffer << message
311
+ Immunio.logger.debug { "Adding message to send buffer (send buffer size: #{@send_buffer.size})" }
268
312
  end
269
313
 
270
314
  # Fill send_buffer with messages to send
@@ -276,8 +320,10 @@ module Immunio
276
320
  add_to_send_buffer @next_message
277
321
  else
278
322
  Immunio.logger.warn { "Dropped message over max byte send size, next message size #{@next_message.bytesize}" }
279
- Immunio.logger.debug { "Dropped next message used: #{used_bytes} over max byte: #{@next_message}" }
280
323
  @dropped_message_count += 1
324
+ Immunio.logger.debug do
325
+ "Dropped next message (used: #{used_bytes} over max byte: #{@next_message}, dropped count: #{@dropped_message_count})"
326
+ end
281
327
  end
282
328
  @next_message = nil
283
329
  end
@@ -285,6 +331,9 @@ module Immunio
285
331
  # Empty the queue as much as possible.
286
332
  while !@message_queue.empty?
287
333
  @next_message = @message_queue.pop
334
+
335
+ Immunio.logger.debug { "Emptying message queue: (queue size: #{@message_queue.size})" }
336
+
288
337
  if !send_buffer_has_room used_bytes
289
338
  break
290
339
  end
@@ -303,6 +352,9 @@ module Immunio
303
352
  while @send_buffer.size < @config.min_report_size
304
353
  # If there are no messages in the queue, this will block until one arrives.
305
354
  @next_message = @message_queue.pop
355
+
356
+ Immunio.logger.debug { "Waiting for messages: (queue size: #{@message_queue.size})" }
357
+
306
358
  if !send_buffer_has_room used_bytes
307
359
  break
308
360
  end
@@ -329,6 +381,8 @@ module Immunio
329
381
 
330
382
  # Poll the server sending queued messages at the same time.
331
383
  def poll
384
+ Immunio.logger.trace { "Polling" }
385
+
332
386
  # Prep data
333
387
  body = {
334
388
  send_seq: @send_seq,
@@ -382,28 +436,35 @@ module Immunio
382
436
 
383
437
  req.body = gzip(encoded_body)
384
438
 
439
+ Immunio.logger.debug do
440
+ "Sending request to agent manager (size: #{req.body.size})"
441
+ end
385
442
  Immunio.logger.trace {"Sending request to agent manager (data: #{MessagePack.unpack(encoded_body)}, request: #{req})"}
386
443
  end
387
444
 
388
445
  if response.status >= 400 and response.status < 500 then
389
446
  # 4XX response codes should NOT be retried. Discard the report.
390
447
  @rejected_message_count += @send_buffer.size
448
+ Immunio.logger.debug { "Rejected message count is: #{@rejected_message_count}" }
391
449
  Immunio.logger.trace { "Rejecting #{@send_buffer.size} messages" }
392
450
  @send_buffer = []
393
451
  @send_buffer_bytes = 0
394
452
 
453
+ Immunio.logger.debug {"Received response from agent manager (status: #{response.status})"}
395
454
  Immunio.logger.trace {"Received response from agent manager (status: #{response.status}, raw body: #{raw_log response.body})"}
396
455
  raise Error, "Bad response from Immunio server: #{response.status} #{response.body}"
397
456
  end
398
457
 
399
458
  if response.status >= 500 then
400
459
  # 5XX response codes are treated like errors.
460
+ Immunio.logger.debug {"Received response from agent manager (status: #{response.status})"}
401
461
  Immunio.logger.trace {"Received response from agent manager (status: #{response.status}, raw body: #{raw_log response.body})"}
402
462
  raise Error, "Bad response from Immunio server: #{response.status} #{response.body}"
403
463
  end
404
464
 
405
465
  body = MessagePack.unpack(response.body)
406
466
 
467
+ Immunio.logger.debug {"Received response from agent manager (status: #{response.status})"}
407
468
  Immunio.logger.trace {"Received response from agent manager (status: #{response.status}, body: #{body}, raw body: #{raw_log response.body})"}
408
469
 
409
470
  # Update local data from response
@@ -426,7 +487,6 @@ module Immunio
426
487
  if received_messages
427
488
  received_messages.each { |message| notify message }
428
489
  end
429
-
430
490
  end
431
491
  end
432
492
  end
@@ -34,7 +34,7 @@ module Immunio
34
34
 
35
35
  def self.setup_logger_formatter
36
36
  logger.formatter = proc do |severity, datetime, _progname, msg|
37
- "[#{datetime}] #{severity}: #{msg}\n"
37
+ "[#{datetime}] [#{Process.pid} (#{Thread.current.object_id})]: #{severity}: #{msg}\n"
38
38
  end
39
39
  end
40
40
 
@@ -50,6 +50,11 @@ module Immunio
50
50
  end
51
51
 
52
52
  def new_request(request)
53
+ Immunio.logger.debug { "New request: (started: #{@channel.started?})" }
54
+
55
+ # Reset channel if it was created by parent process
56
+ @channel.reset if @channel.needs_reset?
57
+
53
58
  # Start channel on first request
54
59
  @channel.start unless @channel.started?
55
60
 
@@ -1,5 +1,5 @@
1
1
  module Immunio
2
2
  AGENT_TYPE = "agent-ruby"
3
- VERSION = "1.1.7"
3
+ VERSION = "1.1.10"
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.7
4
+ version: 1.1.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Immunio
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-01-16 00:00:00.000000000 Z
11
+ date: 2017-02-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails