CRITICAL missing tlsactixmutual tls

Missing Tls in Actix with Mutual Tls

Missing Tls in Actix with Mutual Tls — how this specific combination creates or exposes the vulnerability

When an Actix web service is configured to require client certificates for Mutual TLS but the server listener itself lacks TLS, the transport is effectively unencrypted and unauthenticated. This mismatch means clients may establish a plaintext HTTP connection even though the application expects client-side authentication, bypassing the intended Mutual TLS protections.

The vulnerability arises because Mutual TLS relies on two-way authentication over a cryptographically secured channel. Without server-side TLS, there is no encryption in transit, exposing credentials, tokens, and session cookies to eavesdropping. Additionally, without server certificate validation, clients cannot verify the identity of the server, enabling man-in-the-middle attacks. An attacker on the network can intercept or modify requests, and because the server is not enforcing TLS, it may treat the unauthenticated plaintext connection as trusted based solely on the presence of a client certificate that is never validated due to missing server-side TLS termination.

During a middleBrick scan, this configuration appears as Missing Tls combined with ineffective Mutual Tls, producing findings in the Encryption and Authentication categories. The scanner detects that the endpoint does not present a valid server certificate and does not enforce HTTPS, even when the application logic assumes Mutual TLS is active. Findings include the absence of server certificate validation, lack of transport-layer encryption, and potential exposure of sensitive data. Remediation guidance typically involves enabling TLS on the server, ensuring the server presents a valid certificate, and configuring the Actix service to require and verify client certificates over the encrypted channel.

In the context of compliance frameworks referenced by middleBrick, such findings map to OWASP API Top 10 A02:2023 — Cryptographic Failures, and can also affect PCI-DSS and SOC2 controls where encryption in transit is required. middleBrick’s scans identify these gaps and provide prioritized remediation steps so teams can enforce proper Mutual TLS in Actix deployments.

Mutual Tls-Specific Remediation in Actix — concrete code fixes

To secure an Actix service with Mutual TLS, you must enable server-side TLS with a valid certificate and private key, and configure the Actix application to require and validate client certificates. Below is a concrete, working example using Rust and Actix-web with native-tls or rustls.

Using native-tls (openssl-based)

use actix_web::{web, App, HttpServer, Responder};
use actix_web::middleware::Logger;
use native_tls::Identity;
use std::fs::File;
use std::io::Read;

async fn index() -> impl Responder {
    "Hello over Mutual TLS"
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    // Load server identity (certificate + private key)
    let mut cert_file = File::open("server-cert.pem").expect("cannot open server cert");
    let mut key_file = File::open("server-key.pem").expect("cannot open server key");
    let mut cert_buf = Vec::new();
    let mut key_buf = Vec::new();
    cert_file.read_to_end(&mut cert_buf).unwrap();
    key_file.read_to_end(&mut key_buf).unwrap();
    let identity = Identity::from_pkcs8(&cert_buf, &key_buf).expect("invalid pkcs8");

    // Configure TLS acceptor with client CA for client certificate verification
    let mut builder = native_tls::TlsAcceptor::builder(identity);
    let mut ca_file = File::open("ca-chain.pem").expect("cannot open CA cert");
    let mut ca_buf = Vec::new();
    ca_file.read_to_end(&mut ca_buf).unwrap();
    let ca = native_tls::Certificate::from_pem(&ca_buf).expect("invalid CA cert");
    builder.add_root_certificate(ca);
    builder.client_auth_native_tls(native_tls::ClientAuth::Required);
    let acceptor = builder.build().expect("failed to build TLS acceptor");

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

Using rustls (recommended for modern Rust)

use actix_web::{web, App, HttpServer, Responder};
use actix_web::middleware::Logger;
use rustls::{Certificate, PrivateKey, ServerConfig};
use rustls_pemfile::{certs, pkcs8_private_keys};
use std::fs::File;
use std::io::BufReader;
use std::sync::Arc;

async fn index() -> impl Responder {
    "Hello over Mutual TLS (rustls)"
}

fn load_rustls_config() -> Arc {
    // Load server certificate and key
    let cert_file = &mut BufReader::new(File::open("server-cert.pem").unwrap());
    let key_file = &mut BufReader::new(File::open("server-key.pem").unwrap());

    let cert_chain = certs(cert_file).unwrap_or_else(|_| panic!("failed to load certs"));
    let mut keys = pkcs8_private_keys(key_file).unwrap_or_else(|_| panic!("failed to load keys"));

    let certs: Vec = cert_chain.into_iter().map(Certificate).collect();
    let priv_key = PrivateKey(keys.remove(0));

    // Load trusted client CA for client certificate verification
    let mut ca_file = BufReader::new(File::open("ca-chain.pem").unwrap());
    let client_certs = certs(&mut ca_file).unwrap_or_else(|_| panic!("failed to load CA"));
    let client_certs: Vec = client_certs.into_iter().map(Certificate).collect();

    let mut config = ServerConfig::builder()
        .with_safe_defaults()
        .with_no_client_auth()
        .with_client_auth_cert(client_certs, priv_key)
        .expect("invalid client auth config");

    config.alpn_protocols = vec![b"h2".to_vec(), b"http/1.1".to_vec()];
    Arc::new(config)
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    let config = load_rustls_config();

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

Key points in the remediation:

  • Always enable TLS on the server with a valid certificate; do not rely on application-level checks alone.
  • Configure the TLS acceptor to require client certificates (e.g., client_auth_native_tls(native_tls::ClientAuth::Required) or .with_client_auth_cert(...) in rustls).
  • Provide a trusted CA bundle to validate presented client certificates; reject connections without a valid client cert.
  • Ensure the server certificate chain is complete and the private key is protected.
  • Use strong cipher suites and disable outdated protocols (TLS 1.2+ recommended).

After applying these fixes, re-run the middleBrick scan to confirm that Encryption and Authentication findings are resolved and that the endpoint now presents a valid server certificate while enforcing Mutual TLS.

Related CWEs: encryption

CWE IDNameSeverity
CWE-319Cleartext Transmission of Sensitive Information HIGH
CWE-295Improper Certificate Validation HIGH
CWE-326Inadequate Encryption Strength HIGH
CWE-327Use of a Broken or Risky Cryptographic Algorithm HIGH
CWE-328Use of Weak Hash HIGH
CWE-330Use of Insufficiently Random Values HIGH
CWE-338Use of Cryptographically Weak PRNG MEDIUM
CWE-693Protection Mechanism Failure MEDIUM
CWE-757Selection of Less-Secure Algorithm During Negotiation HIGH
CWE-261Weak Encoding for Password HIGH

Frequently Asked Questions

What does Missing Tls in Actix with Mutual Tls mean?
It means the Actix server does not enforce TLS on the transport, even though the application expects Mutual TLS. This exposes credentials and allows man-in-the-middle attacks because client certificates are not validated over an unencrypted channel.
How can I verify Mutual Tls is correctly enforced in Actix?
Use a middleBrick scan to confirm the endpoint requires TLS, presents a valid server certificate, and enforces client certificate validation. You can also test manually with curl: curl --cert client-cert.pem --key client-key.pem --cacert ca-chain.pem https://host:8443 and confirm plaintext HTTP without TLS is rejected.