aboutsummaryrefslogtreecommitdiff
path: root/ihatemoney/tests
diff options
context:
space:
mode:
author0livd <github@destras.fr>2017-08-20 12:37:12 +0200
committerAlexis Metaireau <alexis@notmyidea.org>2017-08-20 12:37:12 +0200
commitec4a099f182629d86a7421af7d4899a655be684e (patch)
treef5b72f89a3fca31f5a74b393a508d0153344a0fc /ihatemoney/tests
parent68e411473540c136dfdb269af888ceddbd0d403b (diff)
downloadihatemoney-mirror-ec4a099f182629d86a7421af7d4899a655be684e.zip
ihatemoney-mirror-ec4a099f182629d86a7421af7d4899a655be684e.tar.gz
ihatemoney-mirror-ec4a099f182629d86a7421af7d4899a655be684e.tar.bz2
Protect admin endpoints against brute force attacks (#249)
* Protect admin endpoints against brute force attacks Add a throttling mechanism to prevent a client brute forcing the authentication form, based on its ip address Closes #245 * Reset attempt counters if they get memory hungry
Diffstat (limited to 'ihatemoney/tests')
-rw-r--r--ihatemoney/tests/tests.py23
1 files changed, 23 insertions, 0 deletions
diff --git a/ihatemoney/tests/tests.py b/ihatemoney/tests/tests.py
index 5fc45a7..86f11f3 100644
--- a/ihatemoney/tests/tests.py
+++ b/ihatemoney/tests/tests.py
@@ -9,6 +9,7 @@ import os
import json
from collections import defaultdict
import six
+from time import sleep
from werkzeug.security import generate_password_hash
from flask import session
@@ -397,6 +398,28 @@ class BudgetTestCase(IhatemoneyTestCase):
resp = self.client.post("/admin?goto=%2Fcreate", data={'admin_password': ''})
self.assertNotIn('<a href="/create">/create</a>', resp.data.decode('utf-8'))
+ def test_login_throttler(self):
+ self.app.config['ADMIN_PASSWORD'] = generate_password_hash("pass")
+
+ # Authenticate 3 times with a wrong passsword
+ self.client.post("/admin?goto=%2Fcreate", data={'admin_password': 'wrong'})
+ self.client.post("/admin?goto=%2Fcreate", data={'admin_password': 'wrong'})
+ resp = self.client.post("/admin?goto=%2Fcreate", data={'admin_password': 'wrong'})
+
+ self.assertIn('Too many failed login attempts, please retry later.',
+ resp.data.decode('utf-8'))
+ # Change throttling delay
+ import gc
+ for obj in gc.get_objects():
+ if isinstance(obj, utils.LoginThrottler):
+ obj._delay = 0.005
+ break
+ # Wait for delay to expire and retry logging in
+ sleep(1)
+ resp = self.client.post("/admin?goto=%2Fcreate", data={'admin_password': 'wrong'})
+ self.assertNotIn('Too many failed login attempts, please retry later.',
+ resp.data.decode('utf-8'))
+
def test_manage_bills(self):
self.post_project("raclette")