Safeguard
Application Security•

CWE-385 Covert Timing Channel: When Timing Leaks Secrets

How long an operation takes can reveal what it did. CWE-385 explained with plain examples and the fixes MITRE recommends for removing time variance.

Safeguard Security Team
3 min read

An attacker does not always need your data. Sometimes they only need a stopwatch. CWE-385 covers covert timing channels: ways of conveying information by modulating some aspect of system behavior over time, so a program on the receiving end can observe the behavior and infer protected information.

It matters for cryptographic code, authentication checks, shared hosts and anything where an observer can measure response times.

How it happens

MITRE explains that in some cases, knowing when data is transmitted between parties can itself give a malicious user privileged information. Externally monitoring the timing of operations can reveal sensitive data. A cryptographic operation, for example, can expose its internal state if the time it takes varies with that state.

MITRE gives examples of timing channels: the system's paging rate, the time a certain transaction requires to execute, and the time it takes to gain access to a shared bus. Covert channels are often split into storage channels and timing channels.

A short illustration is a password check that stops at the first wrong character:

def check(secret: str, guess: str) -> bool:
    for a, b in zip(secret, guess):
        if a != b:
            return False      # returns earlier when the first byte is wrong
    return len(secret) == len(guess)

A guess with a correct first character runs slightly longer than one with a wrong first character. Measure enough requests and the secret falls out one character at a time.

What an attacker gains

MITRE lists confidentiality: information exposure, through the ability to read application data. The attacker learns something the system never meant to disclose, such as key material, whether a user exists, or which branch a request took.

How to find it

The record lists no detection methods. Practical checks:

  • Review code that compares secrets, tokens, MACs or hashes, and look for early exits.
  • Measure response time for valid versus invalid inputs on login, reset and lookup endpoints.
  • Look at crypto code paths where branches or table lookups depend on secret values.

How to fix it

MITRE recommends three steps.

  1. Where possible, choose implementation strategies that do not introduce time variances in operations.
  2. Remove information from the attacker by artificially manipulating how long operations take, or when they occur.
  3. Add artificial or random delays so that CPU time consumed is independent of the action the application takes.

For comparisons, use the constant-time function your language provides:

import hmac
ok = hmac.compare_digest(secret, guess)

Delays and noise help, but a constant-time design is the stronger answer when you can get it, since random delay can be averaged out over many samples.

Quick check

Is network jitter enough to hide a timing channel? Not reliably. Attackers can send many requests and average out noise, so the operation itself should not depend on secret data.

Sources

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.