Skip to content

VNX-324: Use of a Key Past its Expiration Date

Reports code that accepts an expired certificate or signed token: swallowed CertificateExpiredException/ExpiredJwtException, jsonwebtoken ignoreExpiration: true, PyJWT verify_exp: False, ruby-jwt verify_expiration: false, OpenSSL verify callbacks that accept X509_V_ERR_CERT_HAS_EXPIRED, and X509_V_FLAG_NO_CHECK_TIME.

Updated 02 Nov 2026Checked against cli@de9b52a
Field Value
Rule ID VNX-324
Severity Medium
SARIF level warning
Kind sast
Languages Java, Kotlin, JavaScript / TypeScript, Python, Ruby, C, C++
CWE CWE-324
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 key-past-expiry cwe-324 jwt certificate
Source internal/sast/rules/vnx-324.rego

Overview

VNX-324 maps to CWE-324: Use of a Key Past its Expiration Date. It reports code that keeps accepting a certificate or a signed token after the expiry date its issuer gave it.

Why This Matters

Expiry bounds how long a leaked key, certificate or token stays useful. Code that ignores it turns a stolen credential into a permanent one, and keeps trusting certificates that were retired precisely because they could no longer be trusted.

What Gets Flagged

// FLAGGED: the expired certificate is swallowed and the handshake continues
} catch (CertificateExpiredException e) {
    // old partner certificates are still in use
}

// FLAGGED: the claims of an expired token are used anyway
} catch (ExpiredJwtException e) {
    return e.getClaims();
}
// FLAGGED
jwt.verify(token, key, { algorithms: ['RS256'], ignoreExpiration: true });
# FLAGGED
jwt.decode(token, key, algorithms=["HS256"], options={"verify_exp": False})
# FLAGGED
JWT.decode(token, secret, true, { algorithm: 'HS256', verify_expiration: false })
/* FLAGGED: the verify callback accepts an expired certificate */
if (err == X509_V_ERR_CERT_HAS_EXPIRED) {
    return 1;
}

What Is Not Flagged

  • A catch block that rethrows, returns false/null, or answers 401/403 (reading e.getClaims() only to log it is fine).
  • ignoreExpiration: false, verify_exp: True, and the names in comments.
  • Test files, where decoding an expired fixture is normal.
  • Go, which VNX-GO-032 covers.
  • Long certificate validity periods, which are a policy choice.

Remediation

  1. Keep expiry checks on. Let checkValidity() and the JWT library reject expired material.
  2. For refresh flows, verify a separate refresh token instead of accepting the expired access token’s claims.
  3. Rotate expired certificates rather than teaching the client to accept them.

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

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

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