Pii Leakage in Actix with Mutual Tls
Pii Leakage in Actix with Mutual Tls — how this specific combination creates or exposes the vulnerability
Mutual Transport Layer Security (mTLS) in Actix requires both the server and the client to present valid certificates during the TLS handshake. When mTLS is implemented but application-level handling of identity and authorization is weak, sensitive data can still leak. PII leakage occurs when authenticated endpoints expose personally identifiable information—such as email, name, or ID fields—without sufficient property-level or record-level authorization checks.
In Actix applications, developers may assume that mTLS alone is sufficient to protect data because the connection is encrypted and the client is authenticated. However, mTLS authenticates the client to the server and encrypts the transport; it does not enforce that the authenticated principal is allowed to access a specific resource or field. If the route handler trusts the certificate identity but does not apply checks like BOLA/IDOR or property authorization, an attacker who possesses a valid certificate can request another user’s PII and receive it in the response. This is a common misconfiguration where the presence of mTLS masks an authorization gap.
middleBrick’s checks for Authentication, BOLA/IDOR, and Property Authorization are designed to detect these gaps. For example, a scan might reveal that an endpoint /api/users/{id} returns email and phone number fields without verifying that the requesting certificate maps to the same user ID. Even with mTLS, the unauthenticated attack surface (black-box scanning) can trigger PII exposure findings because the API returns sensitive data without adequate data exposure controls. Input validation issues can compound the risk by allowing malformed requests to bypass business logic, and insecure consumption patterns may retain sensitive payloads in logs or error messages, increasing the chance of accidental disclosure.
Another angle involves LLM/AI Security when an Actix service exposes endpoints that return data used to prompt AI models. If PII is present in responses and those responses are forwarded to an LLM endpoint, system prompt leakage or output scanning may reveal credentials or private information. middleBrick’s LLM/AI checks look for system prompt leakage patterns and output scanning for PII, API keys, and executable code, which is relevant when PII travels through AI pipelines. Proper encryption and strict authorization reduce the likelihood that sensitive data reaches these external endpoints.
Additionally, rate limiting and data exposure controls must be considered. Without per-request authorization and data minimization, an mTLS-protected endpoint can still leak PII through verbose error messages or overly broad responses. Scanning tools like middleBrick can highlight these findings and map them to compliance frameworks such as OWASP API Top 10 and GDPR, emphasizing the need for precise authorization and encryption practices alongside mTLS.
Mutual Tls-Specific Remediation in Actix — concrete code fixes
To reduce PII leakage risk in Actix while using mTLS, enforce strict mapping between the client certificate identity and the data requested. Use the certificate’s subject or a mapped claim to identify the user, then apply record-level checks before returning any PII. Below are concrete code examples demonstrating secure handling with mTLS in Actix.
First, configure Actix to require client certificates and extract identity from the peer certificate:
use actix_web::{web, App, HttpResponse, HttpServer, Responder};
use openssl::ssl::{SslAcceptor, SslFiletype, SslMethod};
use std::sync::Arc;
fn create_ssl_config() -> 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 client certificates for mTLS
builder.set_verify(openssl::ssl::SslVerifyMode::PEER | openssl::ssl::SslVerifyMode::FAIL_IF_NO_PEER_CERT);
builder.check_private_key().unwrap();
builder.build()
}
async fn get_user_profile(
cert_identity: web::ReqData, // extracted from certificate
user_id: web::Path,
) -> impl Responder {
// Ensure the requesting identity matches the requested user_id
if *cert_identity != *user_id {
return HttpResponse::Forbidden().body("Unauthorized access to PII");
}
// Fetch and return only authorized PII
let profile = serde_json::json!({
"user_id": user_id.into_inner(),
"email": "[email protected]",
"name": "Jane Doe"
});
HttpResponse::Ok().json(profile)
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
let ssl_builder = create_ssl_config();
let identity_extractor = web::blocking_op(move |req: &actix_web::HttpRequest| {
// Extract subject common name or a custom extension as identity
req.connection_info().peer_certificate()
.and_then(|cert| {
// Parse the certificate to extract a user identifier
// This is simplified; in production use proper X509 parsing
Some("user-123".to_string())
})
.unwrap_or_else(|| "anonymous".to_string())
});
HttpServer::new(move || {
App::new()
.wrap(identity_extractor.clone())
.app_data(web::ReqData::new(identity_extractor.clone()))
.route("/api/users/{id}", web::get().to(get_user_profile))
})
.bind_openssl("127.0.0.1:8443", ssl_builder)?
.run()
.await
}
This example ensures that the identity extracted from the client certificate is compared against the path parameter before returning PII. It demonstrates data minimization by only including necessary fields and avoiding over-broad responses.
Second, apply property-level authorization for sensitive fields. Even when the user ID matches, restrict which fields are returned based on scope or policy:
async fn get_limited_profile(
cert_identity: web::ReqData,
user_id: web::Path,
) -> impl Responder {
if *cert_identity != *user_id {
return HttpResponse::Forbidden().body("Unauthorized");
}
// Return only non-sensitive fields unless explicitly permitted
let profile = serde_json::json!({
"user_id": user_id.into_inner(),
"name": "Jane Doe"
// email omitted to reduce PII exposure
});
HttpResponse::Ok().json(profile)
}
Combine these patterns with robust certificate validation, revocation checking, and logging to detect anomalies. middleBrick’s scans can verify that such controls are present by checking Authentication, BOLA/IDOR, and Property Authorization findings, ensuring mTLS is complemented by application-level safeguards against PII leakage.
Related CWEs: dataExposure
| CWE ID | Name | Severity |
|---|---|---|
| CWE-200 | Exposure of Sensitive Information | HIGH |
| CWE-209 | Error Information Disclosure | MEDIUM |
| CWE-213 | Exposure of Sensitive Information Due to Incompatible Policies | HIGH |
| CWE-215 | Insertion of Sensitive Information Into Debugging Code | MEDIUM |
| CWE-312 | Cleartext Storage of Sensitive Information | HIGH |
| CWE-359 | Exposure of Private Personal Information (PII) | HIGH |
| CWE-522 | Insufficiently Protected Credentials | CRITICAL |
| CWE-532 | Insertion of Sensitive Information into Log File | MEDIUM |
| CWE-538 | Insertion of Sensitive Information into Externally-Accessible File | HIGH |
| CWE-540 | Inclusion of Sensitive Information in Source Code | HIGH |