A suite for managing risks in multiple projects.

Development

Pre requirements

This Suite uses django, and go-task for basic fast setup of django.

Install following tools:
  1. poetry: pacman -Sy poetry

Startup of the suite

  1. clone this repository

  2. run go-task first-init

    1. it will ask for a password, this password is for your superuser with the username admin

    2. This task migrates alle migrations, and adds all initial fixtures to the databases

  3. 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

  1. First you need to create a new project

  2. Then you create a new Risk analysis and give it a "nice name"

  3. then you add risks to that analysis and add initial risk ratings

  4. later on you can add possible mitigations, evidences and after mitigation risk analysis’s

The views

  1. 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.

  2. 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.

some example scripts:
  • 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

Example run of the container (with redeploy of default fixtures):
        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.

Example run of the container (WITHOUT redeploy of default fixtures):
        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.

Available docker environment variables are:
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

Useful volumes to create:
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.