Firstly...

Not just for security..

Format threat model?

As far as I can tell, the only capital-T, formal threat model, is a threat model performed in formal attire

Remember: At its core, threat modelling is a means to try and make a fairly subjective process more objective, repeatable & consistent.

Security should not be gatekeeping threat modelling

Instead, we should be empowering all platform & product engineering teams to start with asking themselves..

What could go wrong?

Secondly..

Threat modelling must deliver value

.. and finally..

Tooling should align with Engineers

What is Threat Modelling?

A collaborative process executed by multiple people to identify technical security issues in a solution, often based on design, architecture, or purely software.

STRIDE

An established mnemonic tool to help with repeatable threat modelling

(go down to read more)

Spoofing

Threat action aimed at accessing and use of another user’s credentials, such as username and password.

Tampering

Threat action intending to maliciously change or modify persistent data, such as records in a database, and the alteration of data in transit between two computers over an open network, such as the Internet.

Repudiation

Threat action aimed at performing prohibited operations in a system that lacks the ability to trace the operations.

Information Disclosure

Threat action intending to read a file that one was not granted access to, or to read data in transit.

Denial of Service

Threat action attempting to deny access to valid users, such as by making a web server temporarily unavailable or unusable.

Elevation of Privilege

Threat action intending to gain privileged access to resources in order to gain unauthorized access to information or to compromise a system.

I like leveraging the "5 whys" approach, but instead of asking "why" something went wrong, we ask...

What could go wrong?

In many of the formal methodologies there is a focus on “diagrams” - and this is where we run into our first ...

Challenge

I've seen many different approaches in the industry to threat modelling.

1. Ad-hoc documentation

Is better than nothing.

It could be unstructured, or random confluence pages

You may have a standard template!

2. Expensive commercial tools

are better than nothing.

Often they integrate into your cloud solutions to help generate data flow diagrams and the like

They always come with extensive pre-defined list of threats, risks and controls

What if there was another option?

Let's talk about some open source tools that take a dev-first approach
This is threatspec.org

// @accepts arbitrary file writes to WebApp:FileSystem
//   with filename restrictions
// @mitigates WebApp:FileSystem against unauthorised
//   access with strict file permissions

func (p *Page) save() error {
    filename := p.Title + ".txt"
    return ioutil.WriteFile(filename, p.Body, 0600)
}
          
With this, you annotate your existing source code using comments, such as these.

When you run the threatspec tools, it will output reports, DFDs and other artifacts.

This is github.com/OWASP/pytm

#!/usr/bin/env python3

from pytm.pytm import TM, Server, Datastore, Dataflow, Boundary, Actor, Lambda, Data, Classification

tm = TM("my test tm")
tm.description = "another test tm"
tm.isOrdered = True

User_Web = Boundary("User/Web")
Web_DB = Boundary("Web/DB")

user = Actor("User")
user.inBoundary = User_Web

web = Server("Web Server")
web.OS = "CloudOS"
web.isHardened = True
web.sourceCode = "server/web.cc"

db = Datastore("SQL Database (*)")
db.OS = "CentOS"
db.isHardened = False
db.inBoundary = Web_DB
db.isSql = True
db.inScope = False
db.sourceCode = "model/schema.sql"

comments = Data(
    name="Comments", 
    description="Comments in HTML or Markdown",  
    classification=Classification.PUBLIC,  
    isPII=False,
    isCredentials=False,  
    # credentialsLife=Lifetime.LONG,  
    isStored=True, 
    isSourceEncryptedAtRest=False, 
    isDestEncryptedAtRest=True 
)

results = Data(
    name="results", 
    description="Results of insert op",  
    classification=Classification.SENSITIVE,  
    isPII=False, 
    isCredentials=False,  
    # credentialsLife=Lifetime.LONG,  
    isStored=True, 
    isSourceEncryptedAtRest=False, 
    isDestEncryptedAtRest=True 
)

my_lambda = Lambda("cleanDBevery6hours")
my_lambda.hasAccessControl = True
my_lambda.inBoundary = Web_DB

