A suite for managing risks in multiple projects.
Development
Pre requirements
This Suite uses django, and go-task for basic fast setup of django.
-
poetry:
pacman -Sy poetry
Startup of the suite
-
clone this repository
-
run
go-task first-init-
it will ask for a password, this password is for your superuser with the username admin
-
This task migrates alle migrations, and adds all initial fixtures to the databases
-
-
to start the development server from now on run
go-task run-devel
Adding initial test data
To create a simple testbase run go-task add-test-fixture, this also creates a user called testuser with the password: LetMeIn-01
Usage
Adding risks
In general a Risk can be defined without a specific product/project in mind. That way multiple product/project teams can share their knowledge about possible risks and only one source will be used for those, if one changes/enhances the description all others will have that knew information available. Each risk will then be evaluated on a per project basis. Depending on the project a risk might be nearly non existent for one but would have a heavy impact on the other project. So the impact will be project dependant. Mitigations will then be shared through projects, again other projects can reuse the thoughts of others on how to mitigate/fix risks.
To add or change risks you have to enter the admin interface of the system (http://127.0.0.1:8000/admin) login as an admin and start adding risks and mitigations
Adding projects
-
First you need to create a new project
-
Then you create a new Risk analysis and give it a "nice name"
-
then you add risks to that analysis and add initial risk ratings
-
later on you can add possible mitigations, evidences and after mitigation risk analysis’s
The views
-
Are accessible via http://127.0.0.1:8000 will just show the risk analysis’s nice colorized and not so spread through the tables.
-
They also display charts of the current project
The api
Browse to /graphql to see an interactive GraphQl Ui to build up your graphql query.
-
example single api call with login:
#!/bin/bash BASE_URL=https://localhost:8443/ LOGIN_URL=${BASE_URL}login YOUR_USER='admin' YOUR_PASS='nimda' COOKIES=/tmp/cookies.txt CURL_CALL="curl -k -s -c ${COOKIES} -b ${COOKIES} -e ${LOGIN_URL}" echo "Django Auth: get csrftoken ..." ${CURL_CALL} ${LOGIN_URL} > /dev/null DJANGO_TOKEN="csrfmiddlewaretoken=$(grep csrftoken ${COOKIES} | sed 's/^.*csrftoken\s*//')" echo " perform login ..." ${CURL_CALL} \ -d "${DJANGO_TOKEN}&username=${YOUR_USER}&password=${YOUR_PASS}" \ -X POST \ ${LOGIN_URL} echo " do api call ..." ${CURL_CALL} \ -H "Content-Type: application/json" \ -d '{"query": "query { productByTitle(title:\"IconTrust HMI\") { analyzes { riskEntries { risk { asset { name }, origin { name }, stride { name }, title, description } } } } }"}' \ -X GET \ ${BASE_URL}graphql echo echo " logout" rm ${COOKIES} -
example that creates an adoc table from the result:
#!/bin/bash BASE_URL=https://localhost:8443/ LOGIN_URL=${BASE_URL}login YOUR_USER='admin' YOUR_PASS='nimda' COOKIES=/tmp/cookies.txt CURL_CALL="curl -k -s -c ${COOKIES} -b ${COOKIES} -e ${LOGIN_URL}" OUTPUT_ADOC_TABLE=/tmp/output-api-table.adoc trap 'rm -f ${COOKIES}' EXIT # get csrf token ${CURL_CALL} ${LOGIN_URL} > /dev/null DJANGO_TOKEN="csrfmiddlewaretoken=$(grep csrftoken ${COOKIES} | sed 's/^.*csrftoken\s*//')" # login ${CURL_CALL} \ -d "${DJANGO_TOKEN}&username=${YOUR_USER}&password=${YOUR_PASS}" \ -X POST \ ${LOGIN_URL} ${CURL_CALL} \ -H "Content-Type: application/json" \ -d '{"query": "query { productByTitle(title:\"IconTrust HMI\") { analyzes { riskEntries { risk { asset { name }, origin { name }, stride { name, full }, title, description } } } } }"}' \ -X GET \ ${BASE_URL}graphql > /tmp/result.json # trap 'rm -f /tmp/result.json' EXIT echo "{counter2:index:0}" > ${OUTPUT_ADOC_TABLE} echo "|===" >> ${OUTPUT_ADOC_TABLE} echo "| Nr | Asset | Origin | Stride | Title | Description" >> ${OUTPUT_ADOC_TABLE} echo "" >> ${OUTPUT_ADOC_TABLE} jq -r '.data.productByTitle.analyzes[].riskEntries[] | " | {counter:index} | \(.risk.asset.name) | \(.risk.origin.name) | \(.risk.stride | map(.full) | join(", ")) | \(.risk.title) | \(.risk.description | gsub("</li><li>"; " +\n") | gsub("</div>"; " +\n") | gsub("<[^>]*>"; "") | gsub("\r\n"; " +\n")) "' \ /tmp/result.json \ >> ${OUTPUT_ADOC_TABLE} echo "|===" >> ${OUTPUT_ADOC_TABLE} echo "created ADOC table at: »${OUTPUT_ADOC_TABLE}«"
Production docker
docker run --rm -it \
--name product-risk-suite-production \
--volume ./docker/data:/data \
--volume ./docker/config:/config \
-e DJANGO_SUPERUSER_USERNAME=admin \
-e DJANGO_SUPERUSER_PASSWORD=nimda \
-e DATABASE_ENGINE=sqlite3 \
-e DATABASE_NAME=/data/product-risk-db.sqlite3 \
-e DJANGO_DEBUG=${DJANGO_DEBUG} \
-e SET_FIXTURES=true \
-e DJANGO_ALLOWED_HOSTS=${DJANGO_ALLOWED_HOSTS} \
-e DJANGO_CSRF_TRUSTED_ORIGINS=${DJANGO_CSRF_TRUSTED_ORIGINS} \
-p 8443:443 \
product-risk-suite:latest
Or run the the task: go-task docker-build-setup-run, which will also build the container.
docker run --rm -it \
--name product-risk-suite-production \
--volume ./docker/data:/data \
--volume ./docker/config:/config \
-e DATABASE_ENGINE=sqlite3 \
-e DATABASE_NAME=/data/product-risk-db.sqlite3 \
-e DJANGO_DEBUG=${DJANGO_DEBUG} \
-e SET_FIXTURES= \
-e DJANGO_ALLOWED_HOSTS=${DJANGO_ALLOWED_HOSTS} \
-e DJANGO_CSRF_TRUSTED_ORIGINS=${DJANGO_CSRF_TRUSTED_ORIGINS} \
-p 8443:443 \
product-risk-suite:latest
Or run the the task: go-task docker-build-run, which will also build the container.
ENV DJANGO_SECRET_KEY="django-insecure-scwz(sj+*te-dbfuc)vnkju5y1=p1en^d#8mz5*keg2(fj^mn-dudi-bla%" ENV DJANGO_DEBUG= ENV DJANGO_SUPERUSER_USERNAME=admin ENV DJANGO_SUPERUSER_PASSWORD=adminpassword ENV DJANGO_SUPERUSER_EMAIL=admin@example.com ENV DATABASE_ENGINE=sqlite3 ENV DATABASE_NAME= ENV DATABASE_USERNAME= ENV DATABASE_PASSWORD= ENV DATABASE_HOST= ENV DATABASE_PORT= ENV SET_FIXTURES=true ENV DJANGO_LOG_LEVEL=INFO
you should know which to overwrite with values you suite the most
VOLUME /data VOLUME /config
To customize your run you can use a local .env file, for this copy the file dot-env.example to .env (next to the topmost Taskfile.yml).
Adjust the parameters inside the .env, and then simply run one of the above taskfile jobs
Threat model support
Creating a suitable threat model
Currently only threat models created with drawio are supported.
Use the "Threat Modeling" items or any other you might like.
The important part is that each communication way you want to add risks to need a recognizable id set.
To set such an id you need to click the item inside drawio, select the Style Tab, then click on the Edit-Button and select Edit Data from the drop down.
Inside the Dialog do a double click on the text behind the ID and change it to something useful.
Basically each editor is capable of creating a working threat model as long as the svg items that should be selectable contain an attribute called data-cell-id with a name you recognize.