CRITICAL actixjwt none algorithm

Jwt None Algorithm in Actix

Introduction

JSON Web Tokens (JWT) are widely used for authentication in Actix applications. However, a critical vulnerability known as the "none algorithm" can allow attackers to bypass authentication entirely. This occurs when a server accepts a JWT with the header {"alg":"none"}, indicating an unsigned token. In this article, we delve into how this vulnerability specifically manifests in Actix, how to detect it (including with middleBrick), and how to remediate it using Actix's native features and libraries.

The impact is severe: an attacker can forge tokens with arbitrary claims, impersonating any user or gaining administrative privileges. This vulnerability falls under OWASP API Security Top 10: A02 – Broken Authentication and maps to compliance frameworks such as PCI-DSS, SOC2, HIPAA, and GDPR, as shown in the table below.

FrameworkRelevant Control
OWASP API Top 10A02 – Broken Authentication
PCI-DSSRequirement 6.2.4 (code review) and 8.3.3 (access controls)
SOC2CC6.1 (logical access controls)
HIPAA164.312(a)(2)(i) (access control)
GDPRArticle 32 (security of processing)

How Jwt None Algorithm Manifests in Actix

In Actix, developers commonly use crates like jsonwebtoken or middleware such as actix-web-httpauth to handle JWT authentication. The vulnerability arises when the JWT validation logic is configured to accept the none algorithm, either explicitly or by using a library that defaults to allowing it. While the jsonwebtoken crate does not allow none by default, a developer might mistakenly add it to the list of allowed algorithms, creating an opening for attack.

Consider the following vulnerable Actix route that uses jsonwebtoken:

use actix_web::{web, HttpResponse, Responder};
use jsonwebtoken::{decode, DecodingKey, Validation, Algorithm};

#[derive(serde::Deserialize)]
struct Claims {
    sub: String,
    name: String,
}

async fn get_secret_data(token: web::Json<String>) -> impl Responder {
    let secret = "my_secret";
    let mut validation = Validation::new(Algorithm::HS256);
    // VULNERABLE: Adding the None algorithm allows unsigned tokens
    validation.algorithms.push(Algorithm::None);
    
    match decode::<Claims>(&token, &DecodingKey::from_secret(secret), &validation) {
        Ok(_) => HttpResponse::Ok().body("Secret data"),
        Err(_) => HttpResponse::Unauthorized().body("Invalid token"),
    }
}

In this code, validation.algorithms includes Algorithm::None. When a JWT with header {"alg":"none"} and an empty signature is presented, the decode function will accept it without verifying any signature. An attacker can then craft a token with arbitrary claims, such as {"sub":"admin","role":"superuser"}, and gain unauthorized access.

Similarly, if using actix-web-httpauth with a custom validator that does not restrict algorithms, the same issue can occur. The attack pattern is consistent: the attacker sends a token with alg:none and no signature. If the server accepts it, the authentication mechanism is completely bypassed.

This vulnerability is often overlooked because it requires a specific configuration error. However, it is a well‑known issue (e.g., referenced in CVE‑2018‑1000531 for other languages) and is trivial to exploit. Actix developers must ensure that their JWT validation strictly disallows the none algorithm.

Actix-Specific Detection

Detecting the JWT none algorithm vulnerability involves testing whether the Actix application accepts a token with alg:none. This can be done manually by crafting a malicious JWT and sending it to a protected endpoint. For example, using the jwt CLI tool:

jwt encode --alg none --payload '{"sub":"1234567890","name":"Test"}'

This produces a token like eyJhbGciOiJub25lIn0.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IlRlc3QifQ.. Then, call a protected endpoint:

curl -H "Authorization: Bearer eyJhbGciOiJub25lIn0.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IlRlc3QifQ." http://localhost:8080/protected

If the response is 200 OK instead of 401 Unauthorized, the vulnerability exists.

Automated scanning with middleBrick streamlines this detection. middleBrick's security scan includes an Authentication check that actively probes for the JWT none algorithm issue. When you submit an API URL, middleBrick discovers endpoints that require authentication and sends a crafted alg:none token to each. If any endpoint accepts it, middleBrick reports a critical finding in the Authentication category, with a description of the vulnerability, its severity, and remediation steps.

You can scan your Actix API using the middleBrick web dashboard, CLI, or GitHub Action. For instance, with the CLI:

middlebrick scan https://api.your-actix-app.com

