Skip to content

Commit

Permalink
Merge pull request #872 from uc-cdis/feat/httponlycookies
Browse files Browse the repository at this point in the history
feat(cookies): always set httponly flag on cookies (also update deps) PXP-7593
  • Loading branch information
Avantol13 committed Feb 10, 2021
2 parents 1bcbc45 + 473aef9 commit d0fe6fc
Show file tree
Hide file tree
Showing 7 changed files with 233 additions and 169 deletions.
2 changes: 1 addition & 1 deletion fence/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,7 @@ def set_csrf(response):
"""
if not flask.request.cookies.get("csrftoken"):
secure = config.get("SESSION_COOKIE_SECURE", True)
response.set_cookie("csrftoken", random_str(40), secure=secure)
response.set_cookie("csrftoken", random_str(40), secure=secure, httponly=True)

if flask.request.method in ["POST", "PUT", "DELETE"]:
current_session.commit()
Expand Down
2 changes: 1 addition & 1 deletion fence/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ def clear_cookies(response):
Set all cookies to empty and expired.
"""
for cookie_name in list(flask.request.cookies.keys()):
response.set_cookie(cookie_name, "", expires=0)
response.set_cookie(cookie_name, "", expires=0, httponly=True)


def get_error_params(error, description):
Expand Down
312 changes: 166 additions & 146 deletions poetry.lock

Large diffs are not rendered by default.

36 changes: 27 additions & 9 deletions tests/link/test_link.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,9 @@ def test_google_link_auth_return(
)

# manually set cookie for initial session
client.set_cookie("localhost", config["SESSION_COOKIE_NAME"], test_session_jwt)
client.set_cookie(
"localhost", config["SESSION_COOKIE_NAME"], test_session_jwt, httponly=True
)

