v0.14 is out: a mobile auth pack for Swift/iOS and Android, catching insecure token storage, cleartext traffic, and OAuth in embedded WebViews. Read more →
HIGH AI PREVALENCE: MEDIUM auth.rust.jwt.no-expiration-validation

JWT expiration validation is turned off by setting validate_exp: false on the jsonwebtoken Validation.

Why AI tools produce this: AI coding tools produce this regularly, typically when prompted for a shortcut or a quick fix.

Why this matters

With exp checking disabled, decode accepts tokens that have already expired, so a leaked or stolen access token stays usable forever. For OAuth/OIDC this defeats token lifetimes and revocation-by-expiry, letting an attacker replay old tokens.

Leave validate_exp at its default true so expired tokens are rejected. Build the validator with Validation::new(Algorithm::HS256) (or your issuer's algorithm) and do not turn off validate_exp.

VULNERABLE
vulnerable.rs
use jsonwebtoken::{Algorithm, Validation};

fn build_validation_assign() -> Validation {
    let mut validation = Validation::new(Algorithm::HS256);
    // ruleid: auth.rust.jwt.no-expiration-validation
    validation.validate_exp = false;
    validation
}

fn build_validation_assign_default() -> Validation {
    let mut v = Validation::default();
    // ruleid: auth.rust.jwt.no-expiration-validation
    v.validate_exp = false;
    v
}
SAFE
safe.rs
use jsonwebtoken::{Algorithm, Validation};

fn build_validation_default() -> Validation {
    // ok: auth.rust.jwt.no-expiration-validation
    Validation::new(Algorithm::HS256)
}

fn build_validation_literal() -> Validation {
    // ok: auth.rust.jwt.no-expiration-validation
    Validation {
        algorithms: vec![Algorithm::HS256],
        validate_exp: true,
        ..Default::default()
    }
}

fn build_validation_assign() -> Validation {
    let mut validation = Validation::new(Algorithm::HS256);
    // ok: auth.rust.jwt.no-expiration-validation
    validation.validate_exp = true;
    validation
}

Suppressing this rule

If a finding is a genuine false positive, scope the suppression to the exact line and leave a reason, never disable the rule project-wide. Disable directives are line-scoped by design.

// oauthlint-disable-next-line auth.rust.jwt.no-expiration-validation -- <reason>

References

https://docs.rs/jsonwebtoken/latest/jsonwebtoken/struct.Validation.html#structfield.validate_exp ↗https://cwe.mitre.org/data/definitions/613.html ↗