Skip to content

VNX-305: Authentication Bypass by Primary Weakness

An auth middleware, decorator, permission class or servlet filter that lets a request through because a token, API key or Authorization header is present, without verifying it.

Updated 02 Nov 2026Checked against cli@de9b52a
Field Value
Rule ID VNX-305
Severity High
SARIF level error
Kind sast
Languages Java, JavaScript / TypeScript, Python
CWE CWE-305
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 auth-bypass cwe-305
Source internal/sast/rules/vnx-305.rego

Overview

VNX-305 maps to CWE-305: Authentication Bypass by Primary Weakness. It reports an authentication check that only tests whether a credential exists. A Node/Express middleware, a Python decorator, view or Django REST Framework permission, or a Java servlet filter or Spring interceptor reads a token, API key, Authorization header or session cookie from the request and then grants access (next(), return f(*args, **kwargs), call_next, chain.doFilter(...), or return True/true from an auth or permission method) when the value is merely non-empty, or as the very next statement after rejecting an empty one.

Not reported: a check whose condition or intervening lines verify, decode, validate, compare or look the credential up; a variable assigned from a verification call; a value held in the server-side session store (req.session.user, session.getAttribute), which the server itself put there at login; client-side route guards such as Angular canActivate; test files and comments. Verification hidden in another function between the read and the grant is not followed.

Why This Matters

The authentication scheme may be sound (signed JWTs, opaque API keys), but if the gate only checks that a header is present, any value authenticates. An attacker sends Authorization: Bearer x and reaches every protected route.

What Gets Flagged

// FLAGGED
const token = req.headers.authorization?.split(' ')[1];
if (token) return next();

if (!sessionToken) { return res.status(401).send('login required'); }
next();
# FLAGGED
token = request.headers.get("Authorization", "").replace("Bearer ", "")
if token:
    return f(*args, **kwargs)

# FLAGGED: a DRF permission that returns the presence test
def has_permission(self, request, view):
    return bool(request.headers.get("Authorization"))
// FLAGGED
String authToken = request.getHeader("Authorization");
if (authToken != null && authToken.startsWith("Bearer ")) {
    chain.doFilter(req, res);

Not flagged: req.user = jwt.verify(token, secret); next();, if token and ApiToken.query.filter_by(value=token).first():, if (req.session.user) next();.

Remediation

  1. Verify the credential before granting access: check a JWT’s signature, issuer, audience and expiry, or look an API key up in a store and compare it in constant time.
  2. Attach the verified identity to the request (req.user, g.user) and authorise from that, never from the raw header.
  3. Fail closed: any error during verification must reject the request.

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

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

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