HIGH token leakageactix

Token Leakage in Actix

How Token Leakage Manifests in Actix

Token leakage in Actix applications typically occurs through improper handling of authentication tokens in HTTP responses, logs, and error messages. Actix's async-first architecture and middleware system create specific patterns where tokens can be inadvertently exposed.

The most common manifestation appears in Actix's error handling middleware. When authentication fails, Actix applications often return error responses that include the original request's Authorization header or JWT token in the response body or logs. This happens because Actix's error handlers capture the full request context for debugging purposes.

use actix_web::{web, App, HttpServer, HttpResponse, error, Error};

// Vulnerable pattern - token appears in error response
async fn protected_route(auth_token: web::ReqData<String>) -> Result<HttpResponse, Error> {
    if auth_token.is_empty() {
        return Err(error::ErrorUnauthorized(
            HttpResponse::build(401)
                .body(format!("Missing token: {}", auth_token)) // Token exposed
        ));
    }
    Ok(HttpResponse::Ok().finish())
}

Another Actix-specific vulnerability occurs in middleware that logs requests. Actix's logging middleware often captures headers by default, and if not configured properly, will log Authorization headers containing bearer tokens:

use actix_web::{middleware::Logger, dev::ServiceRequest};

// Vulnerable logging - tokens captured in logs
async fn log_middleware(req: ServiceRequest, srv: &mut actix_web::dev::Service<_, _, _>) -> Result<ServiceRequest, actix_web::Error> {
    log::info!("Request: {} {} {:?}", req.method(), req.uri(), req.headers());
    srv.call(req).await
}

Actix's extractors can also cause token leakage when they panic or return detailed error messages. The default error handlers in Actix may include sensitive header information in their JSON responses, exposing tokens to unauthenticated clients.

Actix-Specific Detection

Detecting token leakage in Actix applications requires examining both the code structure and runtime behavior. middleBrick's black-box scanning approach is particularly effective for Actix applications because it tests the actual HTTP responses without needing source code access.

middleBrick scans Actix APIs for token leakage by sending requests to protected endpoints with invalid or expired tokens, then analyzing the responses for sensitive information disclosure. The scanner specifically looks for Authorization headers, JWT payloads, and bearer tokens appearing in HTTP response bodies, headers, or error messages.

Key detection patterns include:

  • 401/403 responses containing original Authorization headers
  • Error messages that echo back submitted tokens
  • Stack traces or debug information that include token values
  • Response headers that reflect request headers containing tokens
  • Log messages captured in HTTP responses

For Actix applications, middleBrick's OpenAPI analysis can identify endpoints that expect authentication tokens, then verify that these endpoints properly sanitize error responses. The scanner tests the unauthenticated attack surface by attempting to access protected routes without valid credentials and examining what information is disclosed.

Code-level detection in Actix involves searching for patterns where tokens are included in response bodies or error messages:

// Patterns to search for in Actix code
// 1. Tokens in error responses
if let Err(e) = authenticate(req.headers()) {
    return Err(error::ErrorUnauthorized(
        HttpResponse::build(401)
            .body(format!("Authentication failed: {:?}", e)) // May expose token
    ));
}

// 2. Tokens in logs
log::error!("Failed authentication: {}", req.headers().get("authorization")?);

middleBrick's continuous monitoring for Pro plan customers can automatically detect when new token leakage vulnerabilities are introduced through code changes, providing alerts before deployment.

Actix-Specific Remediation

Remediating token leakage in Actix requires leveraging Actix's middleware system and error handling patterns. The key principle is to ensure tokens are never included in responses, logs, or error messages.

Proper error handling in Actix should use generic error messages that don't reflect request content:

use actix_web::{error, HttpResponse};

// Secure error handling - no token exposure
async fn protected_route(auth_token: web::ReqData<String>) -> Result<HttpResponse, Error> {
    if auth_token.is_empty() {
        return Err(error::ErrorUnauthorized(
            HttpResponse::build(401)
                .body("Authentication required") // Generic message
        ));
    }
    Ok(HttpResponse::Ok().finish())
}

Actix's middleware system provides hooks for sanitizing request data before logging:

use actix_web::{middleware::Logger, dev::ServiceRequest, dev::Service};
use actix_web::http::HeaderValue;

struct SanitizedLogger;

impl actix_web::middleware::Middleware for SanitizedLogger {
    async fn call(&self, req: ServiceRequest, srv: &mut Service<_, _, _>) -> Result<ServiceRequest, actix_web::Error> {
        // Remove Authorization header before logging
        let mut sanitized_req = req.clone();
        if let Some(_) = sanitized_req.headers_mut().remove("authorization") {
            log::info!("Request: {} {} {:?}", 
                sanitized_req.method(), 
                sanitized_req.uri(), 
                sanitized_req.headers());
        }
        srv.call(sanitized_req).await
    }
}

For Actix applications using JWT tokens, implement custom extractors that sanitize error messages:

use actix_web::{FromRequest, dev::ServiceRequest, Error};
use actix_web::http::header::HeaderError;

struct SanitizedAuthExtractor;

#[async_trait::async_trait]
impl FromRequest for SanitizedAuthExtractor {
    type Config = ();
    type Error = Error;
    type Future = Ready<Result<Self, Self::Error>>;

    fn from_request(req: &ServiceRequest, _: &mut Bytes) -> Self::Future {
        // Custom extraction that returns generic errors
        ready(match req.headers().get("authorization") {
            Some(header) if header.to_str().unwrap().starts_with("Bearer ") => {
                Ok(SanitizedAuthExtractor)
            }
            _ => Err(error::ErrorUnauthorized("Authentication required"))
        })
    }
}

Actix's error handling can be centralized using App error handlers to ensure consistent sanitization across all endpoints:

use actix_web::{App, HttpServer, error, HttpResponse};

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| {
        App::new()
            .wrap(error::ErrorHandler::new(|err, req| {
                // Always return generic error messages
                if err.status() == 401 || err.status() == 403 {
                    Ok(HttpResponse::build(err.status())
                        .content_type("text/plain")
                        .body("Access denied"))
                } else {
                    Err(err)
                }
            }))
            .service(protected_route)
    })
    .bind("127.0.0.1:8080")?
    .run()
    .await
}

Frequently Asked Questions

How does middleBrick detect token leakage in Actix applications?
middleBrick performs black-box scanning by sending requests to Actix endpoints with invalid tokens, then analyzing responses for sensitive information disclosure. It specifically tests for Authorization headers, JWT payloads, and bearer tokens appearing in HTTP response bodies, headers, or error messages. The scanner works without needing source code access, making it effective for testing deployed Actix applications.
Can middleBrick scan Actix applications that use WebSocket connections?
Yes, middleBrick can scan Actix applications with WebSocket endpoints. While the primary scanning focuses on HTTP REST APIs, middleBrick tests the authentication mechanisms and error handling that WebSocket connections rely on. The scanner verifies that token-based authentication for WebSocket upgrades properly sanitizes error responses and doesn't expose sensitive token information in upgrade failures or connection errors.