HIGH CWE-367 Authentication & Authorization

CWE-367 in APIs

CWE ID
CWE-367
Category
Input Validation
Severity
HIGH
Short Name
TOCTOU

What is CWE-367?

CWE-367, Time-of-check Time-of-use (TOCTOU) Race Condition, is a critical software weakness where a system performs a check on a resource, then uses that resource, but the resource changes between the check and the use. This creates a race condition window where an attacker can manipulate the resource state to bypass security controls or cause unexpected behavior.

The weakness occurs in this pattern: the system checks a condition (time-of-check), then later uses the resource based on that check (time-of-use). If the resource changes during the interval between these operations, the system acts on stale or incorrect information. Attackers exploit this by timing their actions to occur during this vulnerable window.

Common examples include checking file permissions before opening a file, verifying user privileges before performing an action, or validating input before processing it. If the resource changes after the check but before the use, the system may grant unauthorized access or perform unintended operations.

CWE-367 in API Contexts

APIs are particularly vulnerable to TOCTOU race conditions due to their stateless nature and concurrent request handling. In API contexts, CWE-367 manifests in several critical ways:

  • Authorization checks: An API verifies a user has permission to access a resource, then performs the operation. Between the check and the operation, the user's permissions could change, or the resource ownership could transfer.
  • Database transactions: An API checks if sufficient funds exist for a transaction, then attempts the transfer. During the gap, the account balance could be modified by another concurrent operation.
  • File operations: An API validates a file path is safe before accessing it, but the file is replaced or moved before the actual read/write operation.
  • Rate limiting: An API checks if a user is below their rate limit, then processes the request. Between the check and processing, the user could exceed their limit through another concurrent request.

RESTful APIs are especially susceptible because they often separate authorization checks from resource operations across different middleware layers or service calls. GraphQL APIs face similar risks when resolvers perform separate validation and execution steps.

Detection

Detecting CWE-367 requires both static analysis and dynamic testing approaches. For manual detection, look for patterns where code performs a check operation, then later performs a use operation on the same resource without proper synchronization.

middleBrick's API security scanner includes specific TOCTOU detection capabilities. The scanner analyzes API endpoints for race condition vulnerabilities by examining:

  • Authorization flow analysis: Identifying endpoints where permission checks precede resource operations without atomic transactions
  • State validation patterns: Detecting separate validation and execution phases that could be exploited
  • Concurrency analysis: Testing endpoints with rapid parallel requests to identify race condition windows
  • Database operation sequencing: Examining SQL queries and ORM operations for non-atomic check-then-use patterns

The middleBrick CLI tool can scan your API endpoints with the command middlebrick scan https://api.example.com/users, which tests for TOCTOU vulnerabilities among other security issues. The scanner runs 12 parallel security checks and provides a risk score with specific findings about race condition vulnerabilities.

For comprehensive testing, use middleBrick's GitHub Action in your CI/CD pipeline. This continuously scans your API endpoints and can fail builds if TOCTOU vulnerabilities are detected, ensuring these issues are caught before deployment.

Remediation

Fixing CWE-367 requires eliminating the time gap between check and use operations. The most effective approach is making the check and use atomic through proper synchronization mechanisms.

Database-level atomicity: Use database transactions with appropriate isolation levels. Instead of checking balance then transferring, use a single atomic UPDATE statement that only succeeds if sufficient funds exist:

UPDATE accounts SET balance = balance - :amount WHERE account_id = :id AND balance >= :amount

This single statement both checks the condition and performs the operation atomically, eliminating the race condition window.

Optimistic locking: Include version numbers or timestamps in your data model. When updating a resource, verify the version hasn't changed since you last read it:

SELECT * FROM users WHERE id = ? FOR UPDATE;

The FOR UPDATE clause locks the row, preventing other transactions from modifying it until your transaction completes.

Authorization middleware: Move authorization checks as close as possible to the actual operation, ideally within the same transaction or atomic operation. Avoid separate middleware layers that perform checks before the main handler executes.

Idempotent operations: Design API operations to be idempotent so that even if race conditions occur, repeated operations have predictable outcomes. Include unique identifiers for operations that can detect and prevent duplicate processing.

Rate limiting implementation: Use atomic increment operations with conditional logic rather than separate check and increment steps. Redis operations like INCR with expiration can handle rate limiting atomically.

Filesystem operations: When working with files, use atomic operations like rename() instead of separate check and move operations. On Unix systems, use file descriptors rather than paths when possible to avoid TOCTOU between path resolution and file access.

Here's a Node.js example of proper atomic authorization:

async function deleteResource(req, res) {  const { resourceId } = req.params;  const userId = req.user.id;  
  try {    // Single atomic operation: check ownership AND delete    const result = await db.query(      'DELETE FROM resources WHERE id = $1 AND owner_id = $2',      [resourceId, userId]    );    
    if (result.rowCount === 0) {      return res.status(404).json({ error: 'Resource not found or unauthorized' });    }    
    res.json({ success: true });  } catch (error) {    res.status(500).json({ error: 'Internal server error' });  }}

This approach eliminates the TOCTOU window by combining the authorization check and the delete operation into a single atomic database query.

Frequently Asked Questions

How can I test my API for TOCTOU race conditions?
Use middleBrick's API security scanner which includes specific TOCTOU detection capabilities. The scanner analyzes your API endpoints for race condition vulnerabilities by examining authorization flows, state validation patterns, and concurrency issues. You can run it from the CLI with middlebrick scan or integrate it into your CI/CD pipeline using the GitHub Action to catch these vulnerabilities before deployment.
What's the difference between TOCTOU and other race conditions?
TOCTOU specifically refers to the pattern where a system checks a resource state, then later uses that resource, with the resource changing between these operations. Other race conditions might involve concurrent access to shared resources without proper synchronization, but TOCTOU is characterized by the explicit check-then-use sequence that creates the vulnerability window.