Update challenge plugins and flag plugins to have exception messages (#1491)

* Update challenge plugins and flag plugins to raise and catch exceptions for flag error messages
* Closes #1425
This commit is contained in:
Kevin Chung
2020-06-14 17:01:23 -04:00
committed by GitHub
parent 1143d751c8
commit 94bd8baca1
4 changed files with 45 additions and 8 deletions

View File

@@ -11,7 +11,7 @@ from CTFd.models import (
db,
)
from CTFd.plugins import register_plugin_assets_directory
from CTFd.plugins.flags import get_flag_class
from CTFd.plugins.flags import FlagException, get_flag_class
from CTFd.utils.uploads import delete_file
from CTFd.utils.user import get_ip
@@ -138,8 +138,11 @@ class CTFdStandardChallenge(BaseChallenge):
submission = data["submission"].strip()
flags = Flags.query.filter_by(challenge_id=challenge.id).all()
for flag in flags:
if get_flag_class(flag.type).compare(flag, submission):
return True, "Correct"
try:
if get_flag_class(flag.type).compare(flag, submission):
return True, "Correct"
except FlagException as e:
return False, e.message
return False, "Incorrect"
@staticmethod

View File

@@ -16,7 +16,7 @@ from CTFd.models import (
)
from CTFd.plugins import register_plugin_assets_directory
from CTFd.plugins.challenges import CHALLENGE_CLASSES, BaseChallenge
from CTFd.plugins.flags import get_flag_class
from CTFd.plugins.flags import FlagException, get_flag_class
from CTFd.plugins.migrations import upgrade
from CTFd.utils.modes import get_model
from CTFd.utils.uploads import delete_file
@@ -184,8 +184,11 @@ class DynamicValueChallenge(BaseChallenge):
submission = data["submission"].strip()
flags = Flags.query.filter_by(challenge_id=challenge.id).all()
for flag in flags:
if get_flag_class(flag.type).compare(flag, submission):
return True, "Correct"
try:
if get_flag_class(flag.type).compare(flag, submission):
return True, "Correct"
except FlagException as e:
return False, e.message
return False, "Incorrect"
@staticmethod

View File

@@ -3,6 +3,14 @@ import re
from CTFd.plugins import register_plugin_assets_directory
class FlagException(Exception):
def __init__(self, message):
self.message = message
def __str__(self):
return self.message
class BaseFlag(object):
name = None
templates = {}
@@ -55,8 +63,8 @@ class CTFdRegexFlag(BaseFlag):
else:
res = re.match(saved, provided)
# TODO: this needs plugin improvements. See #1425.
except re.error:
return False
except re.error as e:
raise FlagException("Regex parse error occured") from e
return res and res.group() == provided

View File

@@ -181,6 +181,29 @@ def test_submitting_correct_regex_case_insensitive_flag():
destroy_ctfd(app)
def test_submitting_invalid_regex_flag():
"""Test that invalid regex flags are errored out to the user"""
app = create_ctfd()
with app.app_context():
register_user(app)
client = login_as_user(app)
chal = gen_challenge(app.db)
gen_flag(
app.db,
challenge_id=chal.id,
type="regex",
content="**",
data="case_insensitive",
)
data = {"submission": "FLAG", "challenge_id": chal.id}
r = client.post("/api/v1/challenges/attempt", json=data)
assert r.status_code == 200
resp = r.get_json()["data"]
assert resp.get("status") == "incorrect"
assert resp.get("message") == "Regex parse error occured"
destroy_ctfd(app)
def test_submitting_incorrect_flag():
"""Test that incorrect flags are incorrect"""
app = create_ctfd()