HIGH pii leakageactixmutual tls

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": "user@example.com",
        "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 IDNameSeverity
CWE-200Exposure of Sensitive Information HIGH
CWE-209Error Information Disclosure MEDIUM
CWE-213Exposure of Sensitive Information Due to Incompatible Policies HIGH
CWE-215Insertion of Sensitive Information Into Debugging Code MEDIUM
CWE-312Cleartext Storage of Sensitive Information HIGH
CWE-359Exposure of Private Personal Information (PII) HIGH
CWE-522Insufficiently Protected Credentials CRITICAL
CWE-532Insertion of Sensitive Information into Log File MEDIUM
CWE-538Insertion of Sensitive Information into Externally-Accessible File HIGH
CWE-540Inclusion of Sensitive Information in Source Code HIGH

Frequently Asked Questions

Does mTLS alone prevent PII leakage in Actix APIs?
No. mTLS encrypts traffic and authenticates clients, but it does not enforce record-level or field-level authorization. Without proper checks, a client with a valid certificate can still access another user’s PII.
How can I verify my Actix API’s handling of mTLS and PII during scans?
Use middleBrick’s scan to test Authentication, BOLA/IDOR, and Property Authorization. The scanner validates that endpoints do not expose PII without matching identity checks, even when mTLS is in place.