def test_api_files_get_non_admin(): app = create_kmactf() with app.app_context(): chal = gen_challenge(app.db) gen_file( app.db, location="0bf1a55a5cd327c07af15df260979668/bird.swf", challenge_id=chal.id, ) with app.test_client() as client: # test_api_files_get_non_admin """Can a user get /api/v1/files if not admin""" r = client.get("/api/v1/files", json="") assert r.status_code == 403 # test_api_files_post_non_admin """Can a user post /api/v1/files if not admin""" r = client.post("/api/v1/files") assert r.status_code == 403 # test_api_file_get_non_admin """Can a user get /api/v1/files/<file_id> if not admin""" r = client.get("/api/v1/files/1", json="") assert r.status_code == 403 # test_api_file_delete_non_admin """Can a user delete /api/v1/files/<file_id> if not admin""" r = client.delete("/api/v1/files/1", json="") assert r.status_code == 403 destroy_kmactf(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)) 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" # Unauthed users should be able to download if view_after_ctf client = app.test_client() 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)
def test_api_file_get_admin(): """Can a user get /api/v1/files/<file_id> if admin""" app = create_ctfd() with app.app_context(): chal = gen_challenge(app.db) f = gen_file(app.db, location='0bf1a55a5cd327c07af15df260979668/bird.swf', challenge_id=chal.id) assert Files.query.count() == 1 assert ChallengeFiles.query.count() == 1 assert f in chal.files with login_as_user(app, 'admin') as client: r = client.get('/api/v1/files/1', json="") assert r.status_code == 200 destroy_ctfd(app)
def test_api_file_delete_admin(): """Can a user delete /api/v1/files/<file_id> if admin""" app = create_kmactf() with app.app_context(): chal = gen_challenge(app.db) f = gen_file( app.db, location="0bf1a55a5cd327c07af15df260979668/bird.swf", challenge_id=chal.id, ) assert Files.query.count() == 1 assert ChallengeFiles.query.count() == 1 assert f in chal.files with login_as_user(app, "admin") as client: r = client.delete("/api/v1/files/1", json="") assert r.status_code == 200 assert Files.query.count() == 0 assert ChallengeFiles.query.count() == 0 chal = Challenges.query.filter_by(id=1).first() assert f not in chal.files destroy_kmactf(app)
def test_api_file_delete_admin(): """Can a user delete /api/v1/files/<file_id> if admin""" app = create_ctfd() with app.app_context(): chal = gen_challenge(app.db) path = os.path.join(app.config["UPLOAD_FOLDER"], "0bf1a55a5cd327c07af15df260979668", "bird.swf") try: # Create a fake file os.makedirs(os.path.dirname(path)) open(path, "a").close() f = gen_file( app.db, location="0bf1a55a5cd327c07af15df260979668/bird.swf", challenge_id=chal.id, ) assert Files.query.count() == 1 assert ChallengeFiles.query.count() == 1 assert f in chal.files # Make sure the file was created assert os.path.exists(path) with login_as_user(app, "admin") as client: r = client.delete("/api/v1/files/1", json="") assert r.status_code == 200 assert Files.query.count() == 0 assert ChallengeFiles.query.count() == 0 chal = Challenges.query.filter_by(id=1).first() assert f not in chal.files # Make sure the API call deleted the file assert os.path.exists(path) is False finally: # Always make sure the file is deleted shutil.rmtree(os.path.dirname(path), ignore_errors=True) destroy_ctfd(app)
def test_user_can_access_files_with_auth_token(): 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) url = url_for("views.files", path=model_path) 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] with app.test_client() as client: r = client.get(url) assert r.status_code == 403 assert r.get_data(as_text=True) != "testing file load" r = client.get( url_for( "views.files", path=model_path, token="random_token_that_shouldnt_work", ) ) assert r.status_code == 403 assert r.get_data(as_text=True) != "testing file load" r = client.get(file_url) assert r.status_code == 200 assert r.get_data(as_text=True) == "testing file load" # Unauthed users shouldn't be able to see files if the CTF is admins only set_config("challenge_visibility", "admins") r = client.get(file_url) assert r.status_code == 403 assert r.get_data(as_text=True) != "testing file load" set_config("challenge_visibility", "private") 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(): 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") location = os.path.join(path, "test_file_path", "test.txt") directory = os.path.dirname(location) model_path = os.path.join("test_file_path", "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) url = url_for("views.files", path=model_path) # Unauthed user should be able to see challenges if challenges are public set_config("challenge_visibility", "public") with app.test_client() as client: r = client.get(url) assert r.status_code == 200 assert r.get_data(as_text=True) == "testing file load" # Unauthed user should not be able to see challenges if challenges are private set_config("challenge_visibility", "private") with app.test_client() as client: r = client.get(url) assert r.status_code == 403 assert r.get_data(as_text=True) != "testing file load" # Authed user should be able to see files if challenges are private register_user(app) client = login_as_user(app) r = client.get(url) assert r.status_code == 200 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(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(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(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)
def test_reset(): app = create_ctfd() with app.app_context(): base_user = "******" for x in range(10): chal = gen_challenge(app.db, name="chal_name{}".format(x)) gen_flag(app.db, challenge_id=chal.id, content="flag") gen_hint(app.db, challenge_id=chal.id) gen_file( app.db, location="{name}/{name}.file".format(name=chal.name), challenge_id=chal.id, ) for x in range(10): user = base_user + str(x) user_email = user + "@ctfd.io" user_obj = gen_user(app.db, name=user, email=user_email) gen_award(app.db, user_id=user_obj.id) gen_solve(app.db, user_id=user_obj.id, challenge_id=random.randint(1, 10)) gen_fail(app.db, user_id=user_obj.id, challenge_id=random.randint(1, 10)) gen_tracking(app.db, user_id=user_obj.id) # Add PageFiles for x in range(5): gen_file( app.db, location="page_file{name}/page_file{name}.file".format(name=x), page_id=1, ) assert Users.query.count() == 11 # 11 because of the first admin user assert Challenges.query.count() == 10 assert ( Files.query.count() == 15 ) # This should be 11 because ChallengeFiles=10 and PageFiles=5 assert Flags.query.count() == 10 assert Hints.query.count() == 10 assert Submissions.query.count() == 20 assert Pages.query.count() == 1 assert Tracking.query.count() == 10 client = login_as_user(app, name="admin", password="******") with client.session_transaction() as sess: data = {"nonce": sess.get("nonce"), "pages": "on"} r = client.post("/admin/reset", data=data) assert r.location.endswith("/admin/statistics") assert Pages.query.count() == 0 assert Users.query.count() == 11 assert Challenges.query.count() == 10 assert Tracking.query.count() == 11 assert Files.query.count() == 10 with client.session_transaction() as sess: data = {"nonce": sess.get("nonce"), "notifications": "on"} r = client.post("/admin/reset", data=data) assert r.location.endswith("/admin/statistics") assert Notifications.query.count() == 0 assert Users.query.count() == 11 assert Challenges.query.count() == 10 assert Tracking.query.count() == 11 with client.session_transaction() as sess: data = {"nonce": sess.get("nonce"), "challenges": "on"} r = client.post("/admin/reset", data=data) assert r.location.endswith("/admin/statistics") assert Challenges.query.count() == 0 assert Flags.query.count() == 0 assert Hints.query.count() == 0 assert Files.query.count() == 0 assert Tags.query.count() == 0 assert Users.query.count() == 11 assert Tracking.query.count() == 11 with client.session_transaction() as sess: data = {"nonce": sess.get("nonce"), "submissions": "on"} r = client.post("/admin/reset", data=data) assert r.location.endswith("/admin/statistics") assert Submissions.query.count() == 0 assert Solves.query.count() == 0 assert Fails.query.count() == 0 assert Awards.query.count() == 0 assert Unlocks.query.count() == 0 assert Users.query.count() == 11 assert Challenges.query.count() == 0 assert Flags.query.count() == 0 assert Tracking.query.count() == 0 with client.session_transaction() as sess: data = {"nonce": sess.get("nonce"), "accounts": "on"} r = client.post("/admin/reset", data=data) assert r.location.endswith("/setup") assert Users.query.count() == 0 assert Solves.query.count() == 0 assert Fails.query.count() == 0 assert Tracking.query.count() == 0 destroy_ctfd(app)
def test_user_can_access_files_with_auth_token(): 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) url = url_for('views.files', path=model_path) 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] with app.test_client() as client: r = client.get(url) assert r.status_code == 403 assert r.get_data(as_text=True) != 'testing file load' r = client.get( url_for('views.files', path=model_path, token="random_token_that_shouldnt_work")) assert r.status_code == 403 assert r.get_data(as_text=True) != 'testing file load' r = client.get(file_url) assert r.status_code == 200 assert r.get_data(as_text=True) == 'testing file load' # Unauthed users shouldn't be able to see files if the CTF is admins only set_config('challenge_visibility', 'admins') r = client.get(file_url) assert r.status_code == 403 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 # 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' finally: rmdir(directory) destroy_ctfd(app)
def test_user_can_access_files(): 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') location = os.path.join(path, 'test_file_path', 'test.txt') directory = os.path.dirname(location) model_path = os.path.join('test_file_path', '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) url = url_for('views.files', path=model_path) # Unauthed user should be able to see challenges if challenges are public set_config('challenge_visibility', 'public') with app.test_client() as client: r = client.get(url) assert r.status_code == 200 assert r.get_data(as_text=True) == 'testing file load' # Unauthed user should not be able to see challenges if challenges are private set_config('challenge_visibility', 'private') with app.test_client() as client: r = client.get(url) assert r.status_code == 403 assert r.get_data(as_text=True) != 'testing file load' # Authed user should be able to see files if challenges are private register_user(app) client = login_as_user(app) r = client.get(url) 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 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(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(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(url) assert r.status_code == 200 assert r.get_data(as_text=True) == 'testing file load' finally: rmdir(directory) destroy_ctfd(app)