CRITICAL man in the middleactix

Man In The Middle in Actix

How Man In The Middle Manifests in Actix

A Man-In-The-Middle (MITM) attack against an Actix-based API occurs when an adversary intercepts or alters traffic between a client and the server. This is rarely a flaw in Actix's core logic but stems from TLS/SSL configuration weaknesses or application-level trust assumptions. In Rust's Actix-web framework, common manifestation points include:

  • Insecure TLS Configuration: Using rustls or native-tls with permissive settings. For example, creating an SslAcceptor without explicitly setting a minimum TLS version or allowing legacy cipher suites. A historical example is CVE-2020-17530, where certain rustls versions allowed connections with TLS 1.0/1.1, making traffic vulnerable to downgrade attacks.
  • Missing Certificate Validation: When Actix acts as a client (e.g., calling downstream APIs) using reqwest or surf, disabling certificate verification (danger_accept_invalid_certs(true) or custom rustls::ClientConfig with dangerous().set_certificate_verifier(...)) creates a MITM vector.
  • Mixed Content or HTTP Fallback: An Actix server that does not enforce HTTPS via redirects or HSTS headers allows initial connections over plain HTTP, where MITM can occur before any encryption is established.
  • Unvalidated Redirects: If an Actix endpoint accepts a URL parameter and issues a redirect (e.g., HttpResponse::Found().append_header(("location", url))) without validating the target scheme, an attacker could redirect a user from HTTPS to HTTP.

The attack exploits trust boundaries. If an API relies solely on transport security without additional integrity checks (like signatures), a MITM with a forged certificate (e.g., via compromised CA or user-installed root) can read or modify JSON payloads, tokens, or PII.

Actix-Specific Detection

Detecting MITM vulnerabilities in an Actix API requires examining both the server's TLS handshake and its HTTP behavior.

Manual Inspection

  • TLS Configuration Review: Inspect Actix server initialization code. Look for HttpServer::bind().tls(ssl_acceptor) and verify the SslAcceptor setup. Red flags include: .set_min_proto_version(Some(Protocol::TLSv1)), or using rustls::crypto::CryptoProvider::get_default().unwrap().cipher_suites without filtering weak suites (e.g., TLS_RSA_WITH_AES_128_CBC_SHA).
  • HTTP-to-HTTPS Enforcement: Check for middleware that redirects HTTP to HTTPS (e.g., actix-web::middleware::Redirect) and HSTS header setting (actix-web::middleware::DefaultHeaders with Strict-Transport-Security).
  • Outbound Client Configuration: Search for reqwest::Client::builder().danger_accept_invalid_certs(true) or similar in any service that makes external calls on behalf of the API.

Automated Scanning with middleBrick

middleBrick's Encryption check (one of its 12 parallel security tests) automatically probes an API's TLS configuration. When you submit an Actix endpoint URL to middleBrick, it:

  • Performs a TLS handshake analysis, checking for protocol versions, cipher suite strength, certificate validity, and HSTS presence.
  • Attempts HTTP connections to verify if the server responds over unencrypted channels.
  • Reports findings with a severity score and remediation guidance specific to the detected weakness, such as "Weak cipher suite detected (TLS_RSA_WITH_AES_128_CBC_SHA)" or "No HSTS header."

For example, scanning an Actix API with middlebrick scan https://api.example.com might return a medium-severity finding if TLS 1.0 is enabled, mapping to OWASP API Top 10:API7:2023 – Security Misconfiguration.

You can integrate this into your CI/CD pipeline using the middleBrick GitHub Action. By adding a step that runs middlebrick/scan-action@v1 with your staging API URL, you can fail the build if the Encryption check score drops below a threshold, preventing deployment of Actix services with weak TLS.

Actix-Specific Remediation

Remediation involves hardening the Actix server's TLS stack and enforcing secure transport end-to-end.

1. Configure Strong TLS on the Server

When setting up rustls with Actix, explicitly define a secure configuration:

use actix_web::{web, App, HttpServer, HttpResponse, Responder};
use rustls::{ServerConfig, PrivateKey, Certificate};
use std::fs::File;
use std::io::BufReader;

async fn index() -> impl Responder {
HttpResponse::Ok().body("Hello HTTPS!")
}
async fn main() -> std::io::Result<()> {
// Load certificates
let cert_file = &mut BufReader::new(File::open("cert.pem").unwrap());
let key_file = &mut BufReader::new(File::open("key.pem").unwrap());
let cert_chain = rustls_pemfile::certs(cert_file).unwrap();
let mut keys = rustls_pemfile::pkcs8_private_keys(key_file).unwrap();
let server_config = ServerConfig::builder()
.with_safe_defaults() // Enforces TLS 1.2+ and strong ciphers
.with_no_client_auth() // Adjust if mutual TLS is needed
.with_single_cert(cert_chain, keys.remove(0))
.unwrap();

HttpServer::new(|| {
App::new().route("/", web::get().to(index))
})
.bind_rustls("0.0.0.0:8443", server_config)?
.run()
.await
}

Key points:

  • .with_safe_defaults() uses rustls's secure preset (TLS 1.2/1.3, AEAD ciphers only). Avoid .with_protocol_versions(&[&Protocol::TLSv1_2, &Protocol::TLSv1_3]) for explicit control.
  • Do not use .with_cipher_suites(...) to re-enable CBC-mode suites; the safe default excludes them.

2. Enforce HTTPS and HSTS

Use Actix middleware to redirect HTTP and set HSTS:

use actix_web::{dev::Service, http::header, HttpResponse, HttpMessage};
use actix_web::middleware::{self, Redirect, DefaultHeaders};

let app = App::new()
.wrap(Redirect::new().to("https://{host}{uri}")) // HTTP to HTTPS
.wrap(DefaultHeaders::new()
.header(header::STRICT_TRANSPORT_SECURITY, "max-age=31536000; includeSubDomains"))
.service(web::resource("/").route(web::get().to(index)));

This ensures clients never communicate over HTTP and instruct browsers to always use HTTPS.

3. Secure Outbound Calls

If your Actix service calls external APIs, configure the client with strict certificate verification. For reqwest:

let client = reqwest::Client::builder()
.use_rustls_tls() // Use rustls with default secure config
.build()
.unwrap();
// Never call .danger_accept_invalid_certs(true) in production

4. Validate Redirects

When generating redirects, whitelist allowed schemes and domains:

fn safe_redirect(url: &str) -> HttpResponse {
if url.starts_with("https://trusted-api.example.com") {
HttpResponse::Found().append_header(("location", url)).finish()
} else {
HttpResponse::BadRequest().body("Invalid redirect URL")
}
}

By combining these Actix-specific configurations, you close common MITM vectors. Continuously monitor your API's TLS posture with middleBrick's Dashboard to track score improvements over time and receive alerts if a regression introduces weak ciphers or disables HSTS.

FAQ

Q: Does MITM only affect public APIs?
A: No. Internal or partner APIs are equally vulnerable if TLS is misconfigured. Attackers on the same network (e.g., compromised internal host, malicious insider) can intercept traffic. All Actix APIs, regardless of exposure, must enforce strong TLS.

Q: Can middleBrick detect all TLS flaws in my Actix API?
A: middleBrick's Encryption check tests for common misconfigurations (protocol versions, cipher strength, certificate issues, HSTS, HTTP fallback). It does not scan for every CVE in underlying TLS libraries (e.g., a specific rustls memory corruption bug). For those, you must keep dependencies updated via cargo audit. middleBrick's score reflects the observable security posture from the network perspective.