VNX-222: Truncation of Security-relevant Information
Detects C and C++ bounded copies and formats (snprintf, strncpy, strlcpy, strncat, ...) whose truncation is never checked, when the truncated buffer is then used to open, remove or execute a file, run a command, contact a host, compare a name or write the audit log.
| Field | Value |
|---|---|
| Rule ID | VNX-222 |
| Severity | Medium |
| SARIF level | warning |
| Kind | sast |
| Languages | C, C++ |
| CWE | CWE-222 |
| 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 | truncation buffer path cwe-222 |
| Source | internal/sast/rules/vnx-222.rego |
Overview
VNX-222 maps to CWE-222: Truncation of Security-relevant Information. Bounded string functions prevent overflow by cutting the result short, and they report that they did so only through a return value that is easy to ignore. When the truncated buffer then decides something, the decision is made on the wrong value: "%s/%s.txt" loses its extension and opens a different file, a truncated user name can equal a privileged one, a truncated command runs without its trailing options, and a truncated log line loses the part an investigator needed.
The rule reports a statement that discards the result of snprintf, vsnprintf, _snprintf, sprintf_s, strncpy, strncpy_s, strcpy_s, strlcpy, strncat, strlcat or g_strlcpy into an array declared in the same function, when within twelve lines the buffer is passed to:
- file calls:
open,openat,fopen,creat,access,stat,realpath,unlink,remove,rename,chmod,chown,mkdir,rmdir,chdir,chroot,truncate,std::ifstream/ofstream/fstream,.open(); - process and library loading: the
execfamily,system,popen,dlopen,LoadLibrary; - network:
connect,bind,getaddrinfo,gethostbyname,SSL_set_tlsext_host_name,X509_check_host; - decisions and records:
strcmp/strncmp/strcasecmp/memcmp,crypt,setenv/putenv,syslog; - a Unix socket path copied into
addr.sun_pathand then passed tobindorconnect.
A format counts only when it inserts a string (%s) or takes its format from a variable: "%d" into a 256-byte buffer cannot truncate.
What Gets Flagged
char path[256];
snprintf(path, sizeof(path), "%s/%s.txt", base, name); /* FLAGGED */
return open(path, O_RDONLY);
char user[16];
strlcpy(user, login, sizeof(user)); /* FLAGGED */
return strcmp(user, "administrator") == 0;
What Is Not Flagged
- A checked result:
int n = snprintf(...); if (n < 0 || (size_t)n >= sizeof(path)) return -1;orif (strlcpy(...) >= sizeof(user)). - A later comparison against
sizeoforstrlen(buf)before the use, or the source length tested against the buffer size just before the copy:if (strlen(sock_path) >= sizeof(addr.sun_path)) return -1;. - Buffers that are only displayed (
printf,puts, UI calls), integer-only formats, comments, strings and test code.
Remediation
int n = snprintf(path, sizeof(path), "%s/%s.txt", base, name);
if (n < 0 || (size_t)n >= sizeof(path))
return -ENAMETOOLONG;
References
- CWE-222: Truncation of Security-relevant Information
- SEI CERT FIO37-C / STR03-C: Do not inadvertently truncate a string
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-222
// nosec vnx-222
Or record an ignore rule: vulnetix ignore add --rule vnx-222 --reason "...". See Suppressing findings.