Skip to content

VNX-645: Overly Restrictive Account Lockout Mechanism

Reports login code that locks or disables an account once a failed-attempt counter reaches a threshold, in a file that gives the lock no expiry, and django-axes AXES_COOLOFF_TIME = None. Locks with an expiry and administrator deactivation are not reported.

Updated 02 Nov 2026Checked against cli@de9b52a
Field Value
Rule ID VNX-645
Severity Medium
SARIF level warning
Kind sast
Languages JavaScript / TypeScript, Python
CWE CWE-645
CAPEC CAPEC-66
ATT&CK T1190
CWSS vector CWSS:1.0/TI:M/AP:A/AL:A/IC:N/FC:LT/RP:N/RL:A/AV:I/AS:N/IN:A/SC:A/BI:M/DI:H/EX:M/EC:N/P:C
Tags account-lockout denial-of-service authentication cwe-645
Source internal/sast/rules/vnx-645.rego

Overview

VNX-645 maps to CWE-645: Overly Restrictive Account Lockout Mechanism. It reports a statement that locks or disables an account (user.is_locked = True, user.active = false, { locked: true }) on the line of, or just after, a comparison of a failed-login counter with a threshold, when nothing in the file ever lets the lock expire. It also reports AXES_COOLOFF_TIME = None in django-axes settings.

Why This Matters

A permanent lockout turns the lockout into a denial-of-service. An attacker who knows or guesses usernames sends a few bad passwords for each and locks every account until an administrator intervenes.

What Gets Flagged

if user.failed_attempts >= MAX_ATTEMPTS:
    user.is_locked = True          # no locked_until anywhere

AXES_COOLOFF_TIME = None
if (user.loginAttempts > 5) {
  user.active = false;
}

Not flagged: the same lock with user.locked_until = timezone.now() + timedelta(minutes=15) or user.lockUntil = Date.now() + LOCK_TIME, AXES_COOLOFF_TIME = timedelta(minutes=30), an administrator deactivating a user, and test code.

Remediation

  1. Make the lock expire: store a lock-until time and refuse logins only until then, increasing the delay on repeated lockouts.
  2. Prefer throttling by client (IP address or device) plus CAPTCHA over locking the account itself.
  3. Notify the account owner when a lockout happens.

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

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

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