VNX-672: Operation on a file, socket, stream or connection after it was closed
Reports Python and Node.js code that reads, writes, queries or sends on a file, socket, stream, descriptor or database connection after closing or releasing it in the same block, including use of a file after its with-block ends.
| Field | Value |
|---|---|
| Rule ID | VNX-672 |
| Severity | Low |
| SARIF level | note |
| Kind | sast |
| Languages | JavaScript / TypeScript, Python |
| CWE | CWE-672 |
| 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 | expired-resource-use cwe-672 use-after-close |
| Source | internal/sast/rules/vnx-672.rego |
Overview
VNX-672 maps to CWE-672: Operation on a Resource after Expiration or Release. The rule follows a release in straight-line code and reports the first operations on the released handle:
- Python:
X.close()(oros.close(fd)) followed within 15 lines byX.read/readline/write/seek/flush/send/sendall/recv/execute/cursor/commit/fetch*(oros.read/os.writeon the fd), including a cursor obtained from the closed connection; and awith open(...) as f:block followed, after it ends, by such a call onf. - Node.js / TypeScript:
X.end(),X.close(),X.destroy()orX.release()followed byX.write/read/query/execute/run/all/get/exec/prepare/send/push/each, andfs.closeSync(fd)followed byfs.readSync(fd, ...)and friends.
What Gets Flagged
with open(path) as cfg:
first = cfg.readline()
rest = cfg.read() # FLAGGED: the file closed when the block ended
conn.close()
cur.execute("SELECT 1") # FLAGGED: cur = conn.cursor() above
client.release();
await client.query(sql, [id]); // FLAGGED: the pooled client may now belong to someone else
What Is Not Flagged
- A reassignment or re-open of the variable between release and use.
- A
return/raise/throw/break/continue, a newdef/function, anelse/except, or the end of the block holding the release (a close on an error path, a close in another method). f.closedchecks,stream.on('finish', ...)listeners afterend().- HTTP responses (
res.end()), which VNX-666 covers; comments, docstrings and string literals.
Remediation
Release a resource after its last use, or keep the use inside the with block. For pooled connections, release in a finally once the query has completed.
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-672
// nosec vnx-672
Or record an ignore rule: vulnetix ignore add --rule vnx-672 --reason "...". See Suppressing findings.