Skip to content

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).

Updated 02 Nov 2026Checked against cli@de9b52a
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

  1. Clamp the client-supplied number (min(n, MAX)) or reject values above a limit before using it.
  2. Fix hash cost factors server-side; never accept them from the request.
  3. For confirmed false positives, add a # vulnetix-ignore: VNX-408 comment on the line.

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

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

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