Skip to content

VNX-460: Improper Cleanup on Thrown Exception

Reports Java code that releases a lock (unlock()) or closes a file, socket or JDBC resource (close()) only on the normal path, with no finally between acquisition and release, so an exception in between leaves it held or open.

Updated 02 Nov 2026Checked against cli@de9b52a
Field Value
Rule ID VNX-460
Severity Medium
SARIF level warning
Kind sast
Languages Java
CWE CWE-460
CAPEC CAPEC-66
ATT&CK T1190
CWSS vector CWSS:1.0/TI:M/AP:RU/AL:S/IC:N/FC:LT/RP:RU/RL:S/AV:L/AS:N/IN:A/SC:A/BI:M/DI:H/EX:M/EC:N/P:C
Tags improper-cleanup cwe-460
Source internal/sast/rules/vnx-460.rego

Overview

VNX-460 maps to CWE-460: Improper Cleanup on Thrown Exception. It reports a x.lock() (including readLock()/writeLock()) followed later in the same block by x.unlock() with no finally in between, and a closeable resource (FileInputStream, FileWriter, Buffered*, RandomAccessFile, Socket, ZipFile, Object*Stream, Scanner, getConnection(), prepareStatement(), Files.newInputStream()…) assigned to a variable and later closed with v.close() in the same block with no finally in between. The lock/try/finally idiom, try-with-resources, release inside a finally block, tryLock branches, a lock released in another method and streams over in-memory buffers are not reported.

Why This Matters

If anything between acquisition and release throws, the release never runs. A lock stays held and every later caller blocks; file descriptors and database connections leak until the pool or process runs out, which is a reliable denial of service.

What Gets Flagged

// FLAGGED: unlock() is skipped if validate() throws
lock.lock();
validate(delta);
value += delta;
lock.unlock();

// FLAGGED: the stream leaks if load() throws
FileInputStream in = new FileInputStream(file);
props.load(in);
in.close();

// NOT FLAGGED
lock.lock();
try {
    value += delta;
} finally {
    lock.unlock();
}

Remediation

  1. Call unlock() in a finally block that immediately follows lock().
  2. Open closeable resources in try-with-resources (try (var in = new FileInputStream(f)) { ... }).
  3. For confirmed false positives, add a // vulnetix-ignore: VNX-460 comment on the line.

References

Suppressing this rule

Put a nosec comment on the line, or on line 1 to cover the whole file. Use the comment marker of the file’s language (#, //, -- or ;):

# nosec vnx-460
// nosec vnx-460

Or record an ignore rule: vulnetix ignore add --rule vnx-460 --reason "...". See Suppressing findings.

Edit this pageSources: cli/internal/sast/rules/vnx-460.rego, cli/internal/sast/docs/vnx-460.md
esc
↑ ↓ move↵ openSearches in your browser. A key like autonomy.max or a code like threshold_required jumps straight to it.