Missing Tls in Actix with Jwt Tokens
Missing Tls in Actix with Jwt Tokens — how this specific combination creates or exposes the vulnerability
When an Actix web service exchanges JWT tokens without transport-layer encryption, tokens can be intercepted in transit. Even if the token itself is cryptographically signed, transmitting it over HTTP exposes the entire security boundary: an attacker on the network path can capture the token and reuse it (session hijacking). This is not about the JWT signature algorithm being weak; it is about the lack of TLS allowing passive sniffing of what is often an opaque bearer credential.
In practice, this typically occurs when an Actix API is deployed without a reverse proxy or TLS termination enforcing HTTPS, or when developers configure routes to accept both HTTP and HTTP2 without redirecting to HTTPS. Because JWT tokens are often stored in Authorization: Bearer headers, they are easy targets for interception on unencrypted channels. The risk is amplified if the token contains sensitive claims (scopes, roles, or PII), as captured tokens can be replayed until expiration or revocation, bypassing authentication logic that the application assumes is protected by network security alone.
Additionally, mixed-content scenarios where some endpoints require HTTPS and others do not can lead to accidental token leakage via HTTP links or redirects. If an Actix service issues a JWT and returns it over HTTP, any intermediate proxy or client that logs requests might persist the token in clear text. Attack patterns such as credential replay and token theft therefore map directly to the broader OWASP API Security Top 10, notably Broken Object Level Authorization (BOLA) and Security Misconfiguration, when transport security is omitted for authenticated flows.
Jwt Tokens-Specific Remediation in Actix — concrete code fixes
Remediation centers on enforcing HTTPS for all endpoints that issue, validate, or rely on JWT tokens, and ensuring the application never accept or transmit tokens over unencrypted channels. Below are concrete Actix examples that demonstrate a secure setup with TLS enforcement and proper JWT handling.
Enforce HTTPS and redirect HTTP to HTTPS
Use Actix-web’s wrap_fn or middleware to inspect the connection and redirect insecure requests. This ensures tokens are only ever exchanged over encrypted transport.
use actix_web::{web, App, HttpServer, HttpResponse, middleware::Logger};
use actix_web::dev::ServiceRequest;
use actix_web::error::ErrorPermanent;
use std::future::{ready, Ready};
async fn redirect_to_https(req: ServiceRequest) -> Result {
if !req.connection_info().ssl().unwrap_or(false) {
let host = req.connection_info().host().to_string();
let uri = req.uri().to_string();
let target = format!("https://{}{}", host, uri);
return Err(actix_web::error::ErrorPermanent(
actix_web::HttpResponse::PermanentRedirect()
.insert_header(("location", target))
.finish()
));
}
Ok(req)
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new()
.wrap(Logger::default())
.wrap_fn(|req, srv| {
let fut = srv.call(req);
async move {
match fut.await {
Ok(res) => Ok(res),
Err(e) if e.as_response_error().status_code().is_redirection() => Err(e),
Err(e) => {
let req = e.as_response_error().error_response().request().clone();
redirect_to_https(req).await.map_err(|e_inner| e_inner.into())
}
}
}
})
.service(web::resource("/auth/token").to(issue_token))
})
.bind("0.0.0.0:8080")?
.run()
.await
}
Issue and validate JWT tokens over HTTPS-only endpoints
Define a secure handler that issues a JWT over HTTPS and sets strict transport security headers. Use the jsonwebtoken crate for signing and ensure the token is only returned when the request is TLS-terminated.
use actix_web::{web, HttpResponse};
use jsonwebtoken::{encode, Header, EncodingKey};
use serde::{Serialize};
#[derive(Serialize)]
struct Claims {
sub: String,
scope: String,
exp: usize,
}
async fn issue_token() -> HttpResponse {
let my_claims = Claims {
sub: "user-123".to_string(),
scope: "read write".to_string(),
exp: (chrono::Utc::now() + chrono::Duration::hours(1)).timestamp() as usize,
};
let token = encode(
&Header::default(),
&my_claims,
&EncodingKey::from_secret("secret".as_ref()),
).unwrap();
HttpResponse::Ok()
.insert_header(("Strict-Transport-Security", "max-age=31536000; includeSubDomains"))
.json(token)
}
Validate JWT tokens and require secure connections for protected routes
Protect endpoints that accept JWTs by requiring HTTPS and validating the token before processing the request. This ensures that even if a token is intercepted, it cannot be used without TLS to deliver it to a protected resource.
use actix_web::{web, HttpRequest, HttpResponse, dev::ServiceRequest};
use actix_web::middleware::Next;
use actix_web::body::BoxBody;
use actix_web::http::header::AUTHORIZATION;
use jsonwebtoken::{decode, TokenData, Validation, DecodingKey};
async fn validate_jwt_middleware(
req: ServiceRequest,
next: Next,
) -> Result, actix_web::Error> {
let auth_header = req.headers().get(AUTHORIZATION)
.ok_or_else(|| actix_web::error::ErrorUnauthorized("Missing Authorization header"))?;
let token = auth_header.to_str().map_err(|_| actix_web::error::ErrorUnauthorized("Invalid header"))?;
if !token.starts_with("Bearer ") {
return Err(actix_web::error::ErrorUnauthorized("Invalid token format"));
}
let token = token.trim_start_matches("Bearer ");
let _claims: TokenData = decode(
token,
&DecodingKey::from_secret("secret".as_ref()),
&Validation::default(),
).map_err(|_| actix_web::error::ErrorUnauthorized("Invalid token"))?;
next.call(req).await
}
In summary, the combination of missing TLS and JWT tokens leads to token exposure in clear text. Remediation requires enforcing HTTPS for all endpoints, redirecting HTTP to HTTPS, and validating JWTs only over secure connections. These practices reduce the attack surface for token interception and replay.
Related CWEs: encryption
| CWE ID | Name | Severity |
|---|---|---|
| CWE-319 | Cleartext Transmission of Sensitive Information | HIGH |
| CWE-295 | Improper Certificate Validation | HIGH |
| CWE-326 | Inadequate Encryption Strength | HIGH |
| CWE-327 | Use of a Broken or Risky Cryptographic Algorithm | HIGH |
| CWE-328 | Use of Weak Hash | HIGH |
| CWE-330 | Use of Insufficiently Random Values | HIGH |
| CWE-338 | Use of Cryptographically Weak PRNG | MEDIUM |
| CWE-693 | Protection Mechanism Failure | MEDIUM |
| CWE-757 | Selection of Less-Secure Algorithm During Negotiation | HIGH |
| CWE-261 | Weak Encoding for Password | HIGH |