# simulate successfully authed reponse with user email
google_auth_get_user_info_mock.return_value = {"email": google_account}
Expand Down Expand Up @@ -251,7 +253,9 @@ def test_patch_google_link(
db_session.commit()

# manually set cookie for initial session
client.set_cookie("localhost", config["SESSION_COOKIE_NAME"], test_session_jwt)
client.set_cookie(
"localhost", config["SESSION_COOKIE_NAME"], test_session_jwt, httponly=True
)

r = client.patch(
"/link/google", headers={"Authorization": "Bearer " + encoded_credentials_jwt}
Expand Down Expand Up @@ -349,7 +353,9 @@ def test_patch_google_link_account_not_in_token(
db_session.commit()

# manually set cookie for initial session
client.set_cookie("localhost", config["SESSION_COOKIE_NAME"], test_session_jwt)
client.set_cookie(
"localhost", config["SESSION_COOKIE_NAME"], test_session_jwt, httponly=True
)

r = client.patch(
"/link/google", headers={"Authorization": "Bearer " + encoded_credentials_jwt}
Expand Down Expand Up @@ -399,7 +405,9 @@ def test_patch_google_link_account_doesnt_exist(
)

# manually set cookie for initial session
client.set_cookie("localhost", config["SESSION_COOKIE_NAME"], test_session_jwt)
client.set_cookie(
"localhost", config["SESSION_COOKIE_NAME"], test_session_jwt, httponly=True
)

r = client.patch(
"/link/google", headers={"Authorization": "Bearer " + encoded_credentials_jwt}
Expand Down Expand Up @@ -462,7 +470,9 @@ def test_google_link_g_account_exists(
db_session.commit()

# manually set cookie for initial session
client.set_cookie("localhost", config["SESSION_COOKIE_NAME"], test_session_jwt)
client.set_cookie(
"localhost", config["SESSION_COOKIE_NAME"], test_session_jwt, httponly=True
)

# simulate successfully authed reponse with user email
google_auth_get_user_info_mock.return_value = {"email": google_account}
Expand Down Expand Up @@ -535,7 +545,9 @@ def test_google_link_g_account_access_extension(
db_session.commit()

# manually set cookie for initial session
client.set_cookie("localhost", config["SESSION_COOKIE_NAME"], test_session_jwt)
client.set_cookie(
"localhost", config["SESSION_COOKIE_NAME"], test_session_jwt, httponly=True
)

# simulate successfully authed reponse with user email
google_auth_get_user_info_mock.return_value = {"email": google_account}
Expand Down Expand Up @@ -616,7 +628,9 @@ def test_google_link_g_account_exists_linked_to_different_user(
db_session.commit()

# manually set cookie for initial session
client.set_cookie("localhost", config["SESSION_COOKIE_NAME"], test_session_jwt)
client.set_cookie(
"localhost", config["SESSION_COOKIE_NAME"], test_session_jwt, httponly=True
)

# simulate successfully authed reponse with user email
google_auth_get_user_info_mock.return_value = {"email": google_account}
Expand Down Expand Up @@ -678,7 +692,9 @@ def test_google_link_no_proxy_group(
db_session.commit()

# manually set cookie for initial session
client.set_cookie("localhost", config["SESSION_COOKIE_NAME"], test_session_jwt)
client.set_cookie(
"localhost", config["SESSION_COOKIE_NAME"], test_session_jwt, httponly=True
)

# simulate successfully authed reponse with user email
google_auth_get_user_info_mock.return_value = {"email": google_account}
Expand Down Expand Up @@ -758,7 +774,9 @@ def test_google_link_when_google_mocked(
)

# manually set cookie for initial session
client.set_cookie("localhost", config["SESSION_COOKIE_NAME"], test_session_jwt)
client.set_cookie(
"localhost", config["SESSION_COOKIE_NAME"], test_session_jwt, httponly=True
)

headers = {"Authorization": "Bearer " + encoded_creds_jwt.jwt}

Expand Down
4 changes: 3 additions & 1 deletion tests/login/test_google_login.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ def test_google_login_http_headers_are_less_than_4k_for_user_with_many_projects(
"redirect": "https://localhost/user/oauth2/authorize?client_id=7f7kAS4MJraUuo77d7RWHr4mZ6bvGtuzup7hw46I&response_type=id_token&redirect_uri=https://webapp.example/fence&scope=openid+user+data+google_credentials&nonce=randomvalue"
},
)
client.set_cookie("localhost", config["SESSION_COOKIE_NAME"], test_session_jwt)
client.set_cookie(
"localhost", config["SESSION_COOKIE_NAME"], test_session_jwt, httponly=True
)

user_projects = {
"test": {
Expand Down
42 changes: 32 additions & 10 deletions tests/session/test_session.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,9 @@ def test_valid_session(app):
# the username
with app.test_client() as client:
# manually set cookie for initial session
client.set_cookie("localhost", config["SESSION_COOKIE_NAME"], test_session_jwt)
client.set_cookie(
"localhost", config["SESSION_COOKIE_NAME"], test_session_jwt, httponly=True
)
with client.session_transaction() as session:
assert session["username"] == username

Expand All @@ -75,7 +77,9 @@ def test_valid_session_modified(app):
# the username
with app.test_client() as client:
# manually set cookie for initial session
client.set_cookie("localhost", config["SESSION_COOKIE_NAME"], test_session_jwt)
client.set_cookie(
"localhost", config["SESSION_COOKIE_NAME"], test_session_jwt, httponly=True
)
with client.session_transaction() as session:

assert session["username"] == username
Expand All @@ -100,7 +104,9 @@ def test_expired_session_lifetime(app):

with app.test_client() as client:
# manually set cookie for initial session
client.set_cookie("localhost", config["SESSION_COOKIE_NAME"], test_session_jwt)
client.set_cookie(
"localhost", config["SESSION_COOKIE_NAME"], test_session_jwt, httponly=True
)
with client.session_transaction() as session:
# make sure we don't have the username when opening
# the session, since it has expired
Expand All @@ -127,7 +133,9 @@ def test_expired_session_timeout(app):

with app.test_client() as client:
# manually set cookie for initial session
client.set_cookie("localhost", config["SESSION_COOKIE_NAME"], test_session_jwt)
client.set_cookie(
"localhost", config["SESSION_COOKIE_NAME"], test_session_jwt, httponly=True
)
with client.session_transaction() as session:
# make sure we don't have the username when opening
# the session, since it has expired
Expand All @@ -145,7 +153,9 @@ def test_session_cleared(app):
# the username
with app.test_client() as client:
# manually set cookie for initial session
client.set_cookie("localhost", config["SESSION_COOKIE_NAME"], test_session_jwt)
client.set_cookie(
"localhost", config["SESSION_COOKIE_NAME"], test_session_jwt, httponly=True
)
with client.session_transaction() as session:
session["username"] = username
session.clear()
Expand All @@ -161,7 +171,9 @@ def test_invalid_session_cookie(app):
# the username
with app.test_client() as client:
# manually set cookie for initial session
client.set_cookie("localhost", config["SESSION_COOKIE_NAME"], test_session_jwt)
client.set_cookie(
"localhost", config["SESSION_COOKIE_NAME"], test_session_jwt, httponly=True
)
with client.session_transaction() as session:
# main test is that we haven't raised an exception by this point

Expand Down Expand Up @@ -199,9 +211,14 @@ def test_valid_session_valid_access_token(
# the username
with app.test_client() as client:
# manually set cookie for initial session
client.set_cookie("localhost", config["SESSION_COOKIE_NAME"], test_session_jwt)
client.set_cookie(
"localhost", config["ACCESS_TOKEN_COOKIE_NAME"], test_access_jwt
"localhost", config["SESSION_COOKIE_NAME"], test_session_jwt, httponly=True
)
client.set_cookie(
"localhost",
config["ACCESS_TOKEN_COOKIE_NAME"],
test_access_jwt,
httponly=True,
)

response = client.get("/user")
Expand Down Expand Up @@ -242,9 +259,14 @@ def test_valid_session_valid_access_token_diff_user(

with app.test_client() as client:
# manually set cookie for initial session
client.set_cookie("localhost", config["SESSION_COOKIE_NAME"], test_session_jwt)
client.set_cookie(
"localhost", config["ACCESS_TOKEN_COOKIE_NAME"], test_access_jwt
"localhost", config["SESSION_COOKIE_NAME"], test_session_jwt, httponly=True
)
client.set_cookie(
"localhost",
config["ACCESS_TOKEN_COOKIE_NAME"],
test_access_jwt,
httponly=True,
)

response = client.get("/user")
Expand Down
4 changes: 3 additions & 1 deletion tests/test_logout.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,9 @@ def test_logout_fence(app, client, user_with_fence_provider, monkeypatch):
# this redirect valid
with mock.patch("fence.allowed_login_redirects", return_value={"some_site.com"}):
# manually set cookie for initial session
client.set_cookie("localhost", config["SESSION_COOKIE_NAME"], test_session_jwt)
client.set_cookie(
"localhost", config["SESSION_COOKIE_NAME"], test_session_jwt, httponly=True
)

r = client.get("/logout?next={}".format(redirect))
assert r.status_code == 302
Expand Down

0 comments on commit d0fe6fc

Please sign in to comment.