Skip to content
This repository was archived by the owner on Jun 1, 2023. It is now read-only.

Commit c7ed781

Browse files
committed
Support for SameSite in cookies.
1 parent 9381db1 commit c7ed781

File tree

3 files changed

+44
-3
lines changed

3 files changed

+44
-3
lines changed

Diff for: src/oidcrp/cookie.py

+20-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import hmac
44
import logging
55
import os
6+
import sys
67
import time
78

89
from http.cookies import SimpleCookie
@@ -107,7 +108,7 @@ def _make_hashed_key(parts, hashfunc='sha256'):
107108

108109

109110
def make_cookie(name, load, seed, expire=0, domain="", path="", timestamp="",
110-
enc_key=None):
111+
enc_key=None, secure=True, http_only=True, same_site=""):
111112
"""
112113
Create and return a cookie
113114
@@ -137,6 +138,13 @@ def make_cookie(name, load, seed, expire=0, domain="", path="", timestamp="",
137138
:type timestamp: text
138139
:param enc_key: The key to use for cookie encryption.
139140
:type enc_key: byte string
141+
:param secure: A secure cookie is only sent to the server with an encrypted request over the
142+
HTTPS protocol.
143+
:type secure: boolean
144+
:param http_only: HttpOnly cookies are inaccessible to JavaScript's Document.cookie API
145+
:type http_only: boolean
146+
:param same_site: Whether SameSite (None,Strict or Lax) should be added to the cookie
147+
:type same_site: byte string
140148
:return: A tuple to be added to headers
141149
"""
142150
cookie = SimpleCookie()
@@ -172,13 +180,24 @@ def make_cookie(name, load, seed, expire=0, domain="", path="", timestamp="",
172180
cookie_signature(seed, load, timestamp).encode('utf-8')]
173181

174182
cookie[name] = (b"|".join(cookie_payload)).decode('utf-8')
183+
184+
# Necessary if Python version < 3.8
185+
if sys.version_info[:2] <= (3, 8):
186+
cookie[name]._reserved[str("samesite")] = str("SameSite")
187+
175188
if path:
176189
cookie[name]["path"] = path
177190
if domain:
178191
cookie[name]["domain"] = domain
179192
if expire:
180193
cookie[name]["expires"] = _expiration(expire,
181194
"%a, %d-%b-%Y %H:%M:%S GMT")
195+
if secure:
196+
cookie[name]["Secure"] = secure
197+
if http_only:
198+
cookie[name]["httponly"] = http_only
199+
if same_site:
200+
cookie[name]["SameSite"] = same_site
182201

183202
return tuple(cookie.output().split(": ", 1))
184203

Diff for: tests/test_02_cookie.py

+24
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from http.cookies import SimpleCookie
33

44
import pytest
5+
from oidcrp.cookie import make_cookie
56

67
from oidcservice.exception import ImproperlyConfigured
78
from oidcrp.cookie import CookieDealer
@@ -143,3 +144,26 @@ def test_cookie_parts():
143144
'1463043535',
144145
'18a201305fa15a96ce4048e1fbb03f7715f86499']
145146

147+
148+
def test_cookie_default():
149+
kaka = make_cookie('test', "data", b"1234567890abcdefg")
150+
assert "Secure" in kaka[1]
151+
assert "HttpOnly" in kaka[1]
152+
assert "SameSite" not in kaka[1]
153+
154+
155+
def test_cookie_http_only_false():
156+
kaka = make_cookie('test', "data", b"1234567890abcdefg", http_only=False)
157+
assert "Secure" in kaka[1]
158+
assert "HttpOnly" not in kaka[1]
159+
160+
161+
def test_cookie_not_secure():
162+
kaka = make_cookie('test', "data", b"1234567890abcdefg", secure=False)
163+
assert "Secure" not in kaka[1]
164+
assert "HttpOnly" in kaka[1]
165+
166+
167+
def test_cookie_same_site_none():
168+
kaka = make_cookie('test', "data", b"1234567890abcdefg", same_site="None")
169+
assert "SameSite=None" in kaka[1]

Diff for: tests/test_14_oidc.py

-2
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,8 @@
44
import time
55

66
import pytest
7-
87
from cryptojwt.jwk.rsa import import_private_rsa_key_from_file
98
from cryptojwt.key_bundle import KeyBundle
10-
119
from oidcmsg.oauth2 import AccessTokenRequest
1210
from oidcmsg.oauth2 import AccessTokenResponse
1311
from oidcmsg.oauth2 import AuthorizationRequest

0 commit comments

Comments
 (0)