my_lambda_to_db = Dataflow(my_lambda, db, "(λ)Periodically cleans DB")
my_lambda_to_db.protocol = "SQL"
my_lambda_to_db.dstPort = 3306

user_to_web = Dataflow(user, web, "User enters comments (*)")
user_to_web.protocol = "HTTP"
user_to_web.dstPort = 80
user_to_web.data = comments

web_to_user = Dataflow(web, user, "Comments saved (*)")
web_to_user.protocol = "HTTP"

web_to_db = Dataflow(web, db, "Insert query with comments")
web_to_db.protocol = "MySQL"
web_to_db.dstPort = 3306

db_to_web = Dataflow(db, web, "Comments contents")
db_to_web.protocol = "MySQL"
db_to_web.data = results

tm.process()
          
For those into the pythonic arts, PyTM is a good one to check out. Mind you, you do have to write actual python code.

This is Threatdragon from OWASP. Unfortunately, it's not really threat modelling as code

Now I want to spend some time talking about an open source tool I've been tinkering away on the last few years. Threatcl.

Here is a simple example

(go ahead, you can scroll down too)


threatmodel "Tower of London" {
  description = "A historic castle"
  author = "@xntrik"

  attributes {
    new_initiative = "true"
    internet_facing = "true"
    initiative_size = "Small"
  }

  information_asset "crown jewels" {
    description = "including the imperial state crown"
    information_classification = "Confidential"
  }

  usecase {
    description = "The Queen can fetch the crown"
  }

  third_party_dependency "community watch" {
    description = "The community watch helps guard the premise"
    uptime_dependency = "degraded"
  }

  threat {
    description = "Someone who isn't the Queen steals the crown"
    impacts = ["Confidentiality"]

    expanded_control "Guards" {
      description = "Trained guards patrol tower"
      risk_reduction = 75
    }
  }
}
          

Plus, now we can use CI/CD, such as github actions, to validate your hcl files, and even publish dashboards.


name: threatcl dashboard

on:
  push:
    branches:
      - main

jobs:
  threatcl-dashboard:
    permissions:
      contents: write
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      - name: threatcl dashboard
        uses: threatcl/[email protected]
        with:
          command: 'dashboard'
          files: './hcl-files/*'
          outdir: './dashboard'
      - name: threatcl custom dashboard
        uses: threatcl/[email protected]
        with:
          command: 'dashboard'
          files: './hcl-files/*'
          outdir: './custom-dashboard'
          dashboard-template: './templates/dashboard-template.tpl'
          dashboard-filename: 'db'
          threatmodel-template: './templates/threatmodel-template.tpl'
      - name: threatcl custom html dashboard
        uses: threatcl/[email protected]
        with:
          command: 'dashboard'
          files: './hcl-files/*'
          outdir: './html-dashboard'
          dashboard-template: './templates/dashboard-template-html.tpl'
          dashboard-filename: 'index'
          threatmodel-template: './templates/threatmodel-template-html.tpl'
          dashboard-html: 'true'
          

You can see this example here.

Threatcl can generate data flow diagrams too.

Here you can see a rule that will flag a threat model that has a threat without any controls.

(go ahead, you can scroll down too)


- id: threatcl-missing-control
    patterns:
      - pattern: |
          threat {
            ...
            description = "$THREAT"
            ...
          }
      - pattern-not: |
          threat {
            ...
            expanded_control "$CONTROL_NAME" {
              ...
            }
            ...
          }
    message: "The `threat` block '$THREAT' is missing an `expanded_control`"
    severity: WARNING
    languages: [hcl]
    metadata:
      category: security
      cwe: "CWE-657: Violation of Secure Design Principles"
      confidence: LOW
      likelihood: LOW
      impact: LOW
      subcategory:
        - audit
          

See the example here

Here is an example of what a finding looks like:

And guess what? It generated a perfectly valid file on the first attempt.

What does the DFD look like?

Much better.