Skip to content

VNX-681: Incorrect Conversion between Numeric Types

Detects lengths, sizes and file offsets narrowed to a type too small to hold them: C/C++ 8- and 16-bit variables or casts from strlen, read or ftell, int from ftell/lseek, and Java int/short casts of long sizes and times.

Updated 02 Nov 2026Checked against cli@de9b52a
Field Value
Rule ID VNX-681
Severity Medium
SARIF level warning
Kind sast
Languages C, C++, Java
CWE CWE-681
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 numeric-truncation cwe-681
Source internal/sast/rules/vnx-681.rego

Overview

VNX-681 maps to CWE-681: Incorrect Conversion between Numeric Types. A length stored in a uint16_t, or a file size cast to int, silently wraps once the value is large enough. The truncated number then sizes a copy, an allocation or a seek, and the code works on test data and fails on the large input an attacker supplies.

What Gets Flagged

uint16_t name_len = strlen(name);        // FLAGGED: 8/16-bit from a length
out[2] = (uint8_t)strlen(name);          // FLAGGED: narrowing cast
int size = ftell(fp);                    // FLAGGED: file offset into int
pos = (int)ftello(fp);                   // FLAGGED

char c;
while ((c = fgetc(fp)) != EOF) { ... }   // FLAGGED: EOF test after narrowing to char
byte[] buf = new byte[(int) uploadFile.length()];   // FLAGGED
int size = (int) Files.size(p);                     // FLAGGED
int len = (int) conn.getContentLengthLong();        // FLAGGED
short id = (short) System.currentTimeMillis();      // FLAGGED

C and C++: variables declared as char, short, uint8_t, uint16_t, BYTE, WORD, USHORT and similar, initialised from or cast from strlen, wcslen, strnlen, ftell, ftello, lseek, read, recv, recvfrom, fread or C++ .size()/.length(); and int/unsigned int from ftell/ftello/lseek. Java: casts to int, short, byte or char of Files.size(), getContentLengthLong(), getSize(), getCompressedSize(), length() on a file, size()/position() on a channel, System.currentTimeMillis() and System.nanoTime().

What Is Not Flagged

  • int len = strlen(s) and the (int)strlen(s) idiom for a printf precision.
  • Conversions to size_t, long, off_t, uint32_t and wider.
  • Math.toIntExact(...), and casts of int-valued size()/length() calls on collections and strings.
  • Comments and string literals.

Remediation

Keep sizes in size_t/off_t (C) or long (Java). Where a narrower type is required by a format or protocol, check the range first and fail on overflow: if (n > UINT16_MAX) return -1; or Math.toIntExact(file.length()).

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-681
// nosec vnx-681

Or record an ignore rule: vulnetix ignore add --rule vnx-681 --reason "...". See Suppressing findings.

Edit this pageSources: cli/internal/sast/rules/vnx-681.rego, cli/internal/sast/docs/vnx-681.md
esc
↑ ↓ move↵ openSearches in your browser. A key like autonomy.max or a code like threshold_required jumps straight to it.