HIGH missing tlsaxummutual tls

Missing Tls in Axum with Mutual Tls

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

When an Axum service is configured to require Mutual TLS (mTLS) but the server-side TLS settings do not enforce client certificate verification, the endpoint effectively operates without the intended transport-layer authentication. This misconfiguration creates a Missing TLS vulnerability in an otherwise mTLS-protected design: clients may connect successfully, but the server cannot verify their identity. Attackers can capture or spoof requests that should have been authenticated using client certificates, leading to unauthorized access, BOLA/IDOR, or data exposure.

Mutual TLS relies on both parties proving their identity. If the Axum server does not validate presented client certificates (for example, by not setting verify_peer and verify_peer_name in the Rust/TLS stack or equivalent settings in your application layer), the channel is not mutually authenticated. An attacker who can reach the network path can send unauthenticated requests that the server accepts because it only checks that a TLS connection exists, not that it is backed by a trusted client certificate. This bypasses the intended access control boundary introduced by mTLS and can expose sensitive endpoints that assume strong client authentication.

Additionally, if the server trusts any CA rather than a pinned client CA, it may accept certificates issued by unrelated or compromised CAs. This expands the attack surface and can allow lateral movement if an attacker obtains any valid certificate from a broadly trusted CA. Insecure protocol choices (such as allowing older TLS versions or weak cipher suites) further weaken the protection that mTLS is meant to provide, making it easier to downgrade or intercept traffic. The combination of an mTLS-intended API with missing or lax server-side verification turns a security control into a false sense of protection.

Mutual Tls-Specific Remediation in Axum — concrete code fixes

To properly enforce Mutual TLS in Axum, you must configure the underlying HTTPS layer to require and validate client certificates. Below are concrete Rust examples using hyper with rustls, which is a common stack for Axum services. These examples ensure that the server requests and validates client certificates against a trusted CA and that the certificate contents are inspected for authorization decisions.

use axum::Router;
use rustls::{Certificate, PrivateKey, ServerConfig};
use rustls_pemfile::{certs, pkcs8_private_keys};
use std::fs::File;
use std::io::BufReader;
use std::net::SocketAddr;
use std::sync::Arc;

async fn make_mtls_router() -> Router {
    // Load server certificate and private key
    let cert_file = &mut BufReader::new(File::open("server.crt").unwrap());
    let key_file = &mut BufReader::new(File::open("server.key").unwrap());
    let cert_chain: Vec<Certificate> = certs(cert_file).unwrap().into_iter().map(Certificate).collect();
    let mut keys: Vec<PrivateKey> = pkcs8_private_keys(key_file).unwrap().into_iter().map(PrivateKey).collect();

    // Configure client certificate verification
    let mut server_config = ServerConfig::builder()
        .with_safe_defaults()
        .with_no_client_auth() // Start with no auth; we will require it
        .with_single_cert(cert_chain, keys.remove(0))
        .expect("invalid certificate or key");

    // Require and verify client certificates against a trusted CA
    let client_ca = rustls::CertificateAuthorityTrustAnchor::from_web_pki_roots();
    let mut client_verifier = rustls::client::WebPkiServerVerifier::new_with_single_cert(
        vec![rustls::OwnedTrustAnchor::from_subject_spki_name_constraints(
            // Replace with your CA's DER-encoded SubjectPublicKeyInfo
            vec![/* DER bytes */],
            vec![],
            vec![],
        )],
    );
    server_config.client_auth_mandatory = true;
    server_config.client_auth_root_subjects = client_ca.into();
    server_config.verify_scts = true;

    let config = Arc::new(server_config);
    let listener = tokio_rustls::TlsAcceptor::from(config);

    // Build Axum router as usual
    let app = Router::new();
    // In practice, you would bind with hyper + tls acceptor to enforce mTLS on each connection
    app
}

// In your main, bind with TLS:
// let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
// let tls_acceptor = listener;
// axum::serve(tls_acceptor, app).await.unwrap();

The key elements are:

  • Set client_auth_mandatory = true to require client certificates.
  • Provide a trusted set of client CA subject identifiers so the server rejects certificates not signed by those CAs.
  • Optionally inspect the client certificate’s fields (e.g., SANs or OIDs) in your route handlers for fine-grained authorization, but the transport enforcement happens at the TLS layer.

If you use a framework that abstracts TLS (e.g., via a reverse proxy or gateway), ensure the proxy is configured to request and validate client certificates and that Axum trusts only proxied requests that have been properly authenticated. Do not rely on headers like X-SSL-Cert without strict edge configuration, as they can be spoofed.

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

How can I verify that my Axum server is properly enforcing Mutual TLS?
Test by connecting with a valid client certificate issued by the trusted CA and confirm the handshake succeeds. Then connect without a client certificate or with a certificate from an untrusted CA; the TLS handshake should fail. You can also inspect server logs or use a TLS testing tool (e.g., openssl s_client) to confirm that verify_peer is enabled and that client certificates are rejected when invalid.
Does middleBrick detect Missing TLS misconfigurations in mTLS setups?
Yes. middleBrick runs unauthenticated black-box checks including TLS inspection and can identify when a server claims to require Mutual TLS but does not validate client certificates. Findings include severity, context, and remediation guidance to harden your endpoints.