Beast Attack in Axum (Rust)
Beast Attack in Axum with Rust
The BEAST (Browser Exploit Against SSL/TLS) attack exploits a vulnerability in CBC-mode cipher suites in TLS 1.0 and earlier, allowing an attacker to decrypt portions of encrypted traffic by manipulating initialization vectors (IVs) and observing ciphertext changes. While Axum itself does not implement TLS—the underlying hyper server or a reverse proxy (like nginx) handles encryption—misconfigurations in the deployment stack can leave Axum-based APIs exposed if they rely on outdated TLS settings.
In a typical Axum service, developers may configure TLS directly using hyper-rustls or tokio-rustls for embedded HTTPS servers. If the TLS configuration permits TLS 1.0 or weak CBC-mode ciphers (e.g., TLS_RSA_WITH_AES_128_CBC_SHA), the service becomes susceptible to BEAST. This is particularly relevant in internal tooling or legacy environments where compatibility overrides security.
middleBrick’s scan detects such exposure by testing the unauthenticated attack surface, including TLS version and cipher suite negotiation. Even though the attack is network-layer, its impact surfaces in API security scoring because compromised confidentiality can lead to session hijacking, credential theft, or API key leakage—directly affecting findings under the ‘Encryption’ and ‘Data Exposure’ checks. middleBrick reports these as high-severity findings with guidance to disable TLS 1.0 and prioritize AEAD ciphers like AES-GCM or ChaCha20-Poly1305.
Rust-Specific Remediation in Axum
To mitigate BEAST risk in an Axum application, ensure TLS is configured to reject TLS 1.0 and prefer modern, secure cipher suites. Using tokio-rustls with rustls allows precise control over TLS parameters. The following example shows a secure Axum server setup that disables TLS 1.0 and enables only AEAD ciphers:
use axum::{Router, routing::get};
use tokio::net::TcpListener;
use tokio_rustls::{TlsAcceptor, rustls};
use std::sync::Arc;
#[tokio::main]
async fn main() {
// Load TLS certificate and key
let certs = rustls::Certificate(
std::fs::read("cert.pem").expect("failed to read cert")
);
let key = rustls::PrivateKey(
std::fs::read("key.pem").expect("failed to read key")
);
// Configure rustls to reject TLS 1.0 and weak ciphers
let mut cfg = rustls::ServerConfig::builder()
.with_safe_defaults()
.with_no_client_auth()
.with_single_cert(vec![certs.0], key.0)
.expect("invalid cert/key");
// Explicitly disable TLS 1.0 and enforce modern versions
cfg.versions = vec![
rustls::version::TLS13,
rustls::version::TLS12,
];
// Optionally restrict to AEAD-only ciphers (safe_defaults already does this)
// but we can verify: cfg.cipher_suites should not include any CBC suites
let acceptor = TlsAcceptor::from(Arc::new(cfg));
let app = Router::new().route("/", get(|| async { "Hello, world!" }));
let listener = TcpListener::bind("0.0.0.0:443").await.unwrap();
loop {
let (stream, _) = listener.accept().await.unwrap();
let acceptor = acceptor.clone();
tokio::spawn(async move {
match acceptor.accept(stream).await {
Ok(tls_stream) => {
// Handle HTTP over TLS via hyper
if let Err(err) = hyper::server::conn::http1::Builder::new()
.serve_connection(tls_stream, app.into_make_service())
.await
{
eprintln!("HTTP error: {}", err);
}
}
Err(err) => eprintln!("TLS error: {}", err),
}
});
}
}
This configuration ensures that:
- TLS 1.0 is explicitly disabled via
cfg.versions. - Only TLS 1.2 and 1.3 are permitted.
- The
with_safe_defaults()method inrustlsautomatically excludes CBC-mode ciphers in favor of AEAD suites (e.g., TLS_AES_128_GCM_SHA256, TLS_CHACHA20_POLY1305_SHA256). - No agents or configuration changes to Axum routing are needed—security is enforced at the transport layer.
After applying this fix, a middleBrick rescan will show improved scores in the ‘Encryption’ category, reflecting the removal of BEAST-prone configurations. Note that middleBrick does not alter your server; it only reports findings based on what it observes during the black-box scan.