HIGH out of bounds readactixmutual tls

Out Of Bounds Read in Actix with Mutual Tls

Out Of Bounds Read in Actix with Mutual Tls

An Out Of Bounds Read occurs when an application reads memory beyond the allocated buffer. In Actix with Mutual TLS (mTLS), this can arise when TLS-terminated requests are parsed and application-layer buffers are sized based on attacker-controlled metadata rather than validated certificate-bound constraints. mTLS ensures client authentication via client certificates, but it does not automatically constrain how route handlers interpret message size or structure. If a handler deserializes frames or streams without strict length checks, an attacker may supply content that triggers reads past the end of a slice or vector, potentially exposing stack or heap memory.

Consider an Actix web service that uses mTLS for client authentication and processes incoming byte payloads. A route might read a header indicating a payload length and then copy that many bytes into a buffer. If the length is not cross-checked against the actual TLS record size or the remaining bytes in the stream, an Out Of Bounds Read can occur. This is especially relevant when integrating streaming APIs or chunked formats where the boundary between TLS decryption and application parsing is not explicitly validated. The combination of mTLS (which authenticates peers) and unchecked deserialization (which trusts content-length or framing metadata) creates a scenario where memory safety depends entirely on correct bounds enforcement in user code.

In practice, this can manifest in handlers that parse binary protocols or custom framing. For example, reading a u32 length prefix and then slicing a buffer without verifying that the buffer length is at least length + offset can read beyond the slice. Even with mTLS ensuring the connection is authenticated, the application layer remains responsible for validating message boundaries. Actix payload extractors and body collectors must enforce strict size limits and use safe abstractions (e.g., Cursor, take, and checked slicing) rather than unchecked pointer arithmetic or unchecked indexing.

Mutual Tls-Specific Remediation in Actix

Remediation centers on validating sizes before reads and using safe Rust slicing. Always check buffer lengths against declared sizes and avoid unchecked indexing. When using Actix with mTLS, enforce per-request size limits at the extractor or payload collector level and prefer streaming APIs that enforce bounds automatically.

Example: Safe Actix mTLS configuration with size validation

use actix_web::{web, App, HttpResponse, HttpServer, Responder};
use actix_web::http::header::CONTENT_LENGTH;
use actix_web::web::Bytes;
use std::num::NonZeroUsize;

// A handler that reads a length-prefixed payload safely
async fn handle_payload(body: Bytes) -> impl Responder {
    // Enforce a global maximum to prevent resource exhaustion
    const MAX_BODY: usize = 1024 * 64; // 64 KiB
    if body.len() > MAX_BODY {
        return HttpResponse::PayloadTooLarge().body("body too large");
    }

    // Parse a u32 length prefix at the start, ensuring there are enough bytes
    if body.len() < 4 {
        return HttpResponse::BadRequest().body("missing length prefix");
    }
    let length = u32::from_be_bytes([body[0], body[1], body[2], body[3]]) as usize;

    // Validate that the reported length fits within the actual body
    if length > MAX_BODY || 4 + length > body.len() {
        return HttpResponse::BadRequest().body("invalid length");
    }

    let payload = &body[4..4 + length];
    // Process payload safely within bounds
    HttpResponse::Ok().body(format!("received {} bytes", payload.len()))
}

// Actix mTLS setup (server-side configuration example)
#[actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| {
        App::new()
            .route("/secure", web::post().to(handle_payload))
    })
    .bind_rustls_01(
        "127.0.0.1:8443",
        rustls::ServerConfig::builder()
            .with_safe_defaults()
            .with_client_auth() // require client certs
            .with_single_cert(
                vec![rustls::Certificate(include_bytes("../certs/server.crt").to_vec())],
                rustls::PrivateKey(include_bytes("../certs/server.key").to_vec()),
            )
            .expect("invalid server cert/key")
    )?
    .run()
    .await
}

Key practices to prevent Out Of Bounds Reads

  • Use Bytes and slice with range checks (e.g., body.get(start..end)) instead of unchecked indexing.
  • Enforce a configurable per-route or global size ceiling in your Actix extractors to mitigate DoS and memory safety issues.
  • When integrating with streaming bodies, prefer web::block with bounded buffers and avoid accumulating unbounded chunks without validation.
  • Leverage Rust’s type system: return Result with explicit error handling for malformed length fields, and avoid unsafe blocks unless strictly necessary and carefully audited.

These steps align with the broader security posture provided by the Pro plan’s continuous monitoring and GitHub Action integration, which can flag missing size checks in your CI/CD pipeline before deployment.

Frequently Asked Questions

Does mTLS prevent Out Of Bounds Read vulnerabilities in Actix?
No. Mutual TLS authenticates clients and servers but does not enforce application-level bounds. Out Of Bounds Reads must be prevented in code by validating sizes before reading buffers.
How can I detect these issues during development with middleBrick?
Use the CLI to scan your endpoints: middlebrick scan https://your-api.example.com. The scanner checks input validation and size-bound handling, mapping findings to frameworks like OWASP API Top 10 to highlight missing bounds checks.