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.
| Framework | Relevant Control |
|---|---|
| OWASP API Top 10 | A02 – Broken Authentication |
| PCI-DSS | Requirement 6.2.4 (code review) and 8.3.3 (access controls) |
| SOC2 | CC6.1 (logical access controls) |
| HIPAA | 164.312(a)(2)(i) (access control) |
| GDPR | Article 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/protectedIf 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.comThe 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.