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.
- Search for every place a resource is acquired: open, connect, allocate, lock, create.
- For each, trace every exit path, including error paths and early returns, and confirm release.
- Look for resources stored in long-lived objects or caches that are never evicted.
- Check that user-controlled sizes and counts have upper bounds before anything is allocated.
- 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.
- 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++.
- Keep one owner for each resource, and make it clear who releases it.
- Do not touch a resource after release. Set references to null or invalid where the language allows it.
- Complete initialization before publishing a resource to other code.
- 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.