VNX-125: Out-of-bounds Read
Reports C/C++ off-by-one loops (i <= the length of the array they read) and char buffers filled to their full size by read()/recv()/fread() and then used as C strings without a terminating NUL.
| Field | Value |
|---|---|
| Rule ID | VNX-125 |
| Severity | High |
| SARIF level | error |
| Kind | sast |
| Languages | C, C++ |
| CWE | CWE-125 |
| CAPEC | CAPEC-66 |
| ATT&CK | T1190 |
| CWSS vector | CWSS:1.0/TI:H/AP:RU/AL:S/IC:N/FC:LT/RP:RU/RL:S/AV:L/AS:N/IN:A/SC:A/BI:H/DI:H/EX:H/EC:N/P:H |
| Tags | oob-read memory cwe-125 |
| Source | internal/sast/rules/vnx-125.rego |
Overview
VNX-125 maps to CWE-125: Out-of-bounds Read. It reports two shapes:
- An off-by-one loop:
for (...; i <= BOUND; ...)whose body readsARR[i], whereBOUNDis the declared length ofARR(declaredARR[BOUND]in the same file) orsizeof(ARR),sizeof(ARR) / sizeof(ARR[0]),ARRAY_SIZE(ARR),countof/_countof/nitems(ARR). Theforline is reported. - A
chararray filled to its full size byread(),recv(),pread()orfread(buf, 1, sizeof(buf), ...), so it holds no terminating NUL, then passed to a string function (strlen,strdup,strcmp,strstr,atoi,puts,printf("%s"),std::string(...)) withoutbuf[n] = '\0'in between.
The previous version reported every strcpy/memcpy call; those are not reads past a buffer by themselves and are no longer reported.
What Gets Flagged
static int scores[MAX_USERS];
for (int i = 0; i <= MAX_USERS; i++) // FLAGGED: reads scores[MAX_USERS]
sum += scores[i];
char buf[256];
ssize_t n = read(fd, buf, sizeof(buf));
size_t len = strlen(buf); // FLAGGED: buf is not terminated
What Is Not Flagged
i < BOUND,i <= BOUND - 1, and loops over a bound unrelated to the indexed array.- Reads sized
sizeof(buf) - 1, and buffers terminated (buf[n] = '\0') before use. - Binary buffers handled with
memcpy.
Remediation
Use < for loop bounds over array lengths. Read at most sizeof(buf) - 1 bytes and terminate the buffer at the returned length before treating it as a string.
References
- CWE-125: Out-of-bounds Read
- SEI CERT STR32-C: Do not pass a non-null-terminated character sequence to a library function that expects 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-125
// nosec vnx-125
Or record an ignore rule: vulnetix ignore add --rule vnx-125 --reason "...". See Suppressing findings.