Safeguard
Application Security•

CWE-1176 Inefficient CPU Computation and Denial of Service

Slow algorithms are a performance bug until an attacker controls the input size. Then they become a denial of service. Here is how to spot and bound them.

Safeguard Security Team
3 min read

CWE-1176 covers products that perform CPU computations with algorithms that are less efficient than they could be for what the developer needs. In other words, the work can be done with less effort. On its own that is a quality issue. It turns into a security issue when someone else decides how much work you have to do.

This is a class level entry, so it is broad. It applies to any language and any team that runs code on untrusted input.

How it happens

A developer picks a simple approach that works fine on test data. A nested loop to remove duplicates, a regular expression with heavy backtracking, a parser that reads an entire input before checking its size. Each is fine at small scale.

MITRE's consequence note says the product may run slower in ways users notice, and that if an attacker can influence the amount of computation, for example by triggering worst-case complexity, the performance problem might introduce a vulnerability.

The observed example in the record is CVE-2022-37734. A lexer in a Java based GraphQL server did not enforce a maximum number of tokens early enough, which allowed excessive CPU consumption. The cost was driven by input the attacker supplied.

A small Python illustration of the pattern:

# Slow: quadratic work, and the list size comes from the request
def dedupe(items):
    out = []
    for x in items:
        if x not in out:      # scans the whole list every time
            out.append(x)
    return out

# Better: linear work, with a size cap applied before any processing
MAX_ITEMS = 10_000

def dedupe(items):
    if len(items) > MAX_ITEMS:
        raise ValueError("too many items")
    return list(dict.fromkeys(items))

What an attacker gains

The scope is availability. The record lists reduced performance and denial of service through CPU resource consumption. No data is stolen. The service becomes slow or unavailable for everyone else.

How to find it

The record lists no detection methods, so lean on general practice:

  • Load test endpoints with inputs that grow, and watch whether time grows linearly or much faster.
  • Review code where input size controls loop counts, recursion depth or token counts.
  • Check where limits are applied. A limit that runs after parsing has already lost.

How to fix it

Choose algorithms whose cost grows predictably with input. Enforce limits on size, depth and token count before the expensive work starts. The CVE above is a direct example of a limit applied too late. Set timeouts on request handling so one slow input cannot hold a worker indefinitely.

If the slow code lives in a dependency, a dependency scan tells you which advisories apply to versions you run, and reachability analysis tells you whether your code actually calls the affected function.

Quick check

When does an inefficient algorithm become a vulnerability?

When an attacker can influence how much computation is required, for example by triggering worst-case complexity, so that slowdown becomes denial of service.

Why did the GraphQL example matter?

The token limit was enforced too late, so crafted input could consume excessive CPU before being rejected. Limits belong at the earliest point in processing.

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.