Man In The Middle in Axum
How Man In The Middle Manifests in Axum
In Axum, Man-in-the-Middle (MITM) attacks primarily occur when TLS is not properly enforced or when developers disable certificate validation for convenience during development. A common pattern is using reqwest or hyper clients without verifying server certificates, allowing an attacker to intercept and modify traffic between the Axum service and downstream APIs. For example, if an Axum handler makes outbound HTTP calls to a payment gateway or user service and sets danger_accept_invalid_certs = true in the TLS configuration, an attacker with network access can present a fraudulent certificate and decrypt, inspect, or alter the communication.
Another Axum-specific vector involves misconfigured middleware that inadvertently downgrades security. Consider a scenario where Axum’s SetCookie middleware is used without the Secure flag, or where axum::extract::Path or Query extractors are used to build redirect URLs without validation. An attacker could manipulate these to redirect users to a malicious proxy that terminates TLS and re-encrypts with a controlled certificate, capturing session tokens or credentials.
Additionally, if Axum services are deployed behind a reverse proxy (like NGINX) and the Proxy middleware is used to trust headers like X-Forwarded-Proto without validating the proxy chain, an attacker could spoof these headers to make the application believe it’s using HTTPS when it’s actually HTTP, enabling SSL stripping attacks.
Axum-Specific Detection
Detecting MITM vulnerabilities in Axum applications requires checking for disabled TLS validation, missing security flags, and improper trust of headers. middleBrick identifies these issues during its unauthenticated black-box scan by analyzing HTTP responses for missing security headers (Strict-Transport-Security, Secure and HttpOnly flags on cookies) and testing whether the endpoint accepts HTTP connections when HTTPS is expected.
For outbound calls made by Axum services, middleBrick does not directly inspect application code but detects symptoms of MITM susceptibility: if the service communicates with external APIs over HTTP instead of HTTPS, or if TLS errors are improperly handled (e.g., returning detailed error messages that could aid an attacker), these are flagged under the Data Exposure and Encryption checks. For instance, if an Axum handler returns a 502 Bad Gateway with details about a failed TLS handshake to an internal service, it may indicate misconfigured certificate validation that could be exploited.
Developers can also detect potential MITM risks locally by reviewing code for patterns like:
reqwest::Client::builder().danger_accept_invalid_certs(true)hyper::Client::builder().http2_prior_knowledge()without TLS- Setting cookies without
SecureandHttpOnlyflags in Axum’sresponse::Responsebuilders - Using
axum::extract::TypedHeader::headers()to trustX-Forwarded-Protowithout verifying the connection is from a trusted proxy
middleBrick’s scan will highlight missing HSTS headers or cookies lacking the Secure flag as medium-severity findings under the Encryption category, guiding developers to enforce transport security at the framework level.
Axum-Specific Remediation
Remediating MITM risks in Axum involves enforcing TLS validation, securing cookies, and validating trust boundaries. To fix disabled certificate validation in outbound requests, replace unsafe reqwest configurations with proper TLS settings:
let client = reqwest::Client::builder()
.danger_accept_invalid_certs(false) // Explicitly false (default)
.build()?;
If using a custom CA (e.g., for internal services), load it securely:
let ca = reqwest::Certificate::from_pem(&std::fs::read("internal-ca.pem")?)?;
let client = reqwest::Client::builder()
.add_root_certificate(ca)
.build()?;
For inbound requests, ensure Axum services enforce HTTPS. While Axum itself doesn’t terminate TLS (typically handled by a reverse proxy), you can enforce HSTS via middleware:
use axum::{
extract::Request,
middleware::Next,
response::Response,
};
async fn enforce_hsts(mut req: Request, next: Next) -> Result {
let mut res = next.run(req).await?;
res.headers_mut().insert(
axum::http::header::STRICT_TRANSPORT_SECURITY,
axum::header::HeaderValue::from_static("max-age=31536000; includeSubDomains"),
);
Ok(res)
}
// Apply globally
let app = Router::new()
.route("/api/users", get(get_users))
.layer(middleware::from_fn(enforce_hsts));
Secure cookies by setting the Secure and HttpOnly flags when using Axum’s cookie extractors or response builders:
use axum::response::Redirect;
async fn set_auth_cookie() -> Result {
Ok(Redirect::to("/dashboard")
.append_header(
axum::http::header::SET_COOKIE,
"session_id=abc123; HttpOnly; Secure; SameSite=Strict; Path=/;",
))
}
Finally, never trust headers like X-Forwarded-Proto without validating the incoming connection is from a known proxy. Use Axum’s Extension to pass validated connection state from a trusted middleware layer.
Frequently Asked Questions
Does middleBrick test for SSL/TLS misconfigurations in Axum services?
Can I use middleBrick to scan Axum services running locally with self-signed certificates?
danger_accept_invalid_certs=true is more direct.