Skip to content

auth.rust.jwt.disable-signature-validation

Validation::insecure_disable_signature_validation() turns off JWT

OAuthLint idAUTH-RUST-JWT-001
SeverityERROR
LLM prevalenceMEDIUM
CWECWE-347
OWASPAPI2:2023
Languagesrust
Technologiesjsonwebtoken

Why this matters

Validation::insecure_disable_signature_validation() turns off JWT signature verification. Once disabled, decode accepts any token — including ones forged or tampered with by an attacker — because the cryptographic signature is never checked. For OAuth/OIDC this lets an attacker mint arbitrary access tokens and identities.

Never disable signature validation. Build the validator with the expected algorithm, e.g. Validation::new(Algorithm::HS256) (or the RS/ES algorithm your issuer uses), and verify the token through decode::<Claims>(token, &key, &validation).

❌ Vulnerable

rust
use jsonwebtoken::{decode, Algorithm, DecodingKey, Validation};
use serde::Deserialize;

#[derive(Debug, Deserialize)]
struct Claims {
    sub: String,
    exp: usize,
}

fn decode_unverified(token: &str, key: &DecodingKey) -> Claims {
    let mut validation = Validation::new(Algorithm::HS256);
    // ruleid: auth.rust.jwt.disable-signature-validation
    validation.insecure_disable_signature_validation();
    decode::<Claims>(token, key, &validation).unwrap().claims
}

fn decode_chained(token: &str, key: &DecodingKey) -> Claims {
    let mut validation = Validation::default();
    // ruleid: auth.rust.jwt.disable-signature-validation
    let _ = validation.insecure_disable_signature_validation();
    decode::<Claims>(token, key, &validation).unwrap().claims
}

✅ Safe

rust
use jsonwebtoken::{decode, Algorithm, DecodingKey, Validation};
use serde::Deserialize;

#[derive(Debug, Deserialize)]
struct Claims {
    sub: String,
    exp: usize,
}

// ok: auth.rust.jwt.disable-signature-validation -- expected algorithm, signature verified
fn decode_verified(token: &str, key: &DecodingKey) -> Claims {
    let validation = Validation::new(Algorithm::HS256);
    decode::<Claims>(token, key, &validation).unwrap().claims
}

// ok: auth.rust.jwt.disable-signature-validation -- default validation, signature still checked
fn decode_default(token: &str, key: &DecodingKey) -> Claims {
    let validation = Validation::default();
    decode::<Claims>(token, key, &validation).unwrap().claims
}

Suppressing this rule (when you really must)

ts
// oauthlint-disable-next-line auth.rust.jwt.disable-signature-validation -- <reason>
thisLineWouldOtherwiseTriggerTheRule();

Disable directives are line-scoped by design — wholesale silencing of a rule across the codebase is intentionally not supported, because the next reviewer needs to see exactly which lines opted out.

References

Released under the MIT License · powered by Semgrep