Skip to content

Commit 3763771

Browse files
committed
Change config defaults for cookies.
Best practice these days is to set ``secure=True``. This changes CSRF_COOKIE and TF_VALIDITY_COOKIE. Also - TF_VALIDITY_COOKIE name is now configurable. close #1228
1 parent 1a5ae5c commit 3763771

6 files changed

Lines changed: 42 additions & 18 deletions

File tree

CHANGES.rst

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ Features & Improvements
1313
- (:issue:`1206`) Add support for refresh tokens. See :ref:`token_topic`
1414
- (:pr:`1233`) Change :py:data:`SECURITY_TOKEN_MAX_AGE` from an int to a timedelta.
1515
Also - change default from ``never expire`` to 15 minutes.
16-
- (:pr:`xx`) Change default LOGOUT_METHODS to be just ``"POST"``
16+
- (:pr:`1235`) Change default LOGOUT_METHODS to be just ``"POST"``
17+
- (:issue:`1228`) Change default ``csrf`` and ``tf_validity`` cookie config to ``secure=True``
18+
- (:issue:`1228`) The ``tf_validity`` cookie name is now configurable via :py:data:`SECURITY_TWO_FACTOR_VALIDITY_COOKIE_NAME`
1719

1820
Fixes
1921
+++++
@@ -35,6 +37,10 @@ Backwards Compatibility Concerns
3537
feature.
3638
- The default for :py:data:`SECURITY_LOGOUT_METHODS` has been changed to just
3739
allowing ``"POST"``. This is considered modern best practice.
40+
- The default configuration for :py:data:`SECURITY_TWO_FACTOR_VALIDITY_COOKIE`
41+
has been change to ``secure=True``.
42+
- The default configuration for :py:data:`SECURITY_CSRF_COOKIE` has been
43+
changed to ``secure=True``
3844

3945
Notes
4046
+++++

docs/configuration.rst

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -282,12 +282,15 @@ These configuration keys are used globally across all features.
282282
set a CSRF cookie.
283283
The complete set of parameters is described in Flask's `set_cookie`_ documentation.
284284

285-
Default: ``{"samesite": "Strict", "httponly": False, "secure": False}``
285+
Default: ``{"samesite": "Strict", "httponly": False, "secure": True}``
286286

287287
.. versionchanged:: 4.1.0
288288
The 'key' attribute was deprecated in favor of a separate configuration
289289
variable :data:`SECURITY_CSRF_COOKIE_NAME`.
290290

291+
.. versionchanged:: 5.9.0
292+
``secure`` default changed to ``True``
293+
291294
.. py:data:: SECURITY_CSRF_HEADER
292295
293296
The HTTP Header name that will contain the CSRF token. ``X-XSRF-Token``
@@ -1436,12 +1439,24 @@ Configuration related to the two-factor authentication feature.
14361439
Default: ``"30 Days"``.
14371440

14381441

1442+
.. py:data:: SECURITY_TWO_FACTOR_VALIDITY_COOKIE_NAME
1443+
1444+
Name for the two factor validity cookie.
1445+
1446+
Default: ``tf_validity``
1447+
1448+
.. versionadded:: 5.9.0
1449+
14391450
.. py:data:: SECURITY_TWO_FACTOR_VALIDITY_COOKIE
14401451
14411452
A dictionary containing the parameters of the two-factor validity cookie.
14421453
The complete set of parameters is described in Flask's `set_cookie`_ documentation.
14431454

1444-
Default: ``{'httponly': True, 'secure': False, 'samesite': None}``.
1455+
Default: ``{'httponly': True, 'secure': True, 'samesite': "Strict"}``.
1456+
1457+
1458+
.. versionchanged:: 5.9.0
1459+
``secure`` default changed to ``True``. ``samesite`` default changed to ``Strict``
14451460

14461461
.. py:data:: SECURITY_TWO_FACTOR_IMPLEMENTATIONS
14471462

