Repository: CTFd/CTFd
Pull request #824 (2019-01-08 07:10:20)

Default SameSite session cookie setting to Lax

codecov[bot]: # [Codecov](https://codecov.io/gh/CTFd/CTFd/pull/824?src=pr&el=h1) Report
> Merging [#824](https://codecov.io/gh/CTFd/CTFd/pull/824?src=pr&el=desc) into [master](https://codecov.io/gh/CTFd/CTFd/commit/9f7dc0543c24481b84a836c68a3d8b8afc511745?src=pr&el=desc) will **increase** coverage by `0.05%`.
> The diff coverage is `100%`.

[![Impacted file tree graph](https://codecov.io/gh/CTFd/CTFd/pull/824/graphs/tree.svg?width=650&token=IfPqkWkt9A&height=150&src=pr)](https://codecov.io/gh/CTFd/CTFd/pull/824?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master     #824      +/-   ##
==========================================
+ Coverage    84.8%   84.85%   +0.05%     
==========================================
  Files          91       91              
  Lines        4555     4557       +2     
==========================================
+ Hits         3863     3867       +4     
+ Misses        692      690       -2
```


| [Impacted Files](https://codecov.io/gh/CTFd/CTFd/pull/824?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [CTFd/utils/sessions/\_\_init\_\_.py](https://codecov.io/gh/CTFd/CTFd/pull/824/diff?src=pr&el=tree#diff-Q1RGZC91dGlscy9zZXNzaW9ucy9fX2luaXRfXy5weQ==) | `92.42% <100%> (+0.11%)` | :arrow_up: |
| [CTFd/config.py](https://codecov.io/gh/CTFd/CTFd/pull/824/diff?src=pr&el=tree#diff-Q1RGZC9jb25maWcucHk=) | `88.23% <100%> (+0.17%)` | :arrow_up: |
| [CTFd/utils/updates/\_\_init\_\_.py](https://codecov.io/gh/CTFd/CTFd/pull/824/diff?src=pr&el=tree#diff-Q1RGZC91dGlscy91cGRhdGVzL19faW5pdF9fLnB5) | `84.61% <0%> (+5.12%)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/CTFd/CTFd/pull/824?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/CTFd/CTFd/pull/824?src=pr&el=footer). Last update [9f7dc05...0c0c0cb](https://codecov.io/gh/CTFd/CTFd/pull/824?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/CTFd/config.py b/CTFd/config.py
index f0bbdda7..1a443415 100644
--- a/CTFd/config.py
+++ b/CTFd/config.py
@@ -93,6 +93,7 @@ class Config(object):
         solely on IP addresses unless you know what you are doing.
     '''
     SESSION_COOKIE_HTTPONLY = (not os.getenv("SESSION_COOKIE_HTTPONLY"))  # Defaults True
+    SESSION_COOKIE_SAMESITE = os.getenv("SESSION_COOKIE_SAMESITE") or 'Lax'
     PERMANENT_SESSION_LIFETIME = int(os.getenv("PERMANENT_SESSION_LIFETIME") or 604800)  # 7 days in seconds
     TRUSTED_PROXIES = [
         r'^127\.0\.0\.1$',
diff --git a/CTFd/utils/sessions/__init__.py b/CTFd/utils/sessions/__init__.py
index f332cdcd..9ea33872 100644
--- a/CTFd/utils/sessions/__init__.py
+++ b/CTFd/utils/sessions/__init__.py
@@ -88,6 +88,7 @@ class CachingSessionInterface(SessionInterface):
             httponly = self.get_cookie_httponly(app)
             secure = self.get_cookie_secure(app)
             expires = self.get_expiration_time(app, session)
+            samesite = self.get_cookie_samesite(app)
             val = self.serializer.dumps(dict(session))
 
             if session.sid is None:
@@ -102,5 +103,6 @@ class CachingSessionInterface(SessionInterface):
                 httponly=httponly,
                 domain=domain,
                 path=path,
-                secure=secure
+                secure=secure,
+                samesite=samesite
             )


Test patch:
diff --git a/tests/utils/test_sessions.py b/tests/utils/test_sessions.py
new file mode 100644
index 00000000..e3b51d4e
--- /dev/null
+++ b/tests/utils/test_sessions.py
@@ -0,0 +1,21 @@
+from tests.helpers import *
+
+
+def test_sessions_set_httponly():
+    app = create_ctfd()
+    with app.app_context():
+        with app.test_client() as client:
+            r = client.get('/')
+            cookie = dict(r.headers)['Set-Cookie']
+            assert 'HttpOnly;' in cookie
+    destroy_ctfd(app)
+
+
+def test_sessions_set_samesite():
+    app = create_ctfd()
+    with app.app_context():
+        with app.test_client() as client:
+            r = client.get('/')
+            cookie = dict(r.headers)['Set-Cookie']
+            assert 'SameSite=' in cookie
+    destroy_ctfd(app)