2.1.0 / 2019-04-24
General
- Remove Flask-SocketIO in favor of custom Server Side Events code
- Removed the Flask-SocketIO dependency and removed all related code. See Deployment section.
- Added EventSource polyfill from Yaffle/EventSource
- Events are now rate-limited and only availble to authenticated users
- This means real time notifications will only appear to authenticated users
- Browser localStorage is now used to dictate which tab will maintain the persistent connection to the
/events
endpoint- Thanks to https://gist.github.com/neilj/4146038
- Notifications (currently the only use of the events code) now appear with a notification sound
- Thanks to Terrence Martin for the sound
- Added UI to delete and download files from the media library
- Progress bars have been added to some actions which could take time
- To file uploads on challenge page
- To file uploads on the page editor page
- To the import CTF functionality
- Challenge file downloads now require a token to download
/files/<path>
now accepts a?token=
parameter which is a serialized version of{user_id: <>, team_id: <>, file_id: <>}
- If any of these sections are invalid or the user/team is banned the download is blocked
- This allows files to be downloaded via
curl
orwget
(i.e. without cookie authentication)
- Added a team captain concept. Team captains can edit team information such as name, team password, website, etc.
- Only captains can change their team's captain
- Captains are the first to join the team. But they can be transferred to the true captain later on
- Cache
/api/v1/scoreboard
and/api/v1/scoreboard/top/[count]
- Adds
cache.make_cache_key
because Flask-Caching is unable to cleanly determine the endpoint for Flask-Restplus - This helper may change in a future release or be deprecated by an improvement in Flask-Caching
- Adds
- Properly load hidden and banned properties in the admin team edit modal
- Adds a hover color change on table rows in the admin panel.
- If a table row specifies the
data-href
attribute it will become clickable
- If a table row specifies the
- Add a simple Makefile to wrap some basic commands
- make lint: lint the code base
- make test: test the code base
- make serve: create a debug application server
- make shell: create a Python shell with the application preloaded
- Started work on a Sphinx documentation site available at https://docs.ctfd.io
Dependencies
- Upgraded
SQLAlchemy
to 1.3.3 for proper JSON columns in SQLite - Pin
Werkzeug==0.15.2
in requirements.txt - Flask-Profiler added to
serve.py --profile
Models
- Awards table now has a
type
column which is used as a polymorphic identity - Add
Teams.captain_id
column to Teams table
API
- Added /api/v1/teams/[team_id]/members
- Cache
/api/v1/scoreboard
and/api/v1/scoreboard/top/[count]
- Adds
cache.make_cache_key
because Flask-Caching is unable to cleanly determine the endpoint for Flask-Restplus - This helper may change in a future release or be deprecated by an improvement in Flask-Caching
- Adds
- Add
/api/v1/users?notify=true
to email user & password after creating new account - Fix issue where admins could not modify their own profile or their own team
Plugins
CTFd.utils.security.passwords
deprecated and now available atCTFd.utils.crypto
- Built-in challenge plugins now linkify challenge text properly
- Challenge type plugins do not have to append
script_root
to file downloads anymore as that will now be managed by the API - Awards are now polymorphic and subtables can be created for them
Themes
- Fix spelling mistake in
500.html
- Removed
socket.io.min.js
frombase.html
- Added EventSource polyfill from Yaffle/EventSource
- Added
howler.js
to play notification sounds - Vendored/duplicated files which were shared between the
admin
andcore
themes have been de-duped- The files used in the
core
theme should now be considered free to use by other themes
- The files used in the
- CTF start and end times are now injected into
base.html
and available in theCTFd.js
object - Register page now properly says "User Name" instead of "Team Name" since only users can see the Register page
- Users and Teams pages now use a public and private page.
- user.html -> users/public.html and users/private.html
- team.html -> teams/public.html and teams/private.html
- Separate
admin/templates/modals/users/create.html
intoadmin/templates/modals/users/edit.html
Exports
- Exports will now properly export JSON for all JSON columns
- In some configurations the column would be exported as a string.
- Legacy string columns will still be imported properly.
- Exports from old 2.x CTFd versions should upgrade and be installed properly
- Any failure to do so should be considered a bug
Deployment
- User is no longer
root
in Docker image- Errors in writing log files will now fail silently as we expect a future rewrite
- Logs will now also go to stdout
- Update Dockerfile to create and chown/chmod the folders used by
docker-compose
to store files/logs (/var/log/CTFd
,/var/uploads
)- This allows the container to write to the folder despite it being a volume mounted from the host
- Default worker changed back to
gevent
- Removed Flask-SocketIO dependency
- Removed the
SOCKETIO_ASYNC_MODE
config
- Removed the
gevent
is now required to allow the Server Sent Events client polling code to work- If you use the provided
wsgi.py
orgevent
gunicorn workers, there shouldn't be any issues
- If you use the provided
- Cache
/api/v1/scoreboard
and/api/v1/scoreboard/top/[count]
which is invalidated on new solves or every minute
Configuration
- Added
SWAGGER_UI
setting to config.py to control the existence of the/api/v1/
Swagger UI documentation - Removed the
SOCKETIO_ASYNC_MODE
config - Renamed docstring that referenced
SQLALCHEMY_DATABASE_URI
toDATABASE_URL
- The
REVERSE_PROXY
configuration can be set toTrue
or to a comma seperated string of integers (e.g.1,1,1,1,1
)- See https://werkzeug.palletsprojects.com/en/0.15.x/middleware/proxy_fix/#werkzeug.middleware.proxy_fix.ProxyFix
- For example to configure
x_for=1, x_proto=1, x_host=1, x_port=1, x_prefix=1
specify1,1,1,1,1
Tests
- Tests are now executed in parallel
- When using a non-memory database, test helpers will now randomize the database name to be able to parallelize execution
- Test tool switched from
nosetests
topytest
- Lint tool switched from
pycodestyle
toflake8
- Basic security checking added using
bandit
- Allow
create_ctfd()
test helper to take app configuration as an argument