flask_security/core.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -260,9 +260,10 @@
260260
"TWO_FACTOR_ALWAYS_VALIDATE": True,
261261
"TWO_FACTOR_LOGIN_VALIDITY": "30 days",
262262
"TWO_FACTOR_VALIDITY_SALT": "tf-validity-salt",
263+
"TWO_FACTOR_VALIDITY_COOKIE_NAME": "tf_validity",
263264
"TWO_FACTOR_VALIDITY_COOKIE": {
264265
"httponly": True,
265-
"secure": False,
266+
"secure": True,
266267
"samesite": "Strict",
267268
},
268269
"TWO_FACTOR_SETUP_SALT": "tf-setup-salt",
@@ -378,7 +379,7 @@
378379
"CSRF_COOKIE": {
379380
"samesite": "Strict",
380381
"httponly": False,
381-
"secure": False,
382+
"secure": True,
382383
},
383384
"CSRF_HEADER": "X-XSRF-Token",
384385
"CSRF_COOKIE_REFRESH_EACH_REQUEST": False,

flask_security/tf_plugin.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ def tf_verify_validity_token(fs_uniquifier: str) -> bool:
290290
291291
:param fs_uniquifier: The ``fs_uniquifier`` of the submitting user.
292292
"""
293-
token = request.cookies.get("tf_validity", default=None)
293+
token = request.cookies.get(cv("TWO_FACTOR_VALIDITY_COOKIE_NAME"), default=None)
294294
if token is None:
295295
return False
296296

@@ -302,15 +302,15 @@ def tf_verify_validity_token(fs_uniquifier: str) -> bool:
302302

303303

304304
def tf_set_validity_token_cookie(response: Response, token: str) -> Response:
305-
"""Sets the Two-Factor validity token for a specific user given that is
306-
configured and the user selects remember me
307-
308-
:param response: The response with which to set the set_cookie
309-
:param token: validity token
310-
"""
305+
"""Sets the Two-Factor validity cookie"""
311306
cookie_kwargs = cv("TWO_FACTOR_VALIDITY_COOKIE")
312307
max_age = int(get_within_delta("TWO_FACTOR_LOGIN_VALIDITY").total_seconds())
313-
response.set_cookie("tf_validity", value=token, max_age=max_age, **cookie_kwargs)
308+
response.set_cookie(
309+
cv("TWO_FACTOR_VALIDITY_COOKIE_NAME"),
310+
value=token,
311+
max_age=max_age,
312+
**cookie_kwargs,
313+
)
314314
# This is likely overkill since so far we only return this on a POST which is
315315
# unlikely to be cached.
316316
response.vary.add("Cookie")

tests/test_two_factor.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,10 +91,12 @@ def tf_in_session(session):
9191
)
9292

9393

94-
@pytest.mark.settings(two_factor_always_validate=False)
94+
@pytest.mark.settings(
95+
two_factor_always_validate=False, two_factor_validity_cookie_name="tfv"
96+
)
9597
def test_always_validate(app, client, get_message):
9698
tf_authenticate(app, client, remember=True)
97-
assert client.get_cookie("tf_validity")
99+
assert client.get_cookie(app.config["SECURITY_TWO_FACTOR_VALIDITY_COOKIE_NAME"])
98100

99101
logout(client)
100102

@@ -109,7 +111,7 @@ def test_always_validate(app, client, get_message):
109111
assert b"Please enter your authentication code" in response.data
110112

111113
# make sure the cookie doesn't affect the JSON request
112-
client.delete_cookie("tf_validity")
114+
client.delete_cookie(app.config["SECURITY_TWO_FACTOR_VALIDITY_COOKIE_NAME"])
113115
# Test JSON (this authenticates gal@lp.com)
114116
tf_authenticate(app, client, json=True, remember=True)
115117
logout(client)

tests/test_unified_signin.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1857,10 +1857,10 @@ def test_totp_generation(app, client, get_message):
18571857
)
18581858
def test_us_tf_validity(app, client, get_message):
18591859
us_tf_authenticate(app, client, remember=True)
1860-
assert client.get_cookie("tf_validity")
1860+
assert client.get_cookie(app.config["SECURITY_TWO_FACTOR_VALIDITY_COOKIE_NAME"])
18611861
logout(client)
18621862
# logout does NOT remove this cookie
1863-
assert client.get_cookie("tf_validity")
1863+
assert client.get_cookie(app.config["SECURITY_TWO_FACTOR_VALIDITY_COOKIE_NAME"])
18641864

18651865
# This time shouldn't require code
18661866
data = dict(identity="gal@lp.com", passcode="password")

0 commit comments

Comments
 (0)