Driver writers and architects should make threat modeling an integral part of the design process for any driver. This paper provides guidelines for creating threat models for drivers for the Microsoft Windows family of operating systems.
| Introduction | |
| Creating Threat Models for Drivers | |
| Points to Consider | |
| Call to Action and Resources |
Security should be a fundamental design point for any driver. Any successful product is a target. If you are writing a driver for Microsoft Windows operating systems, you must assume that sometime, somewhere, someone will try to use your driver to compromise system security.
Designing a secure driver involves:
| • | Identifying the points at which the driver could be vulnerable to an attack. |
| • | Analyzing the types of attacks that could be mounted at each such point. |
| • | Ensuring that the driver contains features to prevent or thwart such attacks. |
Threat modeling is a structured approach to these important design tasks. A threat model is a way of categorizing and analyzing the threats to an asset. From a driver writer’s perspective, the assets are the hardware, software, and data on the computer or network.
A threat model answers the following questions:
| • | Which assets need protection? |
| • | To what threats are the assets vulnerable? |
| • | How important or likely is each threat? |
| • | How can you mitigate the threats? |
Threat modeling is a critical part of software design because it ensures that security is built into the product, rather than addressed as an afterthought. A good threat model can help find and prevent bugs during the design process, thus eliminating potentially costly patches later.
This paper applies the principles of threat modeling to driver design and provides examples of threats to which a driver might be susceptible. For a more complete description of threat modeling for software design, see Writing Secure Software, by Michael Howard and David LeBlanc, published by Microsoft Press.
Creating a threat model requires a thorough understanding of the driver’s design, the types of threats to which the driver might be exposed, and the consequences of a security attack that exploits a particular threat. After creating the threat model for a driver, you can determine how to mitigate the potential threats.
Threat modeling is most effective when performed in an organized, structured way during driver design, rather than haphazardly during coding. A structured approach increases the likelihood that you will discover vulnerabilities in the design, thereby helping to ensure that the model is comprehensive.
One way to organize a threat modeling effort is to follow these steps:
1. | Create a structured diagram showing data flow through the driver. Include all possible tasks that the driver performs and the source and destination of all input and output from the driver. A formal data flow diagram, or similar structured diagram, can help you to analyze the path of data through your driver and to identify the driver’s external interfaces, boundaries, and interactions. Numerous books about data flow diagrams are available. To find references, search on “data flow diagram” in your favorite Internet search engine. |
2. | Analyze the potential security threats, based on the data flow diagram. |
3. | Assess the threats that you identified in the previous step and determine how to mitigate them. |
A data flow diagram shows in conceptual form the flow of data between the driver and the external entities with which it interacts—typically the operating system, a user process, and the device. A formal data flow diagram uses the following symbols:

Figure 1 shows a sample data flow diagram for a hypothetical kernel-mode Windows Driver Model (WDM) driver. Regardless of the architecture for your particular type of driver, the conceptual model is the same: show all data paths and identify each source of data that enters or exits the driver.

Figure 1. Sample data flow diagram for hypothetical kernel-mode driver.
Note
Figure 1 shows data flowing directly between a user process and the driver, and omits any intermediate drivers. However, in reality, all requests pass through the I/O manager and may traverse one or more higher-level drivers before reaching a particular driver. The figure omits these intermediate steps to emphasize the importance of the original source of the data and the context of the thread that supplied the data. Kernel-mode drivers must validate data that originates in user mode.
Information enters the driver because of requests from the operating system, requests from a user process, or requests (typically interrupts) from the device.
The driver in Figure 1 receives data from the operating system in several types of requests:
| • | Requests to perform administrative tasks for the driver and its device, through calls to DriverEntry, DriverUnload, and AddDevice routines |
| • | Plug and Play requests (IRP_MJ_PNP) |
| • | Power management requests (IRP_MJ_POWER) |
| • | Internal device I/O control requests (IRP_MJ_INTERNAL_DEVICE_CONTROL) |
In response to these requests, data flows from the driver back to the operating system as status information.
The driver in the figure receives data from a user process in the following types of requests:
| • | Create, read, and write requests (IRP_MJ_CREATE, IRP_MJ_READ, or IRP_MJ_WRITE) |
| • | Public device I/O control requests (IRP_MJ_DEVICE_ CONTROL) |
In response to these requests, output data and status information flow from the driver back to the user process.
Finally, the driver receives data from the device because of device I/O operations or user actions (such as opening the tray on a CD drive) that change device status. Likewise, data from the driver flows to the device during I/O operations and changes in device status.
Figure 1 shows driver data flow at a broad conceptual level. Each circle represents a relatively large task and lacks detail. In some cases, a one-level diagram such as the sample is adequate for understanding the data sources and paths. If your driver handles many different types of I/O requests from varying sources, you might need to create one or more additional diagrams that show more detail. For example, the circle labeled “Handle I/O Requests” might be expanded into a separate diagram, similar to Figure 2.

