Pii Leakage in Actix
How PII Leakage Manifests in Actix
PII leakage in Actix applications typically occurs through several Actix-specific code patterns and middleware configurations. The most common manifestation is through Actix's extraction system, where request data is automatically parsed and made available to handlers. When developers use extractors like Query, Json, or Path without proper validation, sensitive data can be inadvertently logged or exposed through error responses.
Consider this Actix pattern that leads to PII leakage:
use actix_web::{web, App, HttpServer, Responder};
async fn login(
user: web::Json
) -> impl Responder {
// UserLogin contains email and password
// If this handler errors, Actix's default error handler may log the entire request body
// including plaintext passwords
HttpResponse::Ok().finish()
}
#[derive(serde::Deserialize)]
struct UserLogin {
email: String,
password: String, // Never log passwords!
}
Another Actix-specific vulnerability occurs with the Logger middleware. By default, it logs request bodies and query parameters, which can contain PII:
use actix_web::{middleware::Logger, App, HttpServer};
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new()
.wrap(Logger::default()) // Logs everything by default!
.service(login)
})
.bind("127.0.0.1:8080")?
.run()
.await
}
Actix's error handling also contributes to PII exposure. When deserialization fails, Actix may include the raw request body in error responses, potentially exposing sensitive data to clients:
async fn sensitive_data(
path: web::Path<(String, String)>
) -> impl Responder {
// If path extraction fails, Actix returns 400 with body details
// This could expose the attempted values
HttpResponse::Ok().body("Processed")
}
Actix-Specific Detection
Detecting PII leakage in Actix applications requires examining both the code structure and runtime behavior. Start by scanning your Actix application with middleBrick, which specifically tests for PII exposure patterns in Rust web applications:
npx middlebrick scan https://your-actix-app.com
middleBrick's PII detection for Actix applications includes:
- Pattern matching for common PII fields in request handlers (email, password, ssn, credit_card)
- Analysis of middleware configurations that may log sensitive data
- Testing for error responses that expose request bodies
- Checking for default Actix configurations that enable verbose logging
Manual detection should focus on these Actix-specific areas:
// Check for these risky patterns in your codebase:
// 1. Default Logger usage
App::new().wrap(Logger::default())
// 2. Unvalidated extractors
async fn handler(
query: web::Query
) -> impl Responder
// 3. Error responses with request details
async fn handler(
path: web::Path<(String, String)>
) -> impl Responder
// 4. Debug logging of structs containing PII
log::debug!("{:?}", user_data);
middleBrick also tests for Actix-specific LLM security issues if your application uses AI features, checking for system prompt leakage and prompt injection vulnerabilities that could expose PII through AI interactions.
Actix-Specific Remediation
Remediating PII leakage in Actix requires leveraging Actix's built-in features and Rust's type system. Here are Actix-specific fixes:
// 1. Custom Logger that excludes sensitive data
use actix_web::{middleware::Logger, web, App, HttpServer};
use log::Level;
struct SafeLogger;
impl actix_web::middleware::Middleware for SafeLogger {
fn start(&self, req: &actix_web::dev::ServiceRequest) -> actix_web::Result<actix_web::middleware::Started> {
// Log only method, path, and status - exclude body/query
Ok(actix_web::middleware::Started::Done)
}
}
// 2. Custom error handler that scrubs PII
use actix_web::{error, dev::HttpResponseBuilder, http::StatusCode, HttpResponse};
#[derive(Debug)]
struct PiiScrubError;
impl error::ResponseError for PiiScrubError {
fn error_response(&self) -> HttpResponse {
HttpResponseBuilder::new(StatusCode::INTERNAL_SERVER_ERROR)
.body("An error occurred") // No PII in response
}
}
// 3. Safe extractor with validation
use actix_web::web;
use serde::Deserialize;
#[derive(Deserialize)]
struct SafeLogin {
email: String,
#[serde(skip_deserializing)]
password: String, // Don't deserialize password at all
}
async fn safe_login(
web::Json(payload): web::Json<SafeLogin>
) -> impl Responder {
// Password was never deserialized, eliminating leakage risk
HttpResponse::Ok().finish()
}
// 4. Sanitized logging
use log::info;
async fn login(
web::Json(payload): web::Json<UserLogin>
) -> impl Responder {
// Log only non-sensitive fields
info!("Login attempt for email: {}", payload.email);
// Never log payload.password
HttpResponse::Ok().finish()
}
#[derive(Deserialize)]
struct UserLogin {
email: String,
password: String,
}
For Actix applications using async-std or tokio, ensure logging configurations are properly scoped to prevent thread-local PII exposure:
use actix_web::{middleware, App, HttpServer};
#[actix_web::main]
async fn main() -> std::io::Result<()> {
std::env::set_var("RUST_LOG", "actix_web=info,myapp=warn");
HttpServer::new(|| {
App::new()
.wrap(middleware::NormalizePath::default())
.wrap(SafeLogger) // Your custom safe logger
.service(login)
})
.bind("127.0.0.1:8080")?
.run()
.await
}
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 |