Threatspec
threatspec - continuous threat modeling, through code
Install / Use
/learn @threatspec/ThreatspecREADME
threatspec - continuous threat modeling, through code
Threatspec is an open source project that aims to close the gap between development and security by bringing the threat modelling process further into the development process. This is achieved by having developers and security engineers write threat modeling annotations as comments inside source code, then dynamically generating reports and data-flow diagrams from the code. This allows engineers to capture the security context of the code they write, as they write it. In a world of everything-as-code, this can include infrastructure-as-code, CI/CD pipelines, and serverless etc. in addition to traditional application code.
Getting started
Step 1 - Install threatspec
$ pip install threatspec
You'll also need to install Graphviz for the report generation.
Step 2 - Initialise threatspec in your code repository
$ threatspec init
Initialising threatspec...
Threatspec has been initialised. You can now configure the project in this
repository by editing the following file:
threatspec.yaml
You can configure threatspec by editing the threatspec.yaml configuration file which looks something like this:
# This file contains default configuration for a threatspec-enabled repository
# Warning: If you delete this file, threatspec will treat this directory as a normal source path if referenced by other threatspec.yaml files.
project:
name: "threatspec project" # Name of your project. This might be you application name or a friendly name for the code repository.
description: "A threatspec project." # A description of the project. This will be used in the markdown report as well as the name.
imports: # Import other threatspec projects into this one.
- './' # Current directory isn't strictly necessary as this is processed anyway. Just here as an example.
paths: # Source code paths to process
- './' # Parse source files in the current directory by default.
# - 'path/to/repo1' # You can refer to other repositories or directories as needed
# - 'path/to/repo2' # ... and you can do this as much as you like
# - 'path/to/source/file.go' # You can directly reference source code files and directories
# - path: 'path/to/node_source # You can also provide ignore paths for a path by providing a dictionary
# ignore: # Any sub-paths defined in this array are ignored as source files within the path are recursively parsed
# - 'node_modules'
# - path: 'path/to/config.py'
# mime: 'text/x-python' # You can explicitly set the mime type for files if needed
Step 3 - Annotate your source code with security concerns, concepts or actions
// @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)
}
Step 4 - Run threatspec against your source code
$ threatspec run
Running threatspec...
Threatspec has been run against the source files. The following threat mode file
has been created and contains the mitigations, acceptances, connections etc. for
the project:
threatmodel/threatmodel.json
The following library files have also been created:
threatmodel/threats.json threatmodel/controls.json threatmodel/components.json
Step 5 - Generate the threat model report
$ threatspec report
Generating report...
The following threat model visualisation image has been created: ThreatModel.md.png
The following threat model markdown report has been created: ThreatModel.md
Example report
<img src="https://github.com/threatspec/threatspec/raw/master/doc/report.png" width="300">See https://github.com/threatspec/threatspec_example_report.
Getting help
For more information, use the command line help flag.
$ threatspec --help
Usage: threatspec [OPTIONS] COMMAND [ARGS]...
threatspec - continuous threat modeling, through code
threatspec is an open source project that aims to close the gap between
development and security by bringing the threat modelling process further
into the development process. This is achieved by having developers and
...
Annotating your code
Supported file types
At the heart of threatspec there is a parser that reads source code files and processes any annotations found in those files. It uses a Python library called comment_parser to extract those comments. The comment_parser library determines the file's MIME type in order to know which type of comments need to be parsed. The supported file MIME types are:
| Language | Mime String | |------------ |------------------------- | | C | text/x-c | | C++/C# | text/x-c++ | | Go | text/x-go | | HTML | text/html | | Java | text/x-java-source | | Javascript | application/javascript | | Shell | text/x-shellscript | | XML | text/xml |
An unknown MIME type will result in a warning and the file will be skipped.
See https://github.com/jeanralphaviles/comment_parser for details.
In addition to these, threatspec will also soon parse the following files natively:
- YAML
- JSON
- Plain text
If the MIME type for a file can't be determined, or if it is incorrect, you can override the MIME type for a path in the threatspec.yaml configuration file.
Comment types
There are four main comment types supported by threatspec.
Single-line
A single-line comments are the most common use-case for threatspec as they allow you to capture the necessary information as close as possible to the code. An example would be
// @mitigates WebApp:FileSystem against unauthorised access with strict file permissions
func (p *Page) save() error {
Multi-line
If you want to capture multiple annotations in the same place, you could use multiple single-line comments. But you can also use multi-line comments instead:
/*
@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)
}
More importantly, if you want to use the extended YAML syntax (see below), you'll need to use multi-line comments:
/*
@mitigates WebApp:FileSystem against unauthorised access with strict file permissions:
description: |
The file permissions 0600 is used to limit the reading and writing of the file to the user and root.
This prevents accidental exposure of the file content to other system users, and also protects against
malicious tampering of data in those files. An attacker would have to compromise the server's user
in order to modify the files.
*/
func (p *Page) save() error {
filename := p.Title + ".txt"
return ioutil.WriteFile(filename, p.Body, 0600)
}
Inline
You can add comments to the end of lines that also contain code. This can be useful, but might result in rather long lines. Probably best to use these for @review annotations.
err = ioutil.WriteFile("final-port.txt", []byte(l.Addr().String()), 0644) // @review WebApp:Web Is this a security feature?
YAML and JSON
Finally, the last comment type isn't really a comment at all. Rather, it's addtional keys in JSON or YAML data files using the x-threatspec extension key. This was primarily chosen to be compatible with OpenAPI/Swagger files but might work in other circumstances. The rest of the threatspec annotation is essentially the same. So a very simple example would be something like:
servers:
- url: http://petstore.swagger.io/v1
x-threatspec: "@exposes Petstore:Web to Man in the Middle (#mitm) with lack of TLS"
A more complete example using the extended syntax just uses the threatspec annotation as a key:
post:
summary: Create a pet
operationId: createPets
tags:
- pets
x-threatspec:
"@exposes Petstore:Pet:Create to Creation of fake pets with lack of authentication":
description: "Any anonymous user can create a pet because there is no authentication and authorization"
Summary of annotations
Here is a quick summary of each supported annotation type. For a full description, see the Annotations section below.
| Annotation | Example |
| ---------- | ------- |
| @component - a hierarchy of components within the application or service. | @component MyApp:Web:Login |
| @threat - a threat | @threat SQL Injection (#sqli) |
| @control - a mitigating control | @control Web Application Firewall (#waf) |
| @mitigates - a mitigation against a particular threat for a component, using a control | @mitigates MyApp:Web:Login against Cross-site Request Forgery with CSRF token generated provided by framework |
| @exposes - a component is exposed to a particular threat | @exposes MyApp:CICD:Deployment to rogue code changes with lack of separation of duty |
| @accepts - the acceptance of a threat against a compo
