Safeguard
Application Security•

CWE-664 Improper Control of a Resource Through Its Lifetime

Files, memory, locks and objects all have a lifecycle. CWE-664 is the parent of the bugs that happen when code ignores it, from leaks to use after free.

Safeguard Security Team
5 min read

CWE-664 sits near the top of the weakness hierarchy. MITRE calls it a pillar: the product does not maintain, or incorrectly maintains, control over a resource throughout its lifetime of creation, use and release. If you have ever fixed a leaked file handle, a use after free, a double close or an object used before it was ready, you have met a descendant of this idea. It touches every language and technology.

How it happens

Resources have rules for how to create them, use them and destroy them. MITRE gives two principles that apply even without explicit instructions: do not use an object until its creation is complete, and do not use an object after it has been slated for destruction.

Breaking those rules shows up in many forms:

  • A resource is created and never released, so it leaks until the process runs out.
  • A resource is released and then used again.
  • A resource is released twice.
  • A resource is used before it is fully initialized.
  • A resource is exposed to code that should not control it.

Because this is a pillar, most of the specific weaknesses beneath it have their own entries. This page is the map. The neighbors include improper initialization, operation on a resource in the wrong phase of its lifetime, improper locking, exposure of a resource to the wrong sphere and operation on a resource after expiration or release.

A leak in Python looks harmless:

# Vulnerable: if parse() raises, the file is never closed
def load(path):
    f = open(path)
    data = parse(f.read())
    f.close()
    return data

Under repeated failures, handles pile up until the process cannot open anything.

Examples from the record

MITRE links two CVEs to this entry:

  • CVE-2018-1000613: a cryptography API uses unsafe reflection when deserializing a private key.
  • CVE-2019-19911: a chain where a Python library does not limit the resources used to process images that specify a very large number of bands (CWE-1284), leading to excessive memory consumption (CWE-789) or an integer overflow.

The second is a useful reminder that lifetime control includes limits. A resource that can be requested without bound is not under control.

If you maintain software that depends on libraries like these, it helps to know which dependencies you ship and whether a flagged function is called. The free dependency scan runs in your browser with no login, keeps the file on your machine, and covers up to 100 dependencies. Reachability analysis then tells you whether your code actually calls the vulnerable function.

What an attacker gains

MITRE lists the consequence only as "Other", since the impact depends on which part of the lifecycle fails. In practice that can mean exhausting memory or handles to cause denial of service, reading data left in a reused resource, or corrupting state. The more specific entries above list those outcomes in detail.

How to find it

The record lists one detection method: use static analysis tools to check for unreleased resources. Add a few practical checks.

  1. Search for every place a resource is acquired: open, connect, allocate, lock, create.
  2. For each, trace every exit path, including error paths and early returns, and confirm release.
  3. Look for resources stored in long-lived objects or caches that are never evicted.
  4. Check that user-controlled sizes and counts have upper bounds before anything is allocated.
  5. Run under load and watch handle, memory and thread counts over time. They should level off.

How to fix it

MITRE lists no formal mitigations on this pillar. The guidance below follows from its description and the child entries.

  1. Tie release to scope. Use constructs that release automatically: context managers in Python, try with resources in Java, defer in Go, destructors or smart pointers in C++.
  2. Keep one owner for each resource, and make it clear who releases it.
  3. Do not touch a resource after release. Set references to null or invalid where the language allows it.
  4. Complete initialization before publishing a resource to other code.
  5. Cap sizes, counts and time for anything that consumes resources on behalf of untrusted input.
# Safer: the file is closed on every path
def load(path):
    with open(path) as f:
        return parse(f.read())

Quick check

Why is this called a pillar?

Pillars are the most abstract type of weakness. They describe a theme that class, base and variant weaknesses fall under. Here the theme is control of a resource across its whole lifecycle.

Does a size limit count as lifetime control?

Yes. The record's own Python image example is an unbounded resource request. Without limits, an attacker decides how much of your memory gets used.

What is the simplest habit that prevents most leaks?

Release resources through scoped constructs that run on every exit path, not by hand at the end of a function.

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.