Threat Modeling for Applications


Whether you are running a bug bounty, or just want a useful way to classify the severity of security issues, it’s important to have a threat-model for your application. There are many different types of attackers, with different capabilities. If you haven’t defined the attackers you are concerned about, and how you deal with them – you can’t accurately define just how critical an issue is.

There are many different views on threat models; I’m going to talk about a simple form that’s quick and easy to define. There are books, tools, and countless threat modeling techniques – it can easily be overwhelming. The goal here is to present something that can add value, while being easy to document.

The Threat Actors

To define the threat model, you must define the different types of attackers that your application may face; some of these apply more to some applications than others. In some cases, it may be perfectly reasonable to say that you don’t protect against some of these – what’s important is to clearly document that fact.

It’s also important to think about what attackers want to achieve – are they trying to steal sensitive data such as credit card numbers or user credentials, tamper with existing data – from business plans to student grades, disrupt services (which can come at great cost), or attacking for some other purpose. There are countless reasons for attackers to target an application, some are important to understand (such as stealing credit card numbers) to prioritize protection mechanisms – in some cases, such as those that attack just because they can, it’s impossible to prioritize to protect against them, as there’s no way to predict how they’ll attack.

Passive Attackers

Passive attackers are in a position that they are able to see communications, but can’t (or won’t, to avoid detection) modify those communications. The solution to most of the passive attackers is to encrypt everything – this not only eliminates most of the passive attacks, it eliminates or greatly complicates many active attacks.

Local (User)

One of the most common examples of a local passive attacker is an evil barista – you are working from a coffee shop and on their open WiFi. At that point, they (and many others) can easily see your network traffic. This also applies to corporate networks and many other environments. What information can a Passive-Local attacker gain to perform attackers later?

Local (Server)

Users aren’t the only ones that have to worry about local passive threats, an attacker monitoring the traffic going to and from a server can be quite effective (rogue monitor port on a local switch perhaps). By watching this traffic, an attacker can gain a great deal of information for future use, and perform some very effective attacks.

One example is a password reset email – if not encrypted, an attacker could capture the reset link, and change a user’s password. This is especially effective if the attacker triggered the password reset themselves. This is made worse, due to the common user training to ignore password reset emails that they didn’t request. As an example of this, let’s look at the email that Twitter sends when you request a password reset:


The all too common verbiage “If you didn’t make this request, please ignore this email” is present – an attacker requests a password reset, and waits for the email to go through. If the connection between the application and the remote email service isn’t encrypted, an attacker could easily take over accounts.


Upstream providers, from the server or client end, are in a position where they have easy access to information – they are also a target for those that want that information; and they will provide it, sometimes willingly, sometimes by force. These positions of power allow for transparently monitoring all traffic to and from a device – giving no indication that an attack is ongoing.

As with passive local attackers, any unencrypted communication could be captured, and used real-time, or stored for later use to enable attacks.


A special, and thankfully rare, type of passive attacker is those that have data feeds coming from many locations, and are able to analyze both ends of a communication. This type of attacker is a challenge that only the most sensitive systems need to be concerned with. Perhaps the most public example of an application that is especially vulnerable to this type of attacker is Tor, thanks to traffic correlation.

Active Attackers

Active attackers run the gamut from normal users looking to get around restrictions to professional hackers – with motivations running from boredom to profit. With passive attackers, there’s generally no way to detect an attack, as nothing is being changed. With active attackers, there are often clear signs of their presence – though too often they are missed due to a flood of false positives.

Malicious User

The malicious user is a legitimate user of your application – could be an employee or someone who signed-up from the internet – that seeks to gain additional privileges, gain access to restricted data, or otherwise make your application do whatever they want. In some of the simplest cases, it can be an employee looking to gain extra privileges to bypass required work, or it can be an attacker that is looking to steal data from the application’s database.

Most often, this type of attacker will look for easy wins, may try to understand the application by manually studying the application, or may just use one of the many tools available to see if there’s an easy way in. Most of the so-called “script kiddies” fit into this category.

Malicious Device

Not only is there a risk of a malicious user, but that a legitimate well-intended user has malware or had their device otherwise been compromised. Attackers can leverage a user’s device to perform attacks as them, or capture information. When a user’s device is compromised, an whole range of attacks are enabled – and allows attacks against many types of applications. It has been well documented that software that allows simple man-in-the-middle attacks can be pre-installed on new PCs – and it can be easily installed via other malware. By performing a local man-in-the-middle attack, an attacker could not only capture information, but inject malicious traffic.

In many cases, there is little to nothing that can be done in these situations, as there’s no reliable way to ensure that a device isn’t compromised.

Advanced / Persistent Attacker

From script kiddies with a lot of time on their hands, to professional hackers, this class of attacker will use similar tactics to the Malicious User, but will move on to more advanced attacks and better tools to achieve their goal. From using effective Cross-Site Scripting (beyond proof-of-concepts like alert('xss')), to SQL Injection, and so many more attack types, these attackers are the ones that are most likely to find real issues. When building a threat model, this class of attacker is likely the most important to consider, as they are the greatest and most likely threat.

IT / SysAdmin

One threat that is too often overlooked is the people running the servers – they have access to the logs, can see the server setup, and in some cases can see the application source code and configuration files. This type of attacker has far more insight than most attackers do – in some cases, it’s assumed that those that run the servers simply must be trusted, as there’s no way to fully protect against them.

This is a case where detailed logging, change approval, and separation of duties – mostly process controls – can help, though are unlikely to prevent someone with this degree of knowledge from taking what they want. When defining a threat model, it’s important to address this issue – identify the technical and procedural controls that are in place, and determine how, or if, you will address the situations where such an attacker could be effective.

