Null Pointer Dereference in Actix with Mutual Tls
Null Pointer Dereference in Actix with Mutual Tls — how this specific combination creates or exposes the vulnerability
A null pointer dereference in Actix when mutual TLS (mTLS) is enabled typically arises when the application code does not guard against absent or failed peer certificate validation before using a value derived from the TLS session. In an mTLS handshake, the server requests and verifies the client certificate. If the validation step is omitted, skipped, or misconfigured, the application may proceed with a nil or uninitialized certificate object and then attempt operations such as extracting the subject, serial number, or public key. These operations on a nil pointer cause a runtime panic, which in a production service manifests as a 500 response or process crash, and in the context of a security scan is flagged as a null pointer dereference.
With middleBrick’s 12 checks running in parallel, the Authentication and BOLA/IDOR checks interact with mTLS configurations. If the endpoint relies on client certificates for authentication but the handler does not ensure the certificate is present, an unauthenticated or partially authenticated path may be exercised during scanning. The scanner then observes a crash or an error path that indicates missing nil checks, which is reported under Authentication and Input Validation findings. Because the scan is unauthenticated and black-box, it probes the surface that mTLS exposes only when certificates are valid; misconfigured mTLS can therefore create a pathway where missing validation logic is reachable and observable as a null pointer dereference.
Real-world patterns include extracting the Common Name (CN) from the peer certificate to enforce tenant or role-based authorization, as seen in systems that use certificate fields for authorization (similar to issues mapped to OWASP API Top 10 Security Misconfiguration and improper error handling). If the certificate is missing or the extraction returns nil, and the code does not check for that condition, a panic occurs. This is especially relevant when the application parses certificates on every request and uses the extracted data in business logic without verifying existence, effectively turning a missing certificate into a null pointer dereference. The scanner’s Input Validation and Authentication checks highlight such gaps, emphasizing the need to treat the certificate as potentially absent even when mTLS is enforced.
Mutual Tls-Specific Remediation in Actix — concrete code fixes
To remediate null pointer dereference risks in Actix with mTLS, explicitly validate the client certificate on every request and handle the nil case before accessing its fields. Below are concrete, working examples that show how to configure mTLS in Actix and safely extract certificate data.
1. Basic mTLS configuration with certificate validation
Configure the Actix server to require and verify client certificates. This ensures the runtime certificate is non-nil when the handler runs, but you must still guard against missing values in edge cases.
use actix_web::{web, App, HttpServer, Responder, HttpResponse};
use openssl::ssl::{SslAcceptor, SslFiletype, SslMethod};
fn create_ssl_acceptor() -> SslAcceptor {
let mut builder = SslAcceptor::mozilla_intermediate(SslMethod::tls()).unwrap();
builder.set_private_key_file("key.pem", SslFiletype::PEM).unwrap();
builder.set_certificate_chain_file("cert.pem").unwrap();
// Require and verify client certificates
builder.set_verify(openssl::ssl::SslVerifyMode::PEER | openssl::ssl::SslVerifyMode::FAIL_IF_NO_PEER_CERT,
verify_callback);
builder.build()
}
fn verify_callback(verify: &openssl::x509::X509VerifyContext) -> bool {
// You can add additional checks here, e.g., CRL or policy checks
true
}
async fn index(cert: Option>) -> impl Responder {
match cert {
Some(c) => HttpResponse::Ok().body(format!("Subject: {}", subject_from_cert(c))),
None => HttpResponse::BadRequest().body("Client certificate missing"),
}
}
fn subject_from_cert(cert: &openssl::x509::X509) -> String {
cert.subject_name()
.entries_by_nid(openssl::nid::Nid::COMMONNAME)
.next()
.and_then(|entry| entry.data().as_utf8().ok())
.map(|s| s.to_string())
.unwrap_or_else(|| "unknown".to_string())
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
let ssl = create_ssl_acceptor();
HttpServer::new(move || {
App::new()
.wrap(actix_web_httpauth::middleware::HttpAuthentication::default())
.app_data(web::Data::new(ssl.clone()))
.route("/", web::get().to(index))
})
.bind_openssl("127.0.0.1:8443", ssl)?
.run()
.await
}
2. Explicit nil checks before using certificate fields
Even with mTLS configured, always treat certificate extraction as fallible. The following handler demonstrates safe extraction with proper nil checks to prevent null pointer dereference.
async fn secure_endpoint(cert: Option
For production, integrate these patterns with your identity provider’s certificate policy and map findings to compliance frameworks such as OWASP API Top 10 and SOC2. middleBar’s scans can then validate that the endpoint no longer exposes a crash path under mTLS, reducing findings related to Authentication and Input Validation.