Figure 2. Expanded data flow diagram for I/O requests.
Figure 2 shows separate tasks for each type of I/O request in Figure 1. (For simplicity, data paths to the device have been omitted.)
The external entities and the types of input and output shown in the diagram may vary, depending on the type of device. For example, Windows supplies class drivers for many common device types. A system-supplied class driver works with a vendor-supplied minidriver, which typically is a dynamic link library (DLL) that contains a set of callback routines. User I/O requests are directed to the class driver, which then calls the routines in the minidriver to perform specific tasks. The minidriver typically does not receive the entire I/O request packet as input; instead, each callback routine receives only the data that is required for its specific task.
As you create the data flow diagrams, remember the variety of sources for driver requests. Any code that is run on a user’s computer could generate an I/O request to a driver, from well-known applications such as Microsoft Office to freeware, shareware, and Web scripts of potentially dubious origin. Depending on your specific device, you might also need to consider media codecs or third-party filters that your company ships to support its device. Possible data sources include:
| • | IRP_MJ_XXX requests that the driver handles |
| • | IOCTLs that the driver defines or handles |
| • | APIs that the driver calls |
| • | Callback routines |
| • | Interfaces that the driver exposes |
| • | Files that the driver reads or writes, including those used during installation |
| • | Registry keys that the driver reads or writes |
| • | Installation procedures for the driver |
| • | Update procedures for the driver |
| • | Error messages, property pages, and any other information displayed to the user |
Your model should also cover the driver installation and update procedures. Include all the files, directories, and registry entries that are read or written during driver installation. Consider also the interfaces exposed in device installers, co-installers, and property pages.
Any point at which the driver exchanges data with an external entity is potentially vulnerable to attack.
After you identify the points at which a driver might be vulnerable, you can determine which types of threats could occur at each point. Consider the following types of questions:
| • | What security mechanisms are in place to protect each resource? |
| • | Are all transitions and interfaces properly secured? |
| • | Could improper use of a feature unintentionally compromise security? |
| • | Could malicious use of a feature compromise security? |
| • | Do default settings provide adequate security? |
The STRIDE Approach
The acronym STRIDE describes six categories of threats to software. This acronym is derived from:
| • | Spoofing |
| • | Tampering |
| • | Repudiation |
| • | Information disclosure |
| • | Denial of service |
| • | Elevation of privilege |
Using STRIDE as a guide, you can pose detailed questions about the kinds of attacks that could be targeted at a driver. The goal is to determine the types of attacks that could be possible at each vulnerable point in the driver and then to create a scenario for each possible attack.
Spoofing
Spoofing is using someone else’s credentials to gain access to otherwise inaccessible assets. A process mounts a spoofing attack by passing forged or stolen credentials.
Tampering
Tampering is changing data to mount an attack.
For example, a driver might be susceptible to tampering if the required driver files are not adequately protected by driver signing and access control lists (ACLs). In this situation, a malicious user could alter the files, thus breaching system security.
Repudiation
Repudiation occurs when a user denies performing an action, but the target of the action has no way to prove otherwise.
A driver might be susceptible to a repudiation threat if it does not log actions that could compromise security. For example, a driver for a video device could be susceptible to repudiation if it does not log requests to change characteristics of its device, such as focus, scanned area, frequency of image capture, target location of captured images, and so forth. The resulting images could be corrupted, but system administrators would have no way to determine which user caused the problem.
Information Disclosure
Information disclosure threats are exactly as the name implies: the disclosure of information to a user who does not have permission to see it.
Any driver that passes information to or from a user buffer is susceptible to information disclosure threats. To avoid information disclosure threats, drivers must validate the length of each user buffer and zero-initialize the buffers before writing data.
Denial of Service
Denial-of-service attacks threaten the ability of valid users to access resources. The resources could be disk space, network connections, or a physical device. Attacks that slow performance to unacceptable levels are also considered denial-of-service attacks. A driver that allows a user process to monopolize a system resource unnecessarily could be susceptible to a denial-of-service attack if the resource consumption hinders the ability of other valid users to perform their tasks.
For example, a driver might use a semaphore to protect a data structure while executing at IRQL = PASSIVE_LEVEL. However, the driver must acquire and release the semaphore within a KeEnterCriticalRegion/KeLeaveCriticalRegion pair, which disables and re-enables the delivery of asynchronous procedure calls (APCs). If the driver fails to use these routines, an APC could cause the operating system to suspend the thread that holds the semaphore. As a result, other processes (including those created by an administrator) would be unable to gain access to the structure.
Elevation of Privilege
An elevation-of-privilege attack can occur if an unprivileged user gains privileged status.
A kernel-mode driver that passes a user-mode handle to a ZwXxx routine is vulnerable to elevation-of-privilege attacks because ZwXxx routines bypass security checks. Kernel-mode drivers must validate every handle that they receive from user-mode callers.
Elevation-of-privilege attacks can also occur if a kernel-mode driver relies on the RequestorMode value in the IRP header to determine whether an I/O request comes from a kernel-mode or user-mode caller. In IRPs that arrive from the network or the Server service (SRVSVC), the value of RequestorMode is KernelMode, regardless of the origin of the request. To avoid such attacks, drivers must perform access control checks for such requests instead of simply using the value of RequestorMode.
Analysis Techniques
A simple way to organize the analysis is to list the vulnerable areas along with the potential threats and one or more scenarios for each type of threat.
To perform a thorough analysis, you must explore the possibility of threats at every potentially vulnerable point in the driver. At each vulnerable point, determine each category of threat (spoofing, tampering, repudiation, information disclosure, denial of service, and elevation of privilege) that might be possible. Then create one or more attack scenarios for each plausible threat.
For example, consider the data flow for IRP_MJ_DEVICE_CONTROL requests as shown in Figure 2. The following table shows two types of threats that a driver could encounter when processing such requests:
| Vulnerable point | Potential threat (STRIDE) | Scenario |
IRP_MJ_DEVICE_CONTROL requests | Denial of service | User process issues a sequence of IOCTLs that causes the device to fail. |
Elevation of privilege | User process issues an IOCTL that permits FILE_ANY_ACCESS. |
One threat is often related to another. For example, an attack that exploits an elevation-of-privilege threat can result in information disclosure or denial of service. Furthermore, some types of attacks depend on a sequence of events. A malicious user might start by exploiting an elevation-of-privilege threat. Then, with the added capabilities that come with elevated privilege, the user might find and exploit additional vulnerabilities.
Threat trees and outlines can be useful in modeling such complex scenarios.
A threat tree is a diagram that shows a hierarchy of threats or vulnerabilities; in essence, a threat tree mimics the malicious user’s steps in mounting an attack. The ultimate goal of the attack is at the top of the tree. Each subordinate level shows the steps required to carry out the attack. Figure 3 is a simple threat tree for the denial-of-service scenario in the preceding example.

