mirror of
https://github.com/aljazceru/CTFd.git
synced 2025-12-17 22:14:25 +01:00
1423 model filter bypass (#1451)
* Add `view=admin` GET param to `/api/v1/users`, `/api/v1/teams`, and `/api/v1/challenges` to bypass filtering for admins * Closes #1423 #1445 * Related to #1165
This commit is contained in:
@@ -47,6 +47,11 @@ class ChallengeList(Resource):
|
|||||||
# This can return None (unauth) if visibility is set to public
|
# This can return None (unauth) if visibility is set to public
|
||||||
user = get_current_user()
|
user = get_current_user()
|
||||||
|
|
||||||
|
# Admins can request to see everything
|
||||||
|
if is_admin() and request.args.get("view") == "admin":
|
||||||
|
challenges = Challenges.query.order_by(Challenges.value).all()
|
||||||
|
solve_ids = set([challenge.id for challenge in challenges])
|
||||||
|
else:
|
||||||
challenges = (
|
challenges = (
|
||||||
Challenges.query.filter(
|
Challenges.query.filter(
|
||||||
and_(Challenges.state != "hidden", Challenges.state != "locked")
|
and_(Challenges.state != "hidden", Challenges.state != "locked")
|
||||||
|
|||||||
@@ -22,7 +22,11 @@ teams_namespace = Namespace("teams", description="Endpoint to retrieve Teams")
|
|||||||
class TeamList(Resource):
|
class TeamList(Resource):
|
||||||
@check_account_visibility
|
@check_account_visibility
|
||||||
def get(self):
|
def get(self):
|
||||||
|
if is_admin() and request.args.get("view") == "admin":
|
||||||
|
teams = Teams.query.filter_by()
|
||||||
|
else:
|
||||||
teams = Teams.query.filter_by(hidden=False, banned=False)
|
teams = Teams.query.filter_by(hidden=False, banned=False)
|
||||||
|
|
||||||
user_type = get_current_user_type(fallback="user")
|
user_type = get_current_user_type(fallback="user")
|
||||||
view = copy.deepcopy(TeamSchema.views.get(user_type))
|
view = copy.deepcopy(TeamSchema.views.get(user_type))
|
||||||
view.remove("members")
|
view.remove("members")
|
||||||
|
|||||||
@@ -31,7 +31,11 @@ users_namespace = Namespace("users", description="Endpoint to retrieve Users")
|
|||||||
class UserList(Resource):
|
class UserList(Resource):
|
||||||
@check_account_visibility
|
@check_account_visibility
|
||||||
def get(self):
|
def get(self):
|
||||||
|
if is_admin() and request.args.get("view") == "admin":
|
||||||
|
users = Users.query.filter_by()
|
||||||
|
else:
|
||||||
users = Users.query.filter_by(banned=False, hidden=False)
|
users = Users.query.filter_by(banned=False, hidden=False)
|
||||||
|
|
||||||
response = UserSchema(view="user", many=True).dump(users)
|
response = UserSchema(view="user", many=True).dump(users)
|
||||||
|
|
||||||
if response.errors:
|
if response.errors:
|
||||||
|
|||||||
@@ -135,6 +135,25 @@ def test_api_challenges_get_admin():
|
|||||||
destroy_ctfd(app)
|
destroy_ctfd(app)
|
||||||
|
|
||||||
|
|
||||||
|
def test_api_challenges_get_hidden_admin():
|
||||||
|
"""Can an admin see hidden challenges in API list response"""
|
||||||
|
app = create_ctfd()
|
||||||
|
with app.app_context():
|
||||||
|
gen_challenge(app.db, state="hidden")
|
||||||
|
gen_challenge(app.db)
|
||||||
|
|
||||||
|
with login_as_user(app, "admin") as admin:
|
||||||
|
challenges_list = admin.get("/api/v1/challenges", json="").get_json()[
|
||||||
|
"data"
|
||||||
|
]
|
||||||
|
assert len(challenges_list) == 1
|
||||||
|
challenges_list = admin.get(
|
||||||
|
"/api/v1/challenges?view=admin", json=""
|
||||||
|
).get_json()["data"]
|
||||||
|
assert len(challenges_list) == 2
|
||||||
|
destroy_ctfd(app)
|
||||||
|
|
||||||
|
|
||||||
def test_api_challenges_post_admin():
|
def test_api_challenges_post_admin():
|
||||||
"""Can a user post /api/v1/challenges if admin"""
|
"""Can a user post /api/v1/challenges if admin"""
|
||||||
app = create_ctfd()
|
app = create_ctfd()
|
||||||
|
|||||||
@@ -696,6 +696,9 @@ def test_api_accessing_hidden_banned_users():
|
|||||||
app.db.session.commit()
|
app.db.session.commit()
|
||||||
|
|
||||||
with login_as_user(app, name="visible_user") as client:
|
with login_as_user(app, name="visible_user") as client:
|
||||||
|
list_teams = client.get("/api/v1/teams").get_json()["data"]
|
||||||
|
assert len(list_teams) == 0
|
||||||
|
|
||||||
assert client.get("/api/v1/teams/1").status_code == 404
|
assert client.get("/api/v1/teams/1").status_code == 404
|
||||||
assert client.get("/api/v1/teams/1/solves").status_code == 404
|
assert client.get("/api/v1/teams/1/solves").status_code == 404
|
||||||
assert client.get("/api/v1/teams/1/fails").status_code == 404
|
assert client.get("/api/v1/teams/1/fails").status_code == 404
|
||||||
@@ -707,6 +710,10 @@ def test_api_accessing_hidden_banned_users():
|
|||||||
assert client.get("/api/v1/teams/2/awards").status_code == 404
|
assert client.get("/api/v1/teams/2/awards").status_code == 404
|
||||||
|
|
||||||
with login_as_user(app, name="admin") as client:
|
with login_as_user(app, name="admin") as client:
|
||||||
|
# Admins see hidden teams in lists
|
||||||
|
list_users = client.get("/api/v1/teams?view=admin").get_json()["data"]
|
||||||
|
assert len(list_users) == 2
|
||||||
|
|
||||||
assert client.get("/api/v1/teams/1").status_code == 200
|
assert client.get("/api/v1/teams/1").status_code == 200
|
||||||
assert client.get("/api/v1/teams/1/solves").status_code == 200
|
assert client.get("/api/v1/teams/1/solves").status_code == 200
|
||||||
assert client.get("/api/v1/teams/1/fails").status_code == 200
|
assert client.get("/api/v1/teams/1/fails").status_code == 200
|
||||||
|
|||||||
@@ -764,12 +764,19 @@ def test_api_accessing_hidden_users():
|
|||||||
app.db.session.commit()
|
app.db.session.commit()
|
||||||
|
|
||||||
with login_as_user(app, name="visible_user") as client:
|
with login_as_user(app, name="visible_user") as client:
|
||||||
|
list_users = client.get("/api/v1/users").get_json()["data"]
|
||||||
|
assert len(list_users) == 1
|
||||||
|
|
||||||
assert client.get("/api/v1/users/3").status_code == 404
|
assert client.get("/api/v1/users/3").status_code == 404
|
||||||
assert client.get("/api/v1/users/3/solves").status_code == 404
|
assert client.get("/api/v1/users/3/solves").status_code == 404
|
||||||
assert client.get("/api/v1/users/3/fails").status_code == 404
|
assert client.get("/api/v1/users/3/fails").status_code == 404
|
||||||
assert client.get("/api/v1/users/3/awards").status_code == 404
|
assert client.get("/api/v1/users/3/awards").status_code == 404
|
||||||
|
|
||||||
with login_as_user(app, name="admin") as client:
|
with login_as_user(app, name="admin") as client:
|
||||||
|
# Admins see the user in lists
|
||||||
|
list_users = client.get("/api/v1/users?view=admin").get_json()["data"]
|
||||||
|
assert len(list_users) == 3
|
||||||
|
|
||||||
assert client.get("/api/v1/users/3").status_code == 200
|
assert client.get("/api/v1/users/3").status_code == 200
|
||||||
assert client.get("/api/v1/users/3/solves").status_code == 200
|
assert client.get("/api/v1/users/3/solves").status_code == 200
|
||||||
assert client.get("/api/v1/users/3/fails").status_code == 200
|
assert client.get("/api/v1/users/3/fails").status_code == 200
|
||||||
@@ -788,12 +795,19 @@ def test_api_accessing_banned_users():
|
|||||||
app.db.session.commit()
|
app.db.session.commit()
|
||||||
|
|
||||||
with login_as_user(app, name="visible_user") as client:
|
with login_as_user(app, name="visible_user") as client:
|
||||||
|
list_users = client.get("/api/v1/users").get_json()["data"]
|
||||||
|
assert len(list_users) == 1
|
||||||
|
|
||||||
assert client.get("/api/v1/users/3").status_code == 404
|
assert client.get("/api/v1/users/3").status_code == 404
|
||||||
assert client.get("/api/v1/users/3/solves").status_code == 404
|
assert client.get("/api/v1/users/3/solves").status_code == 404
|
||||||
assert client.get("/api/v1/users/3/fails").status_code == 404
|
assert client.get("/api/v1/users/3/fails").status_code == 404
|
||||||
assert client.get("/api/v1/users/3/awards").status_code == 404
|
assert client.get("/api/v1/users/3/awards").status_code == 404
|
||||||
|
|
||||||
with login_as_user(app, name="admin") as client:
|
with login_as_user(app, name="admin") as client:
|
||||||
|
# Admins see the user in lists
|
||||||
|
list_users = client.get("/api/v1/users?view=admin").get_json()["data"]
|
||||||
|
assert len(list_users) == 3
|
||||||
|
|
||||||
assert client.get("/api/v1/users/3").status_code == 200
|
assert client.get("/api/v1/users/3").status_code == 200
|
||||||
assert client.get("/api/v1/users/3/solves").status_code == 200
|
assert client.get("/api/v1/users/3/solves").status_code == 200
|
||||||
assert client.get("/api/v1/users/3/fails").status_code == 200
|
assert client.get("/api/v1/users/3/fails").status_code == 200
|
||||||
|
|||||||
Reference in New Issue
Block a user