HIGH jwt misconfigurationactixjwt tokens

Jwt Misconfiguration in Actix with Jwt Tokens

Jwt Misconfiguration in Actix with Jwt Tokens — how this specific combination creates or exposes the vulnerability

JWT misconfiguration in Actix applications often arises when tokens are issued or validated without enforcing strict algorithms, expiration checks, or proper key management. Actix-web is a popular Rust framework for building HTTP services, and it is commonly used with JWT libraries such as jsonwebtoken to handle authorization. When JWT tokens are accepted without validating the algorithm (e.g., accepting none or HS256 when RS256 is expected), or when public keys are not properly pinned, attackers can forge tokens or escalate privileges.

One concrete scenario involves an Actix endpoint that relies on bearer JWT tokens but does not enforce token binding or audience validation. If the middleware decodes tokens without verifying the issuer (iss) or the intended audience (aud), a token issued for one service may be accepted by another service within the same ecosystem. This can lead to horizontal privilege escalation, where one user gains access to another user’s resources. Additionally, if the secret or private key is weak, or if the key is exposed in client-side code, attackers can sign their own tokens and bypass authentication.

Insecure default configurations compound the risk. For example, some Actix integrations may skip revocation checks or fail to validate the nbf (not before) claim, allowing replay attacks. Because JWTs are often stored in cookies or local storage, missing Secure and HttpOnly flags in conjunction with weak token validation can enable cross-site scripting (XSS) driven token theft. The combination of permissive parsing, missing signature verification, and missing contextual checks (such as IP or device binding) means that a compromised token can be used across the API surface until expiration.

middleBrick detects these patterns by correlating OpenAPI/Swagger specifications with runtime behavior. For instance, if the spec declares a security scheme requiring JWT with RS256, but runtime probes show the endpoint also accepts unsigned tokens or HS256, this inconsistency is flagged as a high-severity finding. The scanner checks for missing mandatory claims, weak signing configurations, and missing HTTPS enforcement in authorization headers, highlighting how misconfigured JWT handling can be leveraged in chained attacks such as IDOR or privilege escalation.

Jwt Tokens-Specific Remediation in Actix — concrete code fixes

To remediate JWT misconfiguration in Actix, enforce strict algorithm validation, verify all standard claims, and bind tokens to their intended context. Use the jsonwebtoken crate with explicit key material and avoid default or permissive settings. Below are concrete, secure code examples for Actix middleware and handler implementations.

Secure JWT validation middleware in Actix

Define a middleware or extractor that decodes and validates tokens with algorithm and claim checks:

use actix_web::{dev::ServiceRequest, Error, FromRequest, HttpMessage};
use actix_web_httpauth::extractors::bearer::BearerAuth;
use jsonwebtoken::{decode, Algorithm, DecodingKey, Validation, Header};
use serde::{Deserialize, Serialize};
use std::sync::Arc;

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

struct AuthenticatedUser {
    claims: Claims,
    user_id: String,
}

impl FromRequest for AuthenticatedUser {
    type Error = Error;
    type Future = std::future::Ready>;
    type Config = ();

    fn from_request(req: &actix_web::HttpRequest, _: &mut actix_web::dev::Payload) -> Self::Future {
        let auth = BearerAuth::from_request(req, _).map_err(|_| actix_web::error::ErrorUnauthorized("Invalid auth"))?;
        let token = auth.token();

        // Enforce expected algorithm and required claims
        let mut validation = Validation::new(Algorithm::RS256);
        validation.set_audience(&["my-api.example.com"]);
        validation.set_issuer(&["auth.example.com"]);
        validation.required_spec_claims.insert("exp");
        validation.required_spec_claims.insert("nbf");
        validation.required_spec_claims.insert("iss");
        validation.required_spec_claims.insert("aud");

        let key = DecodingKey::from_rsa_pem(include_bytes!("/path/to/public_key.pem")).expect("valid key");
        match decode::(token, &key, &validation) {
            Ok(token_data) => {
                let user = AuthenticatedUser {
                    claims: token_data.claims,
                    user_id: token_data.claims.sub,
                };
                std::future::ready(Ok(user))
            }
            Err(_) => std::future::ready(Err(actix_web::error::ErrorUnauthorized("Invalid token"))),
        }
    }
}

async fn protected_route(user: AuthenticatedUser) -> String {
    format!("Hello user: {}", user.user_id)
}

Ensure that the public key is loaded from a trusted source and that key rotation is supported via JWKS with strict pinning. Avoid using Algorithm::HS256 with shared secrets in distributed systems; prefer RS256 with asymmetric keys.

Token issuance with strict settings

When issuing tokens in an Actix handler, explicitly set algorithm, audience, issuer, and short expiration:

use jsonwebtoken::{encode, Header, EncodingKey};
use serde::{Deserialize, Serialize};

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

fn issue_token(user_id: &str) -> String {
    let claims = Claims {
        sub: user_id.to_string(),
        iss: "auth.example.com".to_string(),
        aud: "my-api.example.com".to_string(),
        exp: (chrono::Utc::now() + chrono::Duration::minutes(15)).timestamp() as usize,
        nbf: chrono::Utc::now().timestamp() as usize,
    };
    encode(
        &Header::new(Algorithm::RS256),
        &claims,
        &EncodingKey::from_rsa_pem(include_bytes!("/path/to/private_key.pem")).expect("valid key"),
    ).expect("valid encoding")
}

Always transmit JWTs over HTTPS, set short expirations, and store tokens in HttpOnly, Secure cookies when used in browsers. Validate tokens on every protected route and reject tokens with missing or mismatched claims.

Related CWEs: authentication

CWE IDNameSeverity
CWE-287Improper Authentication CRITICAL
CWE-306Missing Authentication for Critical Function CRITICAL
CWE-307Brute Force HIGH
CWE-308Single-Factor Authentication MEDIUM
CWE-309Use of Password System for Primary Authentication MEDIUM
CWE-347Improper Verification of Cryptographic Signature HIGH
CWE-384Session Fixation HIGH
CWE-521Weak Password Requirements MEDIUM
CWE-613Insufficient Session Expiration MEDIUM
CWE-640Weak Password Recovery HIGH

Frequently Asked Questions

What makes JWT tokens risky in Actix APIs if not validated properly?
If Actix endpoints accept JWT tokens without enforcing algorithm constraints, claim validation, and signature checks, attackers can forge tokens, escalate privileges, or bypass authentication.
How does middleBrick assess JWT token security in Actix APIs?
middleBrick correlates the OpenAPI specification (e.g., securitySchemes with JWT) with runtime behavior to detect missing algorithm enforcement, missing audience/issuer validation, and weak key usage, producing findings with severity and remediation guidance.