CTFs as you need them
APACHE-2.0 License
General
API
bracket_name
and bracket_id
to /api/v1/scoreboard
sha1sum
to GET /api/v1/files
location
to POST /api/v1/files
Plugins
register_user_page_menu_bar()
uploaders.open()
to open a file from an uploaderUploaders.upload()
method to control where files get uploaded toThemes
<meta>
tag & page title via template filesunix_time_to_utc()
as a Jinja filterAdmin Panel
Deployment
python:3.11-slim-bookworm
AWS_S3_CUSTOM_PREFIX
Published by ColdHeat 11 months ago
Security
General
API
email
as a field
to query to /api/v1/users
and /api/v1/teams
to allow searching via email address for Admins/api/v1/files
Admin Panel
Themes
meta
tags can now be inserted into pages from render_template()
callsDeployment
23.9.1
Published by ColdHeat about 1 year ago
General
Admin Panel
discard
type for submissionsPATCH /api/v1/submissions/[submission_id]
to mark submissions as correctHTML_SANITIZATION
HTML_SANITIZATION
to true in config.ini
cannot be disabled via the Admin PanelDeployment
SKIP_DB_PING
to instruct the CTFd Docker image to not test if the database server is availableAWS_S3_ADDRESSING_STYLE
virtual
or path
AWS_S3_CUSTOM_DOMAIN
which specifies a domain that replaces the default one in presigned download URLs
flask
cli tool is now offered as an alternative to the manage.py
script.API
ctfd_
prefix to make them easier to identifyGET /api/v1/hints/[hint_id]
will now return hint information for free hints for unauthenticated users if challenges are visibleThemes
Published by ColdHeat over 1 year ago
Deployment
Published by ColdHeat over 1 year ago
General
Admin Panel
robots.txt
Deployment
/opt/venv
Published by ColdHeat almost 2 years ago
General
Admin Panel
teams+members+fields
which is teams with Custom Field entries and their team members with Custom Field entriesfield_entries
could not be imported under MariaDBconfig
entries sometimes would be recreated for some reason causing an import to failautocomplete='off'
to Admin Panel pagesAPI
/api/v1/challenges
and /api/v1/challenges/[challenge_id]/solves
by caching the solve count data for users and challengesHEAD /api/v1/notifications
to get a count of notifications that have happened.
since_id
parameter to allow for a notification cursor.since_id
to GET /api/v1/notifications
to get Notifications that have happened since a specific IDDeployment
/healthcheck
endpoint to check if CTFd is readySAFE_MODE
config from environment variableAWS_S3_REGION
config has been added to allow specifying an S3 region. The default is us-east-1
DATABASE_URL
DATABASE_PROTOCOL
: SQLAlchemy DB protocol (+ driver, optionally)DATABASE_USER
: Username to access DB server withDATABASE_PASSWORD
: Password to access DB server withDATABASE_HOST
: Hostname of the DB server to accessDATABASE_PORT
: Port of the DB server to accessDATABASE_NAME
: Name of the database to useREDIS_URL
REDIS_PROTOCOL
: Protocol to access Redis server with (either redis or rediss)REDIS_USER
: Username to access Redis server withREDIS_PASSWORD
: Password to access Redis server withREDIS_HOST
: Hostname of the Redis server to accessREDIS_PORT
: Port of the Redis server to accessREDIS_DB
: Numeric ID of the database to accessPlugins
config.json
to have multiple paths to add to the Plugins dropdown in the Admin Panelget_all_tables
and get_columns_for_table
functionsCTFd.utils.email.providers.EmailProvider
CTFd.utils.email.providers.mailgun.MailgunEmailProvider
CTFd.utils.email.providers.smtp.SMTPEmailProvider
CTFd.utils.email.mailgun.sendmail
CTFd.utils.email.smtp.sendmail
Themes
Assets.manifest_css
has been removedevent-source-polyfill
is now pinned to 1.0.19.
core-beta
theme.Published by ColdHeat over 2 years ago
General
Admin Panel
GET /admin/import
to see status of importAPI
count
meta field to the following endpoints:
/api/v1/users/me/solves
/api/v1/users/me/fails
/api/v1/users/me/awards
/api/v1/teams/me/awards
/api/v1/users/[user_id]/solves
/api/v1/users/[user_id]/fails
/api/v1/users/[user_id]/awards
/api/v1/teams/[team_id]/solves
/api/v1/teams/[team_id]/awards
/api/v1/teams/me/fails
/api/v1/teams/[team_id]/fails
/api/v1/users/me/fails
/api/v1/users/[user_id]/fails
Deployment
python3-dev
in Dockerfilenginx:stable
as the image for nginxPlugins
CTFd._internal.challenge.render
and CTFd._internal.challenge.renderer
in the view.js
Challenge type file has been deprecated. Instead Challenge plugins should refer to the challenge.html
attribute provided by the API. Essentially CTFd is moving to having markdown & HTML rendered by the server instead of rendering on the client.Themes
core-beta
theme and begin documenting the creation of themes using ViteuserName
and userEmail
to the CTFd init object in base.html
for easier integration with other JavaScript codeteamId
and teamName
to the CTFd init object in base.html
for easier integration with other JavaScript codeAssets
constant to access front end assets from Jinja templatesviews.themes_beta
route to avoid the .dev
/.min
extension being added automatically to frontend asset urlsMiscellaneous
log()
function--delete_import_on_finish
to python manage.py import_ctf
field_entries
table could not be imported when moving between MySQL and MariaDBPublished by ColdHeat over 2 years ago
Security
General
Published by ColdHeat over 2 years ago
Security
General
Published by ColdHeat over 2 years ago
General
API
/api/v1/challenges/[challenge_id]/solves
endpointContent-Type
header requirementUserSchema
and TeamSchema
to SubmissionSchema
for easier access to account nameAdmin Panel
Themes
theme_settings
can cause broken frontendnode-sass
with sass
and upgrade sass-loader
Deployment
REVERSE_PROXY
to allow comma seperated integersflask-restx
to 0.5.1pybluemonday
to 0.0.9Miscellaneous
Published by ColdHeat about 3 years ago
General
connection_info
to Challenges to allow Admins to more easily specify the connection info for a challengectf_name
, ctf_description
, ctf_start
, ctf_end
, ctf_freeze
. (e.g. {{ ctf_name }}
)API
connection_info
field to /api/v1/challenges/[challenge_id]
/api/v1/topics
for admins to create/delete topics/api/v1/challenges/[challenge_id]/topics
for admins to list the topics on a challenge/api/v1/challenges
will now sort by ID as value to better standardize API output with different databases/api/v1/configs
will now provide an error message when provided Config values are too longPATCH /api/v1/teams/[team_id]
will now only let team members be team captain
Themes
THEME_FALLBACK
option enabled by default. This allows users to provide incomplete themes. Missing theme files will be provided from the built-in core themewindow.BETA_sortChallenges
to /challenges
so that theme code can more easily define how to sort challenges
window.updateChallengeBoard
to /challenges
so that theme code can more easily define when to update challenges
window.updateScoreboard
to /scoreboard
so that theme code can more easily define when to update the scoreboard
Plugins
Challenges.plugin_class
to the Challenges model to access the challenge type plugin class from the Model
Admin Panel
ctf_name
, ctf_description
, ctf_start
, ctf_end
, ctf_freeze
ctf_start
, ctf_end
, ctf_freeze
are represented as ISO8601 timestampsDeployment
THEME_FALLBACK
config is now set to true by defaultmysqladmin
(specifically mysqladmin ping
) with a custom Python scriptpybluemonday
to 0.0.7 (fixes HTML sanitization bypasses and allows comments in HTML)pydantic
from 1.5.1 to 1.6.2Miscellaneous
.dockerignore
ignore node_modules
in any subdirectorysolves
and solved_by_me
fields to the Swagger documentation for Challengesinital
keyword instead of the previous value
keyword.
Published by ColdHeat over 3 years ago
Security
Published by ColdHeat over 3 years ago
General
THEME_FALLBACK
config to help develop themes. See Themes section for details.API
/api/v1/scoreboard
endpoint in Teams Modesolves
item to both /api/v1/challenges
and /api/v1/challenges/[challenge_id]
to more easily determine how many solves a challenge hassolved_by_me
item to both /api/v1/challenges
and /api/v1/challenges/[challenge_id]
to more easily determine if the current account has solved the challengeDELETE /api/v1/users/[user_id]
PATCH /api/v1/users[user_id]
returned a list instead of a dictPATCH /api/v1/users[user_id]
team_id
to GET /api/v1/users
to determine if a user is already in a teamThemes
THEME_FALLBACK
config to help develop themes.
THEME_FALLBACK
will configure CTFd to try to find missing theme files in the default built-in core
theme.{% extends "core/page.html" %}
data-time-format
attribute.<blockquote>
element.users/private.html
, users/public.html
to show awards before a user gets a solveteams/private.html
, teams/public.html
to show awards before a team gets a solvecolorHash
function to use HSL color values to avoid generating too light/dark colors/user
)/api/v1/challenges
to mark solves and display solve countscore/main.scss
to allow using Bootstrap variablesPlugins
Admin Panel
Deployment
config.ini
optional sectionpython3-dev
instead of python-dev
in aptpybluemonday
as pip dependencylxml
and html5lib
from pip dependenciesJinja2
to 2.11.3pip-tools
to 5.4.0Miscellaneous
HTML_SANITIZATION
) to use the pybluemonday
library instead of lxml
/html5lib
examplectf.com
as testing/development domain instead of ctfd.io
flake8-comprehensions
and flake8-bugbear
.pyc
files and __pycache__
to .dockerignore
Published by ColdHeat almost 4 years ago
Published by ColdHeat almost 4 years ago
General
API
POST /api/v1/teams/me/members
to generate invite tokens for teamsPOST /api/v1/awards
where CTFd would 500 when a user could not be found by the provided user_id
POST /api/v1/unlocks
in teams mode now uses the team's score to determine if a user can purchase a hint
POST /api/v1/unlocks
/api/v1/notifications
and /api/v1/notifications/[notification_id]
now have an html parameter which specifies the rendered content of the notification contentThemes
highlight.js
which has been added to package.json
.local()
challenge.html
where the current attempt count would have a typochallenge.html
where the max attempts for a challenge would not show if it was set to 1Plugins
auth.register
(/register
) endpoint now accepts a ?next=
parameter to define where to redirect to after registrationregistered_only
decorator to redirect users to auth.register
(/register
) instead of auth.login
(/login
)db.create_all()
as much during plugin upgrade or during imports
app.db.create_all()
and will not implicitly get it through upgrade()
.upgrade()
without a migrations folder (no idea who would do this really) will need to upgrade their code.upgrade()
function now accepts a lower
parameter which specifies what lower revision should be used to start from.
lower="current"
means to use the current revision and lower=None
would mean to use the absolute base revision (e.g. plugin's first installation)upgrade()
behaviorAdmin Panel
Deployment
always
has been added to nginx in docker-composerequirements.txt
to requirements.in
and generate requirements.txt
using pip-tools
under Python 3.6UPLOAD_PROVIDER
no longer has a default filesystem
set in config.ini. Instead it is defaulted through config.py
Miscellaneous
psycopg2
dependency in development.txt has been removed in favor of psycopg2-binary
which was updated to 2.8.6moto
dependency in development.txt has been updated to 1.3.16pip-tools
to development.txt
import_ctf
and export_ctf
commands to manage.py
and deprecate import.py
and export.py
MAIL_SERVER
config with the TESTING_MAIL_SERVER
envvar during testsping
events in the notification event handler have been fixed to not send duplicatesPublished by ColdHeat about 4 years ago
General
Admin Panel
Themes
@babel/core
, @babel/preset-env
, @fortawesome/fontawesome-free
, babel-loader
, and @babel/polyfill
were updated but only @babel/core
needs to be updated to resolve the transpiliation issueconsole.log
statements from minified production JSMiscellaneous
MAILSENDER_ADDR
config valuePublished by ColdHeat about 4 years ago
General
Admin Panel
API
/api/v1/comments
to manipulate and create commentsThemes
scoreboard.html
.teams/public.html
, teams/private.html
, users/public.html
, users/private.html
), registration pages (register.html
), and settings pages (settings.html
).
form.extra
& user.fields
with a special helper (render_extra_fields
) defined in macros/forms.html
. The best way to implement this is to look at how the core theme handles it and copy the relevant behavior.Miscellaneous
--disable-gevent
switch in serve.pytenacity
library for retrying logicpytest-sugar
for slightly prettier pytest outputlisten()
method to CTFd.utils.events.EventManager
and CTFd.utils.events.RedisEventManager
.
subscribe()
method (which used to implement the functionality of the new listen()
function) now only handles passing notifications from CTFd to the browser. This should also be implemented with gevent or a background thread.Published by ColdHeat about 4 years ago
Admin Panel
Plugins
input
& submit
blocks in challenge.html
to use the default values specified in the original challenge type pluginsPublished by ColdHeat about 4 years ago
General
Admin Panel
API
CTFd.api.v1.helpers.models.build_model_filters
and wrap it to CTFd.utils.helpers.models.build_model_filters
Themes
Plugins
Deployment
config.ini
will now supercede values specified via environment variable. Config behavior is as follows:
config.ini
and is set to a value. That value becomes the app config.config.ini
but is set to an empty string. An envvar with the same name is looked up. The envvar's value is used as the app config.config.py
Published by ColdHeat about 4 years ago
The CTFd v3 Changelog represents the changes from v2.5.0 to v3. It is a summarized version of the changes that occured in all CTFd v3 beta/alpha releases.
CTFd v3 contains some breaking changes but many plugins remain compatible. Themes will need some minor changes to be compatible with v3.
These changes are made with great consideration to existing installations and for the health of the overall CTFd project. If you rely on specific behavior, you can always download the last CTFd v2 release on Github. Official plugin/theme updates will be sent to the email addresses on file.
The major changes in CTFd v3 are as follows with the detailed changelog beneath:
HTML rendering in some cases (challenge description rendering, hint content rendering) has been moved to the server side. Previously it was rendered by the browser but this led to a lot of duplicated behavior and complexity in some plugins. Rendering that HTML content on the server allows CTFd to take more advantage of theme content and reduce duplicated code across themes.
In addition, HTML sanitization can be enabled on the CTFd installation to prevent the injection of malicious scripts in HTML content.
CTFd now uses CommonMark for HTML/Markdown rendering. This leads to much more consistent rendering of HTML/Markdown content.
In some cases, this can break your HTML output. You can use our development testing script to check if your HTML output will change and correct it accordingly.
CTFd no longer directly injects values into the global session object for a theme. You may have used this as {{ nonce }}
or {{ id }}
. Instead these values should be accessed via the Session
global as so: {{ Session.nonce }}
.
All of the public facing forms in CTFd have been converted to form globals with WTForms. You can access them via the Form
global in Jinja. For example, {{ Forms.auth.LoginForm() }}
. A {{ form.nonce() }}
function is available on all forms for easier access to the CSRF nonce as well.
Old forms will still work if the nonce used in the form is updated to {{ Session.nonce }}
.
Values provided by configuration and plugins can now be accessed via the Configs
and Plugins
globals. For example {{ Configs.ctf_name }}
and {{ Plugins.scripts }}
. See the base.html
file of the core theme to get an idea of how to use these values.
Challenge type plugins now have better re-useability with the rest of CTFd. Plugin code no longer needs to copy unchanged methods over from the base challenge plugin classes.
In addition, challenge HTML is now rendered on the server side using a new challenge.html
file provided by the current theme. This means that the theme effectively controls how a challenge should look overall, but the challenge plugin controls the overall content.
CTFd v3 is Python 3 only.
The Docker image used in CTFd is now based on Debian.
Instead of editting config.py
directly, it's now a better idea to edit config.ini
or provide your configuration via environment variables
General
cmarkgfm
HTML_SANITIZATION
server side configuration valueConfig
, User
, Team
, Session
, and Plugin
globals into JinjaAdmin Panel
API
GET /api/v1/config/<config_key>
to return structured data according to ConfigSchemaPATCH /api/v1/users/[user_id]
html
item for GET /api/v1/hints/[hint_id]
which contains the rendered HTML of the Hint contentcontent
from GET /api/v1/hints
Themes
Configs
global which provides wrapped access to get_config
.
{{ Configs.ctf_name }}
instead of get_ctf_name()
or get_config('ctf_name')
challenge.html
which control how a challenge should look.{{ Forms }}
{{ Configs.theme_settings }}
Plugins
challenge.html
from the provided theme./api/v1/challenges/<challenge_id>
in the view
section. This allows for HTML to be properly sanitized and rendered by the server allowing CTFd to remove client side Jinja rendering.challenge.html
now specifies what's required and what's rendered by the theme. This allows the challenge plugin to avoid having to deal with aspects of the challenge besides the description and input.get_standings()
, get_team_stanadings()
, get_user_standings()
now has a fields keyword argument that allows for specificying additional fields that SQLAlchemy should return when building the response set.
FlagException
override_template()
functionalityDeployment
pool_pre_ping
by default to reduce the likelihood of database connection issuesdocker-compose.yml
now uses a non-root user to connect to MySQL/MariaDBconfig.py
should no longer be editting for configuration, instead edit config.ini
or the environment variables in docker-compose.yml
Miscellaneous