Remove keys from session and inject Session class into Jinja (#1456)

* Closes #1362
* Reduces the session object to just an id, nonce, and security hash
This commit is contained in:
Kevin Chung
2020-06-03 02:09:48 -04:00
committed by GitHub
parent 2a8d7ed349
commit 52c65ced55
7 changed files with 27 additions and 22 deletions

View File

@@ -0,0 +1,18 @@
from flask import session
class _SessionWrapper:
@property
def id(self):
return session.get("id", 0)
@property
def nonce(self):
return session.get("nonce")
@property
def hash(self):
return session.get("hash")
Session = _SessionWrapper()

View File

@@ -17,7 +17,7 @@
'urlRoot': "{{ request.script_root }}", 'urlRoot': "{{ request.script_root }}",
'csrfNonce': "{{ nonce }}", 'csrfNonce': "{{ nonce }}",
'userMode': "{{ Configs.user_mode }}", 'userMode': "{{ Configs.user_mode }}",
'userId': {{ id if (id is defined) else 0 }}, 'userId': {{ Session.id }},
'start': {{ Configs.start | tojson }}, 'start': {{ Configs.start | tojson }},
'end': {{ Configs.end | tojson }}, 'end': {{ Configs.end | tojson }},
} }

View File

@@ -10,6 +10,7 @@ from werkzeug.middleware.dispatcher import DispatcherMiddleware
from CTFd.cache import clear_user_recent_ips from CTFd.cache import clear_user_recent_ips
from CTFd.constants.config import Configs from CTFd.constants.config import Configs
from CTFd.constants.plugins import Plugins from CTFd.constants.plugins import Plugins
from CTFd.constants.sessions import Session
from CTFd.exceptions import UserNotFoundException, UserTokenExpiredException from CTFd.exceptions import UserNotFoundException, UserTokenExpiredException
from CTFd.models import Tracking, db from CTFd.models import Tracking, db
from CTFd.utils import config, get_config, markdown from CTFd.utils import config, get_config, markdown
@@ -91,6 +92,7 @@ def init_template_globals(app):
app.jinja_env.globals.update(get_ip=get_ip) app.jinja_env.globals.update(get_ip=get_ip)
app.jinja_env.globals.update(Configs=Configs) app.jinja_env.globals.update(Configs=Configs)
app.jinja_env.globals.update(Plugins=Plugins) app.jinja_env.globals.update(Plugins=Plugins)
app.jinja_env.globals.update(Session=Session)
def init_logs(app): def init_logs(app):
@@ -154,12 +156,6 @@ def init_events(app):
def init_request_processors(app): def init_request_processors(app):
@app.context_processor
def inject_user():
if session:
return dict(session)
return dict()
@app.url_defaults @app.url_defaults
def inject_theme(endpoint, values): def inject_theme(endpoint, values):
if "theme" not in values and app.url_map.is_endpoint_expecting( if "theme" not in values and app.url_map.is_endpoint_expecting(

View File

@@ -13,8 +13,6 @@ from CTFd.utils.security.signing import hmac
def login_user(user): def login_user(user):
session["id"] = user.id session["id"] = user.id
session["name"] = user.name
session["email"] = user.email
session["nonce"] = generate_nonce() session["nonce"] = generate_nonce()
session["hash"] = hmac(user.password) session["hash"] = hmac(user.password)
@@ -24,7 +22,6 @@ def login_user(user):
def update_user(user): def update_user(user):
session["id"] = user.id session["id"] = user.id
session["name"] = user.name
session["email"] = user.email session["email"] = user.email
session["hash"] = hmac(user.password) session["hash"] = hmac(user.password)

View File

@@ -212,9 +212,8 @@ def test_dynamic_challenge_loses_value_properly():
# We need to bypass rate-limiting so creating a fake user instead of logging in # We need to bypass rate-limiting so creating a fake user instead of logging in
with client.session_transaction() as sess: with client.session_transaction() as sess:
sess["id"] = team_id sess["id"] = team_id
sess["name"] = name
sess["email"] = email
sess["nonce"] = "fake-nonce" sess["nonce"] = "fake-nonce"
sess["hash"] = "fake-hash"
data = {"submission": "flag", "challenge_id": 1} data = {"submission": "flag", "challenge_id": 1}
@@ -304,9 +303,8 @@ def test_dynamic_challenge_value_isnt_affected_by_hidden_users():
# We need to bypass rate-limiting so creating a fake user instead of logging in # We need to bypass rate-limiting so creating a fake user instead of logging in
with client.session_transaction() as sess: with client.session_transaction() as sess:
sess["id"] = team_id sess["id"] = team_id
sess["name"] = name
sess["email"] = email
sess["nonce"] = "fake-nonce" sess["nonce"] = "fake-nonce"
sess["hash"] = "fake-hash"
data = {"submission": "flag", "challenge_id": 1} data = {"submission": "flag", "challenge_id": 1}

View File

@@ -144,9 +144,8 @@ def register_user(
if raise_for_error: if raise_for_error:
with client.session_transaction() as sess: with client.session_transaction() as sess:
assert sess["id"] assert sess["id"]
assert sess["name"] == name
assert sess["email"]
assert sess["nonce"] assert sess["nonce"]
assert sess["hash"]
def register_team(app, name="team", password="password", raise_for_error=True): def register_team(app, name="team", password="password", raise_for_error=True):
@@ -171,9 +170,8 @@ def login_as_user(app, name="user", password="password", raise_for_error=True):
if raise_for_error: if raise_for_error:
with client.session_transaction() as sess: with client.session_transaction() as sess:
assert sess["id"] assert sess["id"]
assert sess["name"]
assert sess["email"]
assert sess["nonce"] assert sess["nonce"]
assert sess["hash"]
return client return client
@@ -229,9 +227,8 @@ def login_with_mlc(
if raise_for_error: if raise_for_error:
with client.session_transaction() as sess: with client.session_transaction() as sess:
assert sess["id"] assert sess["id"]
assert sess["name"]
assert sess["email"]
assert sess["nonce"] assert sess["nonce"]
assert sess["hash"]
return client return client

View File

@@ -71,9 +71,8 @@ def test_oauth_configured_flow():
client = login_with_mlc(app) client = login_with_mlc(app)
with client.session_transaction() as sess: with client.session_transaction() as sess:
assert sess["id"] assert sess["id"]
assert sess["name"]
assert sess["email"]
assert sess["nonce"] assert sess["nonce"]
assert sess["hash"]
destroy_ctfd(app) destroy_ctfd(app)