Skip to content

VNX-287: Improper Authentication: check that always succeeds

Detects an authentication routine stubbed to accept everyone: an authenticate/verify-password/verify-token function whose first statement is return true, an auth middleware that only calls next(), or a login_required decorator that returns the view unchanged.

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

Overview

VNX-287 maps to CWE-287: Improper Authentication. A placeholder written during development (“SSO will replace this”, “bcrypt is slow in dev”) is shipped, and the function every login or request goes through accepts anything.

The rule reports, in production code (test and fixture paths are skipped):

  • a function or method named for an authentication decision (authenticate*, check/verify/validate + password, credentials, login, token, jwt, api_key, signature, otp/mfa, session; Java PasswordEncoder.matches) whose first statement is return True/return true, including a one-line Java/JS body and an arrow function whose body is true;
  • an Express-style authentication middleware (requireAuth, ensureAuthenticated, isLoggedIn, checkJwt, …) taking next whose first statement is next();
  • a Python login_required/requires_auth decorator that returns the wrapped view unchanged.

What Gets Flagged

class PartnerBackend(BaseBackend):
    def authenticate(self, request, username=None, password=None):
        return True          # FLAGGED

def login_required(view):
    return view              # FLAGGED
@Override
public boolean matches(CharSequence rawPassword, String encodedPassword) { return true; }  // FLAGGED
const ensureAuthenticated = (req, res, next) => next();   // FLAGGED

What Is Not Flagged

  • Routines whose first statement is a check, a lookup or a returned verification (return bcrypt.compare(...)).
  • User-model flags (is_authenticated, is_active properties) and authorisation predicates (has_permission, supports, isEnabled).
  • Middleware not named for authentication, test and fixture code, comments and string literals.

Remediation

Implement the real check, or fail closed until it exists:

def authenticate(self, request, username=None, password=None):
    user = User.objects.filter(username=username).first()
    if user and user.check_password(password):
        return user
    return None

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

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

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