Skip to content

Commit

Permalink
reduce exp back off level and increase base limit
Browse files Browse the repository at this point in the history
relaxing limits would ensure legitimate requests don't get throttled.

with max of 600 allowed req, otp key could be guessed at least once
with more than 50% probability after ~1180 trials[1]. Previously, it
would have taken (1180 * 1000000 seconds) 37 years, now it would take
(1180 * 90000 seconds) 3.3 years. This should be good enough for our
purpose.

[1] trail - guessing otp key by trying all combinations in the given
period.
prob of success = no of keys tried/total possible keys = 600/100_000 =
0.0006

Suppose a binomial experiment consists of n trials and results in x
successes.
If the probability of success on an individual trial is P, then the
binomial probability is:
b(x; n, P) = nCx * P^x * (1 - P)^(n - x)

in our case, n = 1180, P = 0.0006, x = 1

b(1) = 1180 * 0.0006 * 0.9994^1179 = 0.34891620349

b(at least 1 success) = b(1) + b(2) + ... b(100_000) = 0.50747619524
  • Loading branch information
sonalkr132 committed Jun 13, 2020
1 parent 8ec615f commit adcd717
Show file tree
Hide file tree
Showing 2 changed files with 6 additions and 7 deletions.
11 changes: 5 additions & 6 deletions config/initializers/rack_attack.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
class Rack::Attack
REQUEST_LIMIT = 100
EXP_BASE_REQUEST_LIMIT = 200
EXP_BASE_REQUEST_LIMIT = 300
PUSH_LIMIT = 150
REQUEST_LIMIT_PER_EMAIL = 10
LIMIT_PERIOD = 10.minutes
PUSH_LIMIT_PERIOD = 60.minutes
EXP_BASE_LIMIT_PERIOD = 100.seconds
EXP_BACKOFF_LEVELS = [1, 2, 3].freeze
EXP_BASE_LIMIT_PERIOD = 300.seconds
EXP_BACKOFF_LEVELS = [1, 2].freeze
PUSH_EXP_THROTTLE_KEY = "api/exp/push/ip".freeze

### Prevent Brute-Force Login Attacks ###
Expand Down Expand Up @@ -60,9 +60,8 @@ def self.protected_route?(protected_actions, path, method)
req.ip if protected_route?(protected_ui_actions, req.path, req.request_method)
end

# 200 req in 100 seconds
# 400 req in 10000 seconds (2.7 hours)
# 600 req in 1000000 seconds (277.7 hours)
# 300 req in 300 seconds
# 600 req in 90000 seconds (25 hours)
EXP_BACKOFF_LEVELS.each do |level|
throttle("clearance/ip/#{level}", limit: EXP_BASE_REQUEST_LIMIT * level, period: (EXP_BASE_LIMIT_PERIOD**level).seconds) do |req|
req.ip if protected_route?(protected_ui_mfa_actions, req.path, req.request_method)
Expand Down
2 changes: 1 addition & 1 deletion test/integration/rack_attack_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ class RackAttackTest < ActionDispatch::IntegrationTest
end

context "exponential backoff" do
setup { @mfa_max_period = { 1 => 100, 2 => 10_000, 3 => 1_000_000 } }
setup { @mfa_max_period = { 1 => 300, 2 => 90_000 } }

Rack::Attack::EXP_BACKOFF_LEVELS.each do |level|
should "throttle for mfa sign in at level #{level}" do
Expand Down

0 comments on commit adcd717

Please sign in to comment.