HIGH poodle attackaxummutual tls

Poodle Attack in Axum with Mutual Tls

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

The Poodle attack (CVE-2014-3566) exploits weaknesses in SSL 3.0, primarily the use of CBC-mode ciphers and the lack of protection against padding oracle attacks. While Axum is a Rust web framework and does not implement TLS itself, the risk arises at the transport layer when Axum services are placed behind a TLS-terminating proxy or load balancer that still supports SSL 3.0. Mutual TLS (mTLS) in this context means the client presents a certificate and the server validates it, but if the negotiated protocol is SSL 3.0, the Poodle attack can be leveraged to decrypt intercepted ciphertext by iteratively querying a padding oracle.

In an mTLS setup with Axum, the server verifies client certificates, which increases authentication assurance. However, if the TLS configuration permits SSL 3.0, an attacker who can position themselves as a man-in-the-middle can perform adaptive chosen-ciphertext attacks. For example, if a session cookie or an API token is encrypted using SSL 3.0 with CBC ciphers, the attacker can submit modified requests and observe differences in padding validation errors or timing to gradually reveal plaintext. This is especially dangerous when mTLS is used but the cipher suite is weak, because the client certificate adds value while the protocol provides little confidentiality against padding oracles.

Axum applications commonly terminate TLS at a reverse proxy (such as Nginx, Envoy, or a cloud load balancer) or use Rustls/TlsAcceptor directly. If the terminating endpoint supports SSL 3.0, the Poodle attack surface exists regardless of Axum’s internal logic. mTLS does not prevent protocol downgrade; it only strengthens authentication. Therefore, a misconfigured mTLS deployment that negotiates SSL 3.0 can expose sensitive data, such as serialized authorization tokens or session identifiers, to decryption via Poodle-style padding oracle queries.

To assess this risk with middleBrick, you can scan the public endpoint of your Axum service using the Web Dashboard or the CLI tool (middlebrick scan <url>). The scan includes checks for insecure protocols, weak ciphers, and TLS version support. Findings will map to relevant entries in the OWASP API Top 10 and highlight whether SSL 3.0 is offered, even when mTLS is in place. Continuous monitoring in the Pro plan can alert you if a configuration change re-enables vulnerable protocols, and the GitHub Action can fail builds when scans detect SSL 3.0 support.

Mutual Tls-Specific Remediation in Axum — concrete code fixes

Remediation centers on disabling SSL 3.0 and ensuring strong cipher suites and protocol versions. For Axum applications using Rustls, explicitly configure the server to reject SSL 3.0 and prefer modern TLS 1.2 or TLS 1.3 with AEAD ciphers. When terminating TLS at a proxy, ensure the proxy is configured with secure protocols and that mTLS is enforced with certificate validation and revocation checks.

Below are concrete Rustls-based server examples for Axum that disable SSL 3.0 and enforce strong settings:

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 tokio_rustls::TlsAcceptor;

async fn build_axum_with_mtls() -> Router {
    // Build Axum app
    Router::new()
        // your routes here
}

#[tokio::main]
async fn main() {
    // Load server cert and key
    let cert_file = &mut BufReader::new(File::open("server.crt").expect("cannot open cert"));
    let key_file = &mut BufReader::new(File::open("server.key").expect("cannot open key"));

    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 secure TLS
    let mut config = ServerConfig::builder()
        .with_safe_defaults() // TLS 1.2+, AEAD ciphers, no SSL 3.0
        .with_no_client_auth() // will be replaced with client auth for mTLS
        .with_single_cert(cert_chain, keys.remove(0))
        .expect("invalid cert or key");

    // Enforce mTLS: require and verify client certificates
    use rustls::{ClientCertVerified, ClientCertVerifier, RootCertStore};
    use std::sync::Arc;

    struct MyVerifier {
        roots: RootCertStore,
    }

    impl ClientCertVerifier for MyVerifier {
        fn verify_client_cert(
            &self,
            end_entities: &[Vec<u8>],
            intermediates: &[Vec<u8>],
            server_name: &rustls::ServerName,
            _scts: &mut dyn Iterator<Item = &[u8]>,
            _ocsp_response: &mut dyn Iterator<Item = &[u8]>,
            _now: std::time::SystemTime,
        ) -> Result<ClientCertVerified, rustls::Error> {
            // Implement validation: chain building, revocation, policy checks
            // This is a simplified placeholder
            if end_entities.is_empty() {
                return Err(rustls::Error::General("no client cert".into()));
            }
            // TODO: verify against trusted roots, check revocation, etc.
            Ok(ClientCertVerified::assertion())
        }
    }

    config.client_cert_verifier = Arc::new(MyVerifier { roots: RootCertStore::empty() });

    let acceptor = TlsAcceptor::from(Arc::new(config));
    let listener = tokio::net::TcpListener::bind("0.0.0.0:8443").await.unwrap();
    let app = build_axum_with_mtls().await;

    axum::serve(listener, app.into_make_service())
        .tls_config(acceptor)
        .await
        .unwrap();
}

If you use a reverse proxy, disable SSL 3.0 and weak ciphers there and ensure the proxy validates client certificates before forwarding to Axum. For example, in Nginx you would include ssl_protocols TLSv1.2 TLSv1.3; and ssl_prefer_server_ciphers on;, and configure ssl_client_certificate and verify client on;. middleBrick’s scans will surface remaining TLS configuration issues, and the Pro plan’s continuous monitoring can track these settings over time.

Frequently Asked Questions

Does mutual TLS prevent Poodle if SSL 3.0 is enabled?
No. Mutual TLS strengthens authentication but does not protect against padding oracle attacks. If SSL 3.0 is enabled, an attacker can still perform a Poodle attack to decrypt ciphertext, even when mTLS is used.
How can I verify my Axum service is not vulnerable to Poodle through middleBrick?
Run a scan with the CLI tool using middlebrick scan <your-axum-url> or use the Web Dashboard. The scan checks for SSL 3.0 support and weak ciphers, and findings will indicate whether insecure protocols are exposed despite mTLS.