Figure 3. Simple threat tree.
The threat tree shows the required steps to mount a particular attack and the relationships between the steps.
An outline is an alternative to a threat tree. An outline simply lists in hierarchical order the steps to attack a particular threat. For example:
1.0 Cause device to stop responding.
1.1 Issue IOCTLS in failure sequence.
1.1.1 Determine sequence that causes device to fail.
1.1.2 Get elevated privilege to issue internal IOCTLs.
Either technique can help you to understand which threats are most dangerous and which vulnerabilities in your design are most critical.
Determining how and where a driver might be attacked is not enough. You must then assess these potential threats, determine their relative priorities, and devise a mitigation strategy.
The DREAD Approach
DREAD is an acronym that describes five criteria for assessing threats to software. DREAD stands for:
| • | Damage |
| • | Reproducibility |
| • | Exploitability |
| • | Affected users |
| • | Discoverability |
To prioritize the threats to your driver, rank each threat from 1 to 10 on all 5 of the DREAD assessment criteria, and then add the scores and divide by 5 (the number of criteria). The result is a numeric score between 1 and 10 for each threat. High scores indicate serious threats.
Damage
Assessing the damage that could result from a security attack is obviously a critical part of threat modeling. Damage can include data loss, hardware or media failure, substandard performance, or any similar measure that applies to your device and its operating environment.
Reproducibility
Reproducibility is a measure of how often a specified type of attack will succeed. An easily reproducible threat is more likely to be exploited than a vulnerability that occurs rarely or unpredictable. For example, threats to features that are installed by default, or are used in every potential code path, are highly reproducible.
Exploitability
Exploitability assesses the effort and expertise that are required to mount an attack. A threat that can be attacked by a relatively inexperienced college student is highly exploitable. An attack that requires highly skilled personnel and is expensive to carry out is less exploitable.
In assessing exploitability, consider also the number of potential attackers. A threat that can be exploited by any remote, anonymous user is more exploitable than one that requires an onsite, highly authorized user.
Affected Users
The number of users that could be affected by an attack is another important factor in assessing a threat. An attack that could affect at most one or two users would rate relatively low on this measure. Conversely, a denial-of-service attack that crashes a network server could affect thousands of users and therefore would rate much higher.
Discoverability
Discoverability is the likelihood that a threat will be exploited. Discoverability is difficult to estimate accurately. The safest approach is to assume that any vulnerability will eventually be taken advantage of and, consequently, to rely on the other measures to establish the relative ranking of the threat.
Sample: Assessing Threats
Continuing with the example in “Analysis Techniques,” the following table shows how a designer might assess the hypothetical denial-of-service attack:
| DREAD Criterion | Score | Comments |
Damage | 8 | Disrupts work temporarily, but causes no permanent damage or data loss. |
Reproducibility | 10 | Causes the device to fail every time. |
Exploitability | 7 | Requires a focused effort to determine the command sequence. |
Affected users | 10 | Affects every model of this device on the market. |
Discoverability | 10 | Assumes that every potential threat will be discovered. |
Total: | 9.0 | Mitigating this problem is high priority. |
If possible, your driver design should mitigate against all the threats that your model exposes. However, in some cases, mitigation might not be practical. For example, consider an attack that potentially affects very few users and is unlikely to result in loss of data or system usability. If mitigating such a threat requires several months of additional effort, you might reasonably choose to spend additional time testing the driver instead. Nevertheless, remember that eventually a malicious user is likely to find the vulnerability and mount an attack, and then the driver will require a patch for the problem.
Because driver code is highly specialized, a single checklist cannot apply uniformly to all drivers. The following are general points to consider when creating driver threat models.
Be aware of changes in the operating system and compilers. New releases often contain new features that can help you to prevent or mitigate security threats.
For example, with the release of the Microsoft Windows XP DDK, Microsoft added safe string functions, which replace the standard C/C++ string manipulation functions (strcat, strcpy and so on). The standard C/C++ functions do not enforce buffer sizes, thus allowing applications to write beyond the end of a buffer. The safe string functions prevent this error.
Important: New drivers should use the safe string functions, and older drivers should be modified to use them whenever possible. For more information, see “Safe String Functions” in the Windows DDK documentation and the header file Ntstrsafe.h.
Use driver development tools available in the Windows DDK.
The Microsoft Windows Server 2003 DDK includes Driver Verifier, Call Usage Verifier, PREfast, and Device Path Exerciser, along with other tools to help you to create secure, reliable drivers. These tools can find bugs in driver code and can also find unsafe and insecure coding practices that lead to security breaches.
For more information about testing tools, see the Windows DDK and the WHDC Web site at http://www.microsoft.com/whdc/default.mspx.
Kernel-mode drivers run in the trusted system address space and are, in effect, extensions of the operating system. Kernel-mode drivers must validate all data and addresses that originate with user-mode processes.
Numerous security and reliability issues apply to kernel-mode drivers; this paper cannot possibly list them all. The following are a few of the areas in which kernel-mode drivers can be vulnerable to security threats:
| • | Handling unexpected IOCTLs |
| • | Validating buffer lengths |
| • | Handling IOCTLs that permit FILE_ANY_ACCESS |
| • | Securing device objects |
| • | Securing Registry keys |
| • | Handling user-mode buffers |
| • | Using handles that are passed from user mode to kernel mode |
For information about specific points at which kernel-mode drivers might be vulnerable, see the Windows DDK and the white paper titled Common Driver Reliability Issues, available on the Microsoft Web site at http://www.microsoft.com/whdc/driver/security/drvqa.mspx. All writers of kernel-mode drivers should become familiar with this material.
Most users accept default settings during product installation. Therefore, a default setting that can be exploited by a security attack is both highly reproducible and can affect many users. Whenever possible, make defaults restrictive and allow system administrators to change them if necessary. Do not define nonrestrictive defaults and assume that users or administrators will study your documentation to learn how to tighten them.
During installation, copy driver files to secure locations and set security descriptors if necessary. The system subdirectories of the Windows directory (%windir%) automatically inherit the security settings of their parent directory, which protects system files. Vendors must not override these defaults. Therefore, if your installation procedure copies files only to %windir%\system32\drivers and other subdirectories of the Windows directory, the appropriate security descriptors are in place by default; you do not need to specify a security descriptor in the INF CopyFiles directive.
However, if you install files in a different location, you should set a security descriptor that has access control entries (ACEs) that allow access by the local system and by built-in administrators but deny write access to nonprivileged users. The local system and built-in administrators require write access to install and upgrade devices, drivers, and system service packs. For example:
(A;;GA;;;SY) grants all access to the local system.
(A;;GA;;;BA) grants all access to built-in administrators.
For most drivers, the INF file should specify device characteristics and security settings for device objects. The values in the INF file override the defaults for the security descriptor for the device class.
For WDM drivers, specifying device object security settings in the INF file is the preferred method. Before starting a WDM device stack, the PnP manager propagates the security settings that are specified in the INF file to the security descriptors for the drivers in the stack.
Distribute digitally-signed driver packages only. If the Windows Hardware Quality Labs (WHQL) has a test procedure for your device setup class, apply for a WHQL digital signature for the driver package. If no test procedure exists for the device class, use a Microsoft Authenticode digital signature (Microsoft Windows Server 2003 and later versions only). A digital signature assures your customers that the driver package has not been tampered with.
Enforce tight security on Web sites from which customers can download drivers and driver updates.
If you release third-party drivers with your hardware, ensure that they meet the same standards your company uses internally for security.
For driver developers:
| • | Make threat modeling a required part of driver design. |
| • | Stay current with the latest security news and bulletins. |
| • | Become familiar with the security and reliability issues that apply to your driver and device type. For more information, see the device-specific sections of the Windows DDK. |
| • | Understand which checks the operating system, I/O manager, and any higher-level drivers perform before user requests reach your driver—and which checks they do not perform. |
| • | Use tools from the Windows DDK and the WHDC Web site to test and verify your driver. |
Howard, Michael, and David LeBlanc. Writing Secure Code, Second Edition.
Redmond, WA: Microsoft Press, 2003.
Designed for Microsoft Windows XP Application Specification
http://www.microsoft.com/downloads/details.aspx?FamilyID=209e3d65-f0be-4eef-8602-73bb9bc29d54&DisplayLang=en
Microsoft Hardware and Driver Developer Information
http://www.microsoft.com/whdc/default.mspx
“Common Driver Reliability Problems white paper
Cancel Logic in Windows Drivers white paper
Windows Security Model: What Every Driver Writer Needs to Know white paper
Microsoft Windows Driver Development Kit (DDK)
http://www.microsoft.com/whdc/devtools/ddk/default.mspx
See “Driver Programming Techniques” in “Kernel-Mode Drivers Architecture”
Microsoft Windows Logo Program System and Device Requirements
http://www.microsoft.com/whdc/winlogo/default.mspx