Class: Aikido::Zen::Middleware::AttackWaveProtector

Inherits:
Object
  • Object
show all
Defined in:
lib/aikido/zen/middleware/attack_wave_protector.rb

Instance Method Summary collapse

Constructor Details

#initialize(app, zen: Aikido::Zen, settings: Aikido::Zen.runtime_settings) ⇒ AttackWaveProtector

Returns a new instance of AttackWaveProtector.



7
8
9
10
11
# File 'lib/aikido/zen/middleware/attack_wave_protector.rb', line 7

def initialize(app, zen: Aikido::Zen, settings: Aikido::Zen.runtime_settings)
  @app = app
  @zen = zen
  @settings = settings
end

Instance Method Details

#attack_wave?(context) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Visible for testing.

Returns:

  • (Boolean)


24
25
26
27
28
29
30
31
# File 'lib/aikido/zen/middleware/attack_wave_protector.rb', line 24

def attack_wave?(context)
  request = context.request
  return false if request.nil?

  return false if @settings.bypassed_ips.include?(request.client_ip)

  @zen.attack_wave_detector.attack_wave?(context)
end

#call(env) ⇒ Object



13
14
15
16
17
18
19
20
# File 'lib/aikido/zen/middleware/attack_wave_protector.rb', line 13

def call(env)
  response = @app.call(env)

  context = @zen.current_context
  protect(context)

  response
end

#protect(context) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Visible for testing.



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/aikido/zen/middleware/attack_wave_protector.rb', line 35

def protect(context)
  if attack_wave?(context)
    client_ip = context.request.client_ip

    request = Aikido::Zen::AttackWave::Request.new(
      ip_address: client_ip,
      user_agent: context.request.user_agent,
      source: context.request.framework
    )

    samples = @zen.attack_wave_detector.samples[client_ip].to_a

    attack = Aikido::Zen::AttackWave::Attack.new(
      samples: samples,
      user: context.request.actor
    )

    attack_wave = Aikido::Zen::Events::AttackWave.new(
      request: request,
      attack: attack
    )

    @zen.track_attack_wave(attack_wave)
    @zen.agent.report(attack_wave)
  end
end