Jwt Misconfiguration in Actix
How Jwt Misconfiguration Manifests in Actix
Jwt misconfiguration in Actix applications often stems from improper middleware setup, weak secret management, or missing validation steps. The most common manifestation occurs when developers use actix-web's jsonwebtoken crate without proper validation middleware, leading to scenarios where tokens are accepted without verifying their signature or expiration.
A critical Actix-specific issue arises when using the actix-web-httpauth crate with custom extractors. Developers frequently create extractors that parse tokens but fail to validate them against the expected audience or issuer claims. This allows attackers to craft tokens that bypass authorization checks entirely.
Another manifestation involves improper secret key handling. Actix applications often store JWT secrets in configuration files or environment variables without proper rotation policies. When using HS256 algorithms with weak or hardcoded secrets, attackers can easily brute-force or extract the signing key from the application binary.
Time-based attacks become possible when Actix applications don't properly handle clock skew in token validation. An attacker can exploit this by creating tokens with expiration times that fall within the acceptable skew window, potentially extending their access beyond intended limits.
The following Actix code demonstrates a vulnerable implementation:
use actix_web::{web, App, HttpServer, HttpResponse, get, Responder};
use jsonwebtoken::{encode, decode, Header, EncodingKey, DecodingKey, Validation};
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)]
struct Claims {
sub: String,
exp: usize,
// Missing issuer, audience validation
}
#[get("/protected")]
async fn protected() -> impl Responder {
HttpResponse::Ok().body("Access granted")
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
let secret = "weak-secret-key"; // Hardcoded secret
HttpServer::new(move || {
App::new()
.service(protected)
// No JWT middleware - anyone can access /protected
})
.bind("127.0.0.1:8080")?
.run()
.await
}This code allows unauthenticated access to protected endpoints because no middleware validates incoming JWT tokens. An attacker can simply send requests without any token and receive the "Access granted" response.
Actix-Specific Detection
Detecting JWT misconfiguration in Actix applications requires examining both the code structure and runtime behavior. Start by analyzing the middleware chain in your Actix application. A properly configured JWT system should have middleware that intercepts all protected routes and validates tokens before they reach the handler.
Look for missing validation steps in your token processing logic. In Actix, this often manifests as extractors that parse JWT strings but don't verify the signature, expiration, audience, or issuer claims. The jsonwebtoken::decode function should always be called with a Validation struct that specifies expected parameters.
Secret management is another critical detection point. Search your Actix codebase for hardcoded secrets, especially in main.rs or configuration modules. Secrets should never be embedded directly in source code or stored in plain text configuration files committed to version control.
Runtime detection can be performed using middleBrick's API security scanner. When you scan your Actix application's endpoints, middleBrick tests for JWT-related vulnerabilities by attempting to bypass authentication mechanisms and analyzing token validation logic.
middleBrick specifically checks for:
- Missing or weak JWT validation in Actix middleware chains
- Improper secret key handling and storage
- Lack of audience and issuer validation
- Insufficient clock skew handling
- Missing token expiration checks
- Improper error handling that might leak information
The scanner performs active testing by sending crafted requests to your Actix endpoints, attempting to access protected routes without valid tokens, and analyzing the responses for authentication bypass opportunities.
Here's how to scan your Actix API with middleBrick:
# Install middleBrick CLI
npm install -g middlebrick
# Scan your Actix API endpoints
middlebrick scan http://localhost:8080
# Or integrate into your CI/CD pipeline
middlebrick scan --fail-below B --threshold 80 http://localhost:8080The scan results will show specific findings related to JWT configuration, including any missing validation steps, weak secrets, or authentication bypass opportunities detected in your Actix application.
Actix-Specific Remediation
Remediating JWT misconfiguration in Actix applications requires implementing proper middleware, secure secret management, and comprehensive validation. Start by creating a dedicated JWT middleware that intercepts all requests to protected endpoints.
Here's a secure implementation using Actix's middleware system:
use actix_web::{
dev::ServiceRequest, dev::ServiceResponse, HttpMessage,
middleware::Started, middleware::Middleware
};
use jsonwebtoken::{
decode, DecodingKey, Validation, Algorithm
};
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize)]
struct Claims {
sub: String,
exp: usize,
iss: String,
aud: String,
}
pub struct JwtMiddleware {
secret: String,
issuer: String,
audience: String,
allowed_algorithms: Vec<Algorithm>,
}
impl JwtMiddleware {
pub fn new(secret: String, issuer: String, audience: String) -> Self {
Self {
secret,
issuer,
audience,
allowed_algorithms: vec![Algorithm::HS256],
}
}
}
impl actix_web::middleware::Middleware<actix_web::dev::Payload> for JwtMiddleware {
fn start(&self, req: &ServiceRequest) -> actix_web::Result<Started> {
let token = match req.headers().get("Authorization") {
Some(header) => header.to_str().unwrap_or(""),
None => return Err(actix_web::error::ErrorUnauthorized("Missing token")),
};
if !token.starts_with("Bearer ") {
return Err(actix_web::error::ErrorUnauthorized("Invalid token format"));
}
let token = &token[7..];
let validation = Validation {
iss: Some(self.issuer.clone()),
aud: Some(self.audience.clone()),
algorithms: self.allowed_algorithms.clone(),
..Default::default()
};
let _claims = decode::<Claims>(token, &DecodingKey::from_secret(self.secret.as_bytes()), &validation)
.map_err(|_| actix_web::error::ErrorUnauthorized("Invalid token"))?;
Ok(Started::Done)
}
}
// Usage in main function
#[actix_web::main]
async fn main() -> std::io::Result<()> {
let secret = std::env::var("JWT_SECRET").expect("JWT_SECRET must be set");
let issuer = "your-app.com".to_string();
let audience = "your-app-audience".to_string();
HttpServer::new(move || {
App::new()
.wrap(JwtMiddleware::new(secret.clone(), issuer.clone(), audience.clone()))
.service(protected)
})
.bind("127.0.0.1:8080")?
.run()
.await
}This implementation ensures proper token validation with audience and issuer checks, configurable clock skew, and secure secret management through environment variables.
For secret management, integrate with a secrets manager or use environment variables with proper access controls. Never commit secrets to version control. Implement secret rotation policies to regularly update your JWT signing keys.
Add comprehensive error handling that doesn't leak information about why authentication failed. Use generic error messages like "Invalid token" rather than specific messages that could help attackers.
Finally, implement rate limiting on authentication endpoints to prevent brute-force attacks on your JWT system. Actix provides middleware for this, or you can integrate with services like Redis for distributed rate limiting.
Related CWEs: authentication
| CWE ID | Name | Severity |
|---|---|---|
| CWE-287 | Improper Authentication | CRITICAL |
| CWE-306 | Missing Authentication for Critical Function | CRITICAL |
| CWE-307 | Brute Force | HIGH |
| CWE-308 | Single-Factor Authentication | MEDIUM |
| CWE-309 | Use of Password System for Primary Authentication | MEDIUM |
| CWE-347 | Improper Verification of Cryptographic Signature | HIGH |
| CWE-384 | Session Fixation | HIGH |
| CWE-521 | Weak Password Requirements | MEDIUM |
| CWE-613 | Insufficient Session Expiration | MEDIUM |
| CWE-640 | Weak Password Recovery | HIGH |