The report will show a per‑category breakdown. If the JWT none algorithm vulnerability is found, it will appear under Authentication with a high severity rating. middleBrick also maps the finding to compliance frameworks (OWASP API Top 10, PCI‑DSS, etc.) and provides specific code‑level remediation guidance tailored to your stack, including Actix examples.

By integrating middleBrick into your CI/CD pipeline via the GitHub Action, you can automatically fail builds if the security score drops below a threshold, preventing vulnerable code from reaching production.

Actix-Specific Remediation

To fix the JWT none algorithm vulnerability in an Actix application, you must configure your JWT validator to reject tokens with alg:none and explicitly specify the allowed algorithms. The key is to ensure that the algorithms list in the validation settings does not include Algorithm::None and that you only include the algorithms you intend to use (e.g., HS256).

Here is a secure example using the jsonwebtoken crate in an Actix route:

use actix_web::{web, HttpResponse, Responder};
use jsonwebtoken::{decode, DecodingKey, Validation, Algorithm};

#[derive(serde::Deserialize)]
struct Claims {
    sub: String,
    name: String,
}

async fn get_secret_data(token: web::Json<String>) -> impl Responder {
    let secret = "my_secret";
    let mut validation = Validation::new(Algorithm::HS256);
    // Secure: explicitly set allowed algorithms to only HS256
    validation.algorithms = vec![Algorithm::HS256];
    
    match decode::<Claims>(&token, &DecodingKey::from_secret(secret), &validation) {
        Ok(_) => HttpResponse::Ok().body("Secret data"),
        Err(_) => HttpResponse::Unauthorized().body("Invalid token"),
    }
}

Note that we set validation.algorithms to a vector containing only Algorithm::HS256. This ensures that any token with an algorithm other than HS256 (including none) will be rejected by the decode function.

If you are using the actix-web-httpauth middleware, configure it with a validator that uses a strict Validation as above. For example:

use actix_web_httpauth::bearer::BearerAuth;
use actix_web::{HttpRequest, HttpResponse, Error};
use jsonwebtoken::{decode, DecodingKey, Validation, Algorithm};

#[derive(serde::Deserialize)]
struct Claims {
    sub: String,
    name: String,
}

fn bearer_validator(req: &HttpRequest, credentials: BearerAuth) -> Result<HttpRequest, Error> {
    let token = credentials.token();
    let secret = "my_secret";
    let mut validation = Validation::new(Algorithm::HS256);
    validation.algorithms = vec![Algorithm::HS256]; // Only allow HS256
    
    match decode::<Claims>(token, &DecodingKey::from_secret(secret), &validation) {
        Ok(_) => Ok(req.clone()),
        Err(_) => Err(actix_web_httpauth::error::ErrorUnauthorized("Invalid token")),
    }
}

// In your App configuration:
App::new()
    .service(
        web::scope("/api")
            .route("/protected", web::get().to(get_secret_data))
            .wrap(BearerAuth::new(bearer_validator))
    )

Additionally, keep your dependencies updated to benefit from any security patches. After applying the fix, re‑scan your API with middleBrick to confirm that the issue is resolved. The Authentication score should increase, and the finding should no longer appear in the report. Regular scanning, especially with middleBrick's continuous monitoring (available in the Pro plan), helps maintain a strong security posture over time.

Conclusion

The JWT none algorithm vulnerability is a critical authentication bypass that can be introduced in Actix applications through a simple configuration error. By understanding the attack pattern and implementing strict algorithm validation, you can effectively mitigate this risk. middleBrick provides an efficient way to detect such issues with its 5–15 second scans, and its integration options (CLI, GitHub Action, MCP Server) make it easy to incorporate security checks into your development workflow. Remember, proactive scanning is key: catch vulnerabilities before they reach production.

Frequently Asked Questions

What is the JWT none algorithm vulnerability?
It is a security flaw where a JWT with the header {"alg":"none"} is accepted by the server, allowing an attacker to forge tokens without a signature. This leads to complete authentication bypass, as the server trusts the unsigned token.
How does middleBrick detect the JWT none algorithm vulnerability in my Actix API?
middleBrick's scan includes an active test for this issue. It sends a JWT with "alg":"none" to each protected endpoint discovered. If the endpoint returns a successful response (e.g., 200 OK), middleBrick flags it as a critical finding in the Authentication category, with detailed remediation guidance.