From d4ee127ea4d674062fa7ed3da753c19396077f26 Mon Sep 17 00:00:00 2001 From: Slava Bacherikov Date: Wed, 11 Sep 2013 19:08:39 +0300 Subject: [PATCH 1/3] Update .gitignore, add rules for vim, coverage, tox and python eggs --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) 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 From b5dcefbdb50b6ede90e8e070133d26f0f48f039b Mon Sep 17 00:00:00 2001 From: Slava Bacherikov Date: Wed, 11 Sep 2013 19:11:58 +0300 Subject: [PATCH 2/3] Add tests for broken csrf_token --- tests/test_csrf.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) 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) From 91f70259660a106a49cd8cc2ccd137d47c9c393d Mon Sep 17 00:00:00 2001 From: Slava Bacherikov Date: Wed, 11 Sep 2013 19:16:07 +0300 Subject: [PATCH 3/3] Fix bugs with broken csrf_token --- flask_wtf/csrf.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) 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),