diff --git a/.gitignore b/.gitignore index 39e44d60..9be2b91d 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,7 @@ src/* cover/ venv/ _build +*.sw[op] +.coverage +.tox +*.egg diff --git a/flask_wtf/csrf.py b/flask_wtf/csrf.py index a85dcdd2..5d456362 100644 --- a/flask_wtf/csrf.py +++ b/flask_wtf/csrf.py @@ -73,7 +73,7 @@ def validate_csrf(data, secret_key=None, time_limit=None): if not data or '##' not in data: return False - expires, hmac_csrf = data.split('##') + expires, hmac_csrf = data.split('##', 1) try: expires = float(expires) except: @@ -92,6 +92,9 @@ def validate_csrf(data, secret_key=None, time_limit=None): 'WTF_CSRF_SECRET_KEY', current_app.secret_key ) + if 'csrf_token' not in session: + return False + csrf_build = '%s%s' % (session['csrf_token'], expires) hmac_compare = hmac.new( to_bytes(secret_key), diff --git a/tests/test_csrf.py b/tests/test_csrf.py index 674c64c1..4e904e11 100644 --- a/tests/test_csrf.py +++ b/tests/test_csrf.py @@ -52,6 +52,24 @@ def invalid(reason): assert response.status_code == 200 assert 'token missing' in to_unicode(response.data) + def test_invalid_csrf2(self): + # tests with bad token + response = self.client.post("/", data={ + "name": "danny", + "csrf_token": "9999999999999##test" + # will work only if greater than time.time() + }) + assert response.status_code == 400 + + def test_invalid_secure_csrf3(self): + # test with multiple separators + response = self.client.post("/", data={ + "name": "danny", + "csrf_token": "1378915137.722##foo##bar##and" + # will work only if greater than time.time() + }) + assert response.status_code == 400 + def test_valid_csrf(self): response = self.client.get("/") csrf_token = get_csrf_token(response.data)