VNX-1389: Incorrect Parsing of Numbers with Different Radices
Reports parsers that guess the radix from the text (parseInt without a radix on request data, int(x, 0), strconv.ParseInt(s, 0, n), Integer.decode, strtol(s, end, 0), std::stoi(s, nullptr, 0), scanf %i, inet_aton/inet_addr), so '010' or '0x10' parse to a different value than a check expects.
| Field | Value |
|---|---|
| Rule ID | VNX-1389 |
| Severity | Low |
| SARIF level | note |
| Kind | sast |
| Languages | JavaScript / TypeScript, Python, Go, Java, Kotlin, C, C++ |
| CWE | CWE-1389 |
| 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 | radix-parsing input-validation cwe-1389 |
| Source | internal/sast/rules/vnx-1389.rego |
Overview
VNX-1389 maps to CWE-1389: Incorrect Parsing of Numbers with Different Radices. Several parsing APIs infer the radix from a prefix: a leading 0 means octal, 0x hexadecimal. When the text comes from outside the program, a value that passes a check in one radix means something else in another. The classic case is an IP allow-list bypassed with 0177.0.0.1, which inet_aton reads as 127.0.0.1.
What Gets Flagged
const page = parseInt(req.query.page); // no radix, request data
const raw = req.params.port;
const port = parseInt(raw); // two-line form
mode = int(request.args.get("mode"), 0) # base inferred from prefix
n, err := strconv.ParseUint(s, 0, 32)
int limit = Integer.decode(request.getParameter("limit"));
long port = strtol(port_text, &end, 0);
if (inet_aton(addr_text, &a) == 0) return 0;
int n; sscanf(buf, "%i", &n); // %i guesses the radix too
Not flagged: an explicit radix (parseInt(x, 10), int(x, 16), strtol(s, NULL, 10)), parseInt on values that are not request data (CSS widths, lengths), string-literal arguments, Number(), Integer.parseInt, inet_pton, and wrappers such as malloc_strtoumax.
Remediation
- Pass the radix the input is supposed to be in:
parseInt(value, 10),int(value, 10),strconv.ParseInt(s, 10, 64),Integer.parseInt(s, 10),strtol(s, &end, 10). - Parse IPv4 addresses with
inet_pton(AF_INET, ...)(oripaddress.ip_address/net.ParseIP), which accept dotted decimal only. - Validate the parsed value, not the text, and compare in one canonical form.
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-1389
// nosec vnx-1389
Or record an ignore rule: vulnetix ignore add --rule vnx-1389 --reason "...". See Suppressing findings.