diff --git a/CTFd/views.py b/CTFd/views.py index b4041da9..2cc7110f 100644 --- a/CTFd/views.py +++ b/CTFd/views.py @@ -24,7 +24,7 @@ from CTFd.utils.config.visibility import challenges_visible from CTFd.utils.security.auth import login_user from CTFd.utils.security.csrf import generate_nonce from CTFd.utils import user as current_user -from CTFd.utils.dates import ctftime +from CTFd.utils.dates import ctftime, ctf_ended, view_after_ctf from CTFd.utils.decorators import authed_only from CTFd.utils.security.signing import ( unserialize, @@ -202,7 +202,10 @@ def files(path): if challenges_visible(): if current_user.is_admin() is False: if not ctftime(): - abort(403) + if ctf_ended() and view_after_ctf(): + pass + else: + abort(403) else: if not ctftime(): abort(403) diff --git a/tests/users/test_views.py b/tests/test_views.py similarity index 63% rename from tests/users/test_views.py rename to tests/test_views.py index 83bdc18f..1655ba5f 100644 --- a/tests/users/test_views.py +++ b/tests/test_views.py @@ -112,7 +112,8 @@ def test_themes_handler(): assert r.status_code == 404 r = client.get("/themes/core/static/%2e%2e/%2e%2e/%2e%2e/utils.py") assert r.status_code == 404 - r = client.get("/themes/core/static/%2e%2e%2f%2e%2e%2f%2e%2e%2futils.py") + r = client.get( + "/themes/core/static/%2e%2e%2f%2e%2e%2f%2e%2e%2futils.py") assert r.status_code == 404 r = client.get("/themes/core/static/..%2f..%2f..%2futils.py") assert r.status_code == 404 @@ -191,10 +192,9 @@ def test_user_can_access_files(): assert r.status_code == 200 assert r.get_data(as_text=True) == "testing file load" - with freeze_time("2017-10-7"): - set_config( - "end", "1507262400" - ) # Friday, October 6, 2017 12:00:00 AM GMT-04:00 DST + with freeze_time("2017-10-5"): + # Friday, October 6, 2017 12:00:00 AM GMT-04:00 DST + set_config("start", "1507262400") for v in ("public", "private"): set_config("challenge_visibility", v) @@ -215,6 +215,30 @@ def test_user_can_access_files(): r = admin.get(url) assert r.status_code == 200 assert r.get_data(as_text=True) == "testing file load" + + with freeze_time("2017-10-7"): + # Friday, October 6, 2017 12:00:00 AM GMT-04:00 DST + set_config("end", "1507262400") + for v in ("public", "private"): + set_config("challenge_visibility", v) + + # Unauthed users shouldn't be able to see files if the CTF has ended + client = app.test_client() + r = client.get(url) + assert r.status_code == 403 + assert r.get_data(as_text=True) != "testing file load" + + # Authed users shouldn't be able to see files if the CTF has ended + client = login_as_user(app) + r = client.get(url) + assert r.status_code == 403 + assert r.get_data(as_text=True) != "testing file load" + + # Admins should be able to see files if the CTF has ended + admin = login_as_user(app, "admin") + r = admin.get(url) + assert r.status_code == 200 + assert r.get_data(as_text=True) == "testing file load" finally: rmdir(directory) destroy_ctfd(app) @@ -274,15 +298,108 @@ def test_user_can_access_files_with_auth_token(): assert r.get_data(as_text=True) != "testing file load" set_config("challenge_visibility", "private") - with freeze_time("2017-10-7"): - set_config( - "end", "1507262400" - ) # Friday, October 6, 2017 12:00:00 AM GMT-04:00 DST + with freeze_time("2017-10-5"): + # Friday, October 6, 2017 12:00:00 AM GMT-04:00 DST + set_config("start", "1507262400") # Unauthed users shouldn't be able to see files if the CTF hasn't started r = client.get(file_url) assert r.status_code == 403 assert r.get_data(as_text=True) != "testing file load" + + with freeze_time("2017-10-5"): + # Friday, October 6, 2017 12:00:00 AM GMT-04:00 DST + set_config("start", "1507262400") + for v in ("public", "private"): + set_config("challenge_visibility", v) + + # Unauthed users shouldn't be able to see files if the CTF hasn't started + client = app.test_client() + r = client.get(file_url) + assert r.status_code == 403 + assert r.get_data(as_text=True) != "testing file load" + + # Authed users shouldn't be able to see files if the CTF hasn't started + client = login_as_user(app) + r = client.get(file_url) + assert r.status_code == 403 + assert r.get_data(as_text=True) != "testing file load" + + # Admins should be able to see files if the CTF hasn't started + admin = login_as_user(app, "admin") + r = admin.get(file_url) + assert r.status_code == 200 + assert r.get_data(as_text=True) == "testing file load" + + with freeze_time("2017-10-7"): + # Friday, October 6, 2017 12:00:00 AM GMT-04:00 DST + set_config("end", "1507262400") + for v in ("public", "private"): + set_config("challenge_visibility", v) + + # Unauthed users shouldn't be able to see files if the CTF has ended + client = app.test_client() + r = client.get(file_url) + assert r.status_code == 403 + assert r.get_data(as_text=True) != "testing file load" + + # Authed users shouldn't be able to see files if the CTF has ended + client = login_as_user(app) + r = client.get(file_url) + assert r.status_code == 403 + assert r.get_data(as_text=True) != "testing file load" + + # Admins should be able to see files if the CTF has ended + admin = login_as_user(app, "admin") + r = admin.get(file_url) + assert r.status_code == 200 + assert r.get_data(as_text=True) == "testing file load" finally: rmdir(directory) destroy_ctfd(app) + + +def test_user_can_access_files_if_view_after_ctf(): + app = create_ctfd() + with app.app_context(): + from CTFd.utils.uploads import rmdir + + chal = gen_challenge(app.db) + chal_id = chal.id + path = app.config.get("UPLOAD_FOLDER") + + md5hash = hexencode(os.urandom(16)).decode("utf-8") + + location = os.path.join(path, md5hash, "test.txt") + directory = os.path.dirname(location) + model_path = os.path.join(md5hash, "test.txt") + + try: + os.makedirs(directory) + with open(location, "wb") as obj: + obj.write("testing file load".encode()) + gen_file(app.db, location=model_path, challenge_id=chal_id) + + register_user(app) + with login_as_user(app) as client: + req = client.get("/api/v1/challenges/1") + data = req.get_json() + file_url = data["data"]["files"][0] + + # After ctf end + with freeze_time("2017-10-7"): + # Friday, October 6, 2017 12:00:00 AM GMT-04:00 DST + set_config("end", "1507262400") + + r = client.get(file_url) + assert r.status_code == 403 + assert r.get_data(as_text=True) != "testing file load" + + set_config("view_after_ctf", True) + r = client.get(file_url) + assert r.status_code == 200 + assert r.get_data(as_text=True) == "testing file load" + finally: + rmdir(directory) + + destroy_ctfd(app)