VNX-772: Missing Release of Resource after Effective Lifetime
Reports Java methods that acquire a socket, file stream, JDBC connection or Files stream into a local variable outside try-with-resources and never close, return or hand it off, and file streams created inline for a consumer that does not close them.
| Field | Value |
|---|---|
| Rule ID | VNX-772 |
| Severity | Low |
| SARIF level | note |
| Kind | sast |
| Languages | Java |
| CWE | CWE-772 |
| CAPEC | CAPEC-66 |
| ATT&CK | T1190 |
| CWSS vector | CWSS:1.0/TI:L/AP:RU/AL:S/IC:N/FC:LT/RP:RU/RL:S/AV:L/AS:N/IN:A/SC:A/BI:L/DI:H/EX:L/EC:N/P:L |
| Tags | resource-release cwe-772 |
| Source | internal/sast/rules/vnx-772.rego |
Overview
VNX-772 maps to CWE-772: Missing Release of Resource after Effective Lifetime. It reports a Java method that acquires an operating-system resource into a local variable and never releases it:
Socket,DatagramSocket,ServerSocket,FileInputStream,FileOutputStream,FileReader,FileWriter,RandomAccessFile,ZipFile,JarFile;- a reader, writer,
Scanneror object stream constructed directly around a new file stream; - a JDBC
ConnectionfromDriverManageror aDataSource; - a stream from
Files.lines,list,walk,find,newInputStream,newOutputStream,newBufferedReader,newBufferedWriter.
It is reported when the declaration is not in a try-with-resources header and the rest of the method has no close() of the variable, no close helper call with it, no return of it, no assignment of it elsewhere and no hand-off as a call argument. A file stream created inline and passed straight to a consumer that does not close it (props.load(new FileInputStream(p)), new Scanner(new File(p)).next()) is reported too.
Not reported: try-with-resources (single- or multi-line headers), close in finally, resources returned to the caller, stored in a field or handed to another object, a ServerSocket serving an accept() loop, in-memory streams (ByteArrayInputStream, StringReader, Scanner(System.in)), comments, string literals and test sources.
Why This Matters
A leaked descriptor or connection stays open until the garbage collector finalises it, if it ever does. Under load the process runs out of file descriptors or the pool runs out of connections, and every later request fails.
What Gets Flagged
Socket socket = new Socket(host, port); // flagged
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
return in.readLine();
props.load(new FileInputStream(path)); // flagged
Not flagged:
try (FileInputStream in = new FileInputStream(path)) {
return in.readAllBytes();
}
Remediation
Declare the resource in a try-with-resources header. Where ownership leaves the method, return it or hand it to the object that will close it.
References
- CWE-772: Missing Release of Resource after Effective Lifetime
- SEI CERT FIO04-J: Release resources when they are no longer needed
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-772
// nosec vnx-772
Or record an ignore rule: vulnetix ignore add --rule vnx-772 --reason "...". See Suppressing findings.