VNX-252: Unchecked Return Value
Reports Go I/O calls whose error is silently dropped (bare Write/Read/WriteString, io.Copy, os.WriteFile), C allocations and fopen results used without a NULL check, and unchecked setuid/setgid/chroot privilege changes.
| Field | Value |
|---|---|
| Rule ID | VNX-252 |
| Severity | Medium |
| SARIF level | warning |
| Kind | sast |
| Languages | C, C++, Go |
| CWE | CWE-252 |
| 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 | error-handling unchecked cwe-252 |
| Source | internal/sast/rules/vnx-252.rego |
Overview
A call that reports failure only through its return value fails silently when that value is dropped: a short write goes unnoticed, a NULL pointer is dereferenced, or a failed privilege drop leaves the process running privileged. This maps to CWE-252: Unchecked Return Value.
What Gets Flagged
- Go: a bare statement
recv.Write(...),recv.Read(...)orrecv.WriteString(...), or a bareio.Copy,io.CopyN,io.CopyBuffer,io.WriteString,io.ReadFull,io.ReadAtLeast,os.WriteFileorioutil.WriteFilecall. - C/C++:
malloc,calloc,realloc,strdup,strndup,fopen,fdopenortmpfileassigned to a variable that none of the next six code lines tests. - C/C++: a bare
setuid,setgid,seteuid,setegid,setreuid,setregid,setresuid,setresgid,setgroups,initgroupsorchrootstatement.
conn.Write(frame) // flagged
io.Copy(out, src) // flagged
os.WriteFile(path, data, 0o600) // flagged
char *copy = malloc(n + 1); /* flagged: used without a NULL check */
memcpy(copy, name, n);
setuid(uid); /* flagged */
Not flagged in Go: an explicit discard (_ = f.Close(), _, _ = w.Write(b)), a deferred, returned or assigned result, writes to writers that cannot fail (bytes.Buffer, strings.Builder, bufio.Writer, hashes and HMACs, tabwriter) and to an http.ResponseWriter, and test files. Not flagged in C: a test on the same line or in the next lines (== NULL, !p, if (p), assert(p), serverAssert(p)), abort-on-failure wrappers such as xmalloc/zmalloc, a (void) cast, comments and strings.
Remediation
if _, err := conn.Write(frame); err != nil {
return err
}
char *copy = malloc(n + 1);
if (copy == NULL)
return NULL;
if (setuid(uid) != 0)
abort();
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-252
// nosec vnx-252
Or record an ignore rule: vulnetix ignore add --rule vnx-252 --reason "...". See Suppressing findings.