Developers / DBA

Perhaps the hardest to address are those that build and maintain the application itself. How do you prevent them from inserting a backdoor? Code reviews are normally the answer, but there are real flaws to relying on them. While there may be policies that prevent developers from accessing the production database or credentials – a simple “mistake” made that displays a detailed error message, or allows SQL or code to be injected can quickly render those policies worthless.

A malicious developer is an extremely difficult attacker to address – because they have so much control, and such intimate knowledge of how their applications work. When defining a threat model, you have to account for a member of the development or DBA staff going rogue, ignoring all policies that get into their way, and inserting backdoors or otherwise opening a door that completely defeats the security of the application

Host / Service Provider

When a host or service provider becomes malicious, it can be difficult to impossible to maintain security. As fewer and fewer applications are hosted within corporate walls, it’s important to understand that there is now an additional team of system administrators, networking and IT support that are suddenly involved. They could modify network traffic, add, remove, or replace hardware, clone drives, etc. – this realization has held many organizations back from moving to the cloud, as the fear of breaches and compliance nightmares is too great.

Another issue often overlooked, is the issue of other users of the same host, and this is especially true when using virtual servers; from side channels that allow encryption keys to be stolen, to breaking out the the hypervisor to attack other servers on the same pyhsical hardware.

For high security applications, building an application that can withstand an assault by its hosting provider is a sizeable challenge, though a challenge that must at least be acknowledged.

Local & Upstream Network Providers

If the local or upstream network providers are used to attack, in one way or another, maintaining security can come with a surprising number of challenges. The key to defeating QUANTUM INSERT is as simple as using HTTPS – but there are others that are more challenging.

I recently reviewed an application that verified that the packages it installed were authentic by checking PGP signatures – unfortunately the PGP public key wasn’t securely delivered. Installing that software when under an active network attack would have allowed the attacker to run their own code as root.

Building A Threat Model

A threat model doesn’t have to be some compliance laden document that means more to auditors than developers and security engineers, it can be a simple listing of threat actors and what the defense against them is – or if a given actor isn’t deemed to be a threat, document that. Having a very simple list-based document can provide guidance to the development team, to those classifying security reports, and to those submitting those reports.

As is true with most things in security, simplicity is key.

A Sample

To get you started, I’ve defined a sample, so you can see how easy this can be to setup for your application (this will also save you a bit of time when setting up a bug bounty or pentest). This is an extremely simple, but useful model – it provides critical information and insight.

Application Name: Summus
Application Type: Web
Public Facing: Yes
Language / Platform: C# / ASP.NET MVC
TLS In Use: Yes

Application Description:

Web-based data capture application with four user roles (user, manager, QA, admin); users are able to read scripting and enter data from phone calls and back office transactions. Managers are able to review captured data, flag transactions for QA review, edit data, and approve transactions. QA is able to review captured data, approve transactions, and mark transactions as reviewed, flag for escalation, and assign a quality score. Administrators are able to setup new campaigns (scripting, data capture, etc.), update scripting, update data capture, change settings (approx. 200 options – some global, some campaign specific).

Application is written in C#, and uses the ASP.NET MVC framework; data is stored in SQL Server, and data access is performed via LINQ to SQL. Application is hosted on a cluster of eight IIS 8.5 servers. Application is hosted behind a CDN with a Web Application Firewall. Data capture fields may be flagged as sensitive, and encrypted using AES-256-GCM when stored in the database.


Note: Violations of any of the assumptions listed below, or defects in the processes used are considered to be a vulnerability.

Passive – Local – User: TLS is required; both via redirect from HTTP to HTTPS, and via the Strict-Transport-Security header. Due to these mitigations, it is believed that an attacker monitoring a user’s traffic is not able to gain useful information.

Passive – Local – Server: The server is hosting in a secure, PCI-compliant facility. Firewall rules and switch configurations are audited on a quarterly basis; traffic flows are monitored in real-time by Network Administration; switch ports are set to connect to a single MAC only; unused switch ports are disabled; network access & event logs are monitored in real-time by Network Administration.

Passive – Upstream: Due to the use of TLS, it is believed that an upstream provider is unable to access useful information.

Passive – Global: Due to the use of TLS, it is believed that an upstream provider is unable to access useful information.

Active – Malicious User: The application takes advantage of Cross-Site Scripting and Cross-Site Request Forgery protections provided by the ASP.NET MVC framework; data access is performed via an ORM to eliminate SQL Injection attacks; each page includes permission checks to prevent vertical privilege escalation; a Campaign ID and User ID are stored server-side as part of the session to prevent horizontal privilege escalation.

Active – Malicious Device: As there is no ability to remotely detect if a user’s device has been compromised, this is considered out of scope.

Active – Advanced: In addition to the protections mentioned in the Active – Malicious User section, the application is scanned on a regular basis by commercial scanning tools, and a quarterly pentest is conducted to identify vulnerabilities.

Active – IT / SysAdmin: This scenario is considered to be out of scope for this document. IT controls are documented in a seperate document.

Active – Developer / DBA: All code changes are required to pass through a peer code review prior to being merged into the master branch of source control; developers do not have access to production servers; static code analysis and vulnerability scan is performed prior to deployments; deployments are performed by System Administrators after approval from Change Control group; database server access & event logs are monitored in Real-Time by System Administrators.

Active – Host: Due to other controls, this scenario is considered to be out of scope.

Active – Network Providers: Due to the use of TLS, it is believed that an upstream provider is unable to access useful information, or perform meaningful alteration to traffic.

In closing…

I hope that this will help you define not only a useful threat model for your application, but also come to a better understanding of what threats your application faces and how to address them.