Temporary files are considered insecurely created when the file existence check is performed separately from the actual file creation. Such a situation can occur when creating temporary files using normal file handling functions or when using dedicated temporary file handling functions that are not atomic.

## Why is this an issue?

Creating temporary files in a non-atomic way introduces race condition issues in the application’s behavior. Indeed, a third party can create a given file between when the application chooses its name and when it creates it.

In such a situation, the application might use a temporary file that it does not entirely control. In particular, this file’s permissions might be different than expected. This can lead to trust boundary issues.

### What is the potential impact?

Attackers with control over a temporary file used by a vulnerable application will be able to modify it in a way that will affect the application’s logic. By changing this file’s Access Control List or other operating system-level properties, they could prevent the file from being deleted or emptied. They may also alter the file’s content before or while the application uses it.

Depending on why and how the affected temporary files are used, the exploitation of a race condition in an application can have various consequences. They can range from sensitive information disclosure to more serious application or hosting infrastructure compromise.

#### Information disclosure

Because attackers can control the permissions set on temporary files and prevent their removal, they can read what the application stores in them. This might be especially critical if this information is sensitive.

For example, an application might use temporary files to store users' session-related information. In such a case, attackers controlling those files can access session-stored information. This might allow them to take over authenticated users' identities and entitlements.

#### Attack surface extension

An application might use temporary files to store technical data for further reuse or as a communication channel between multiple components. In that case, it might consider those files part of the trust boundaries and use their content without additional security validation or sanitation. In such a case, an attacker controlling the file content might use it as an attack vector for further compromise.

For example, an application might store serialized data in temporary files for later use. In such a case, attackers controlling those files' content can change it in a way that will lead to an insecure deserialization exploitation. It might allow them to execute arbitrary code on the application hosting server and take it over.

## How to fix it

### Code examples

The following code example is vulnerable to a race condition attack because it creates a temporary file using an unsafe API function.

#### Noncompliant code example

    Imports System.IO

    Sub Example()
        Dim TempPath = Path.GetTempFileName() 'Noncompliant

        Using Writer As New StreamWriter(TempPath)
            Writer.WriteLine("content")
        End Using
    End Sub

#### Compliant solution

    Imports System.IO

    Sub Example()
        Dim RandomPath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())

        Using FileStream As New FileStream(RandomPath, FileMode.CreateNew, FileAccess.Write, FileShare.None, 4096, FileOptions.DeleteOnClose)
            Using Writer As New StreamWriter(FileStream)
                Writer.WriteLine("content")
            End Using
        End Using
    End Sub

### How does this work?

Applications should create temporary files so that no third party can read or modify their content. It requires that the files' name, location, and permissions are carefully chosen and set. This can be achieved in multiple ways depending on the applications' technology stacks.

#### Strong security controls

Temporary files can be created using unsafe functions and API as long as strong security controls are applied. Non-temporary file-handling functions and APIs can also be used for that purpose.

In general, applications should ensure that attackers can not create a file before them. This turns into the following requirements when creating the files:

- Files should be created in a non-public directory.
- File names should be unique.
- File names should be unpredictable. They should be generated using a cryptographically secure random generator.
- File creation should fail if a target file already exists.

Moreover, when possible, it is recommended that applications destroy temporary files after they have finished using them.

Here the example compliant code uses the `Path.GetTempPath` and `Path.GetRandomFileName` functions to generate a unique random file name. The file is then open with the `FileMode.CreateNew` option that will ensure the creation fails if the file already exists. The `FileShare.None` option will additionally prevent the file from being opened again by any process. To finish, this code ensures the file will get destroyed once the application has finished using it with the `FileOptions.DeleteOnClose` option.

## Resources

### Documentation

- OWASP - Insecure Temporary File

### Standards

- OWASP - Top 10 2021 Category A1 - Broken Access Control
- OWASP - Top 10 2017 Category A9 - Using Components with Known Vulnerabilities
- CWE - CWE-377 - Insecure Temporary File
- CWE - CWE-379 - Creation of Temporary File in Directory with Incorrect Permissions
- STIG Viewer - Application Security and Development: V-222567 - The application must not be vulnerable to race conditions.