Configuration is controlled in two files; config.py
controls database connection information, whilst
levels.py
acts as configuration for each level.
This file exposes 3 main symbols.
get_password
should return the database password for a given userdb_host
is the host on which the mysql database residesdb_setup
exposes a list of known username, database, and schema file triplets- For a given setup
user
is the username of a user with rights to access the databasedatabase
is the name of the database which holds the table for the given set of challengesschema
is a file containing the database schema
- For a given setup
Levels contains the configurations for each level and group.
groups
exposes all the groups in the tutorial. This should be an array of objects with the propertiesname
: Name of the groupdifficulty
: Brief flavor text describing the difficulty of the groupflavor
: Flavor text for the groupdb
: An associateddb_setup
object fromconfig.py
levels
contains the specifications for each level, these contain 4 entriestype
: What the type of the challenge is, this should be eithersql
or a string prefixed withsqli-
group
: The index of the group this challenge belongs to (index ingroups
)name
: Name of the challengespec
: A dictionary describing the specification of a challenge. See below for more
The bulk of this file lies in the spec
field. This configures the challenge. The type
field will inform
the program what type the spec
is. Namely a type=sql
spec will be handled differently to a type=sqli
spec.
A sql
spec should include
question
: A one-line question prompttemplate
: A template for the sql that should be entered.{qN}
indicates blanks the user needs to fill in.N
should be a0
indexed increasing sequence- e.g.
SELECT {q0} FROM {q1} WHERE {q2}
will appear asSELECT ___ FROM ___ WHERE ___
- e.g.
match
: A well-formed SQL query producing the expected result. This user's sql will be compared with the output of this query- Order matters
flag
: A flag to give the user if their query matches thematch
queryerror-control
: One offull
,error
, orblind
full
error control will return both the sql error message and the query that was execute back to the usererror
error control will only return the sql errorblind
error control will return no feedback
A sqli
spec should include
question
: same assql
show
: A dictionary containing an identifier followed by place holder text that should be shown to the user- e.g.
{'q0': 'Flag Id'}
will show a input with placeholderFlag Id
to the user- Specifically at least the html
<input name="q0" placeholder="Flag Id">
will be generated
- Specifically at least the html
- e.g.
template
: A sql query with{identifier}
s corresponding to the identifiers inshow
. The user's inputs inshow
will be substituted here.match
: same assql
flag
: same assql
error-control
: same assql
- Generate a .env file with a random MYSQL_ROOT_PAASSWORD.
MYSQL_ROOT_PASSWORD=random_password
- Start up the database and app server by running
docker-compose up
. - Run the database setup.
docker exec -it sqli-tutorial_app_1 /bin/sh -c 'python /app/app/_setup.py root "$MYSQL_ROOT_PASSWORD"'
Ensure mysql is running (on port 3306). Once config.py
is appropriately setup,
simply invoking the following from within /app
will setup all appropriate
users, databases, and schemas.
python3 _setup.py <root username> <root password>
The application can be run locally with the following from within /app
. This will listen on port 5001
.
python3 app.py
Alternatively gunicorn can also be used to run the application. For production workloads gunicorn
should be deployed with at least gevent
or a reverse proxy.