VNX-408: Incorrect Behavior Order: Early Amplification
A number taken from the request sets, with no upper bound, how much work the server does: a range()/for/while-loop bound, a string or array repeat/size, Buffer.alloc, or a bcrypt/PBKDF2 cost chosen by the client (Python Flask/Django, Node Express/Koa).
| Field | Value |
|---|---|
| Rule ID | VNX-408 |
| Severity | Medium |
| SARIF level | warning |
| Kind | sast |
| Languages | JavaScript / TypeScript, Python |
| CWE | CWE-408 |
| 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 | early-amplification cwe-408 |
| Source | internal/sast/rules/vnx-408.rego |
Overview
VNX-408 maps to CWE-408: Incorrect Behavior Order: Early Amplification. A number taken from the request sets, with no upper bound, how much work the server does: a range()/for/while-loop bound, a string or array repeat/size, Buffer.alloc, or a bcrypt/PBKDF2 cost chosen by the client. The value is read from the request on the sink line or assigned from it (including destructuring) in the 15 lines above.
Why This Matters
When the client picks the amplification factor, a single small request can make the server loop, allocate or hash for as long as the attacker likes, before any authentication or rate limit gets a chance to refuse it. The CWE’s ordering aspect (expensive work before authentication) cannot be seen line by line, so the rule reports the unbounded factor itself.
What Gets Flagged
pages = int(request.args.get("pages", 1))
for page in range(pages): # FLAGGED
out.append(render_page(page))
iterations = int(request.form["iterations"])
return hashlib.pbkdf2_hmac("sha256", secret, salt, iterations) # FLAGGED
const count = parseInt(req.query.count, 10);
for (let i = 0; i < count; i++) { rows.push(buildRow(i)); } // FLAGGED
res.send('-'.repeat(req.query.width)); // FLAGGED
const hash = await bcrypt.hash(req.body.password, cost); // FLAGGED (cost from req.body)
Not flagged: a value clamped with min()/Math.min or compared with a bound in between, lengths of request data (len(...), .length), constants, test files, comments and strings.
Remediation
- Clamp the client-supplied number (
min(n, MAX)) or reject values above a limit before using it. - Fix hash cost factors server-side; never accept them from the request.
- For confirmed false positives, add a
# vulnetix-ignore: VNX-408comment on the line.
References
- CWE-408: Incorrect Behavior Order: Early Amplification
- OWASP API4:2023 Unrestricted Resource Consumption
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-408
// nosec vnx-408
Or record an ignore rule: vulnetix ignore add --rule vnx-408 --reason "...". See Suppressing findings.