Safeguard
Application Security•

CWE-404 Improper Resource Shutdown or Release: Causes and Fixes

Resources that are not released, or released wrongly, cause leaks, denial of service and data exposure. CWE-404 explained with real CVEs and fixes in C and Java.

Safeguard Security Team
4 min read

Files, sockets, locks, connections and memory all have a lifecycle. Code that forgets the last step leaves them hanging. CWE-404 is the class for a product that does not release or incorrectly releases a resource before it is made available for re-use.

MITRE says that when a resource is created or allocated, the developer is responsible for releasing it properly and for accounting for every path of expiration or invalidation, such as a set period of time or revocation. It applies in every language and is a parent to many specific weaknesses, including CWE-401 for memory.

How it happens

The common thread is an exit path that skips cleanup: an error branch, an exception, a timeout, a peer that disconnects. The record has real examples:

  • CVE-1999-1127: does not shut down named pipe connections if malformed data is sent.
  • CVE-2001-0830: sockets are not properly closed when an attacker repeatedly connects and disconnects from a server.
  • CVE-2002-1372: a chain where return values of file and socket operations are not checked, allowing consumption of file descriptors.

A Java sketch:

Connection c = pool.getConnection();
PreparedStatement st = c.prepareStatement(sql);
ResultSet rs = st.executeQuery();      // throws on bad input
process(rs);
rs.close(); st.close(); c.close();     // skipped when an exception is thrown

Each failing request keeps a pooled connection. After enough of them the pool is empty and the application stops answering.

What an attacker gains

MITRE lists two impacts:

  • Availability. Most unreleased resource problems are reliability issues, but if an attacker can trigger the leak on purpose, they can deplete the resource and mount a denial of service.
  • Confidentiality. When a resource holding sensitive information is not correctly shut down, the data may be exposed in a later allocation.

The second is easy to miss. A buffer, session object or file handle that is reused without being cleaned can carry one user's data into another user's request.

How to find it

MITRE lists these techniques:

  • Automated dynamic analysis with large test suites and many diverse inputs, such as fuzzing.
  • Manual dynamic analysis: trigger error conditions that are unlikely in normal use, such as running under low memory, with insufficient privileges or permissions, or with resources taken by other processes.
  • Automated static analysis (SAST), which can find some instances by analyzing source code.

Also watch descriptor and connection counts under load. A count that climbs and never falls points to a leak.

How to fix it

MITRE's mitigations, in plain terms:

  1. Prefer a language that avoids the problem or makes it easier to avoid. Garbage collected languages such as Java, Ruby and Lisp release memory for objects that are no longer referenced.
  2. Take responsibility for freeing every resource you allocate, and be consistent about where you free it. Free at all exit points of a function, including error conditions.
  3. Use matching allocation and release functions: malloc with free, new with delete, new[] with delete[].
  4. When releasing a complex object, dispose of all of its member components, not only the object itself.

Garbage collection does not close sockets or files, so use the language's structured cleanup:

try (Connection c = pool.getConnection();
     PreparedStatement st = c.prepareStatement(sql);
     ResultSet rs = st.executeQuery()) {
    process(rs);
}   // all three are closed on every path
with open(path) as f, socket.create_connection((host, port)) as s:
    ...

In C, funnel exits through one cleanup label, as shown for CWE-401. Also check the return values of file and socket calls, so failures do not silently consume descriptors.

Quick check

Does garbage collection solve this weakness? Only for memory. Files, sockets and connections still need explicit release, which try-with-resources or with blocks make automatic.

How can a leak expose data and not just cause a slowdown? A resource that is not shut down cleanly may hold sensitive content that appears in a later allocation.

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.