Pii Leakage in Actix with Basic Auth
Pii Leakage in Actix with Basic Auth — how this specific combination creates or exposes the vulnerability
Actix-web is a popular Rust framework for building HTTP services. When Basic Authentication is used without additional protections, PII can be exposed in ways that are not immediately obvious. Basic Auth sends credentials in an Authorization header encoded as Base64, which is easily reversible. If responses containing user data do not explicitly strip or redact PII, and if logs or error messages inadvertently include the Authorization header or user identity, sensitive information can be exposed.
Consider an Actix endpoint that returns a user profile. If the handler includes the authenticated user’s identity in the response body and that response is cached by an intermediary (e.g., a CDN or proxy), PII can be leaked to unauthorized parties. Another vector is verbose error messages: Actix default error handlers may include request details in responses. If an attacker can trigger error paths while sending a forged Basic Auth header, information about users or internal structures may be reflected in the error output. Additionally, if instrumentation or logging middleware captures headers for debugging, the Base64-encoded credentials and associated user identifiers may be stored in logs, creating a long-term leakage risk.
middleBrick’s LLM/AI Security checks are not applicable here, but its standard security scans detect indicators that PII could be exposed through these channels. The scanner evaluates whether authentication is enforced, whether responses contain sensitive data without appropriate controls, and whether the API exposes data unnecessarily. Findings include indications that PII might be present in responses or logs when authentication is weak or improperly scoped. The scanner also checks whether the OpenAPI/Swagger specification accurately reflects which endpoints return user-specific data and whether protections like authentication are documented and enforced consistently.
During a scan, middleBrick tests unauthenticated endpoints and analyzes spec definitions alongside runtime behavior. Even without credentials, it can identify endpoints that return personal data and flag missing safeguards such as output filtering or strict authentication scopes. This helps developers understand where PII leakage can occur when Basic Auth is used in Actix services and guides them toward implementing safer patterns.
Basic Auth-Specific Remediation in Actix — concrete code fixes
To reduce PII leakage risk in Actix when using Basic Authentication, apply strict controls around authentication, response content, and logging. Always use HTTPS to protect credentials in transit. Ensure that authentication is required for sensitive endpoints and that responses exclude or mask PII unless explicitly required. Avoid logging Authorization headers or user identifiers in plain form.
Below are concrete Actix code examples that demonstrate secure handling of Basic Auth.
Secure Basic Auth middleware with role-based access control
This example shows how to implement Basic Auth in Actix while enforcing role checks and avoiding logging of credentials.
use actix_web::{web, App, HttpResponse, HttpServer, Responder, dev::ServiceRequest, Error};
use actix_web::http::header::AUTHORIZATION;
use actix_web::middleware::Logger;
use std::sync::Arc;
struct AppState {
valid_users: std::collections::HashMap)>, // username -> (password, roles)
}
fn basic_auth_middleware(
req: ServiceRequest,
credentials: (&str, &str),
) -> Result {
let (user, pass) = credentials;
let state = req.app_data::>>().unwrap();
match state.valid_users.get(user) {
Some((stored_pass, roles)) if stored_pass == pass => {
// Attach user and roles to request extensions for downstream handlers
req.extensions_mut().insert(user.to_string());
req.extensions_mut().insert(roles.clone());
Ok(req)
}
_ => Err((actix_web::error::ErrorUnauthorized("Invalid credentials"), req)),
}
}
async fn profile_handler(req: ServiceRequest) -> impl Responder {
// Retrieve identity from extensions, not from logging or echoing headers
if let Some(user) = req.extensions().get::() {
// Return only necessary, non-PII-safe data; avoid returning emails or IDs unless strictly required
HttpResponse::Ok().json(serde_json::json!({ "username": user, "role": "user" }))
} else {
HttpResponse::Unauthorized().finish()
}
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
let mut users = std::collections::HashMap::new();
users.insert("alice".to_string(), ("s3cret".to_string(), vec!["user".to_string()]));
let app_state = web::Data::new(Arc::new(AppState { valid_users: users }));
HttpServer::new(move || {
App::new()
.app_data(app_state.clone())
.wrap(
Logger::default()
.exclude_regex(r#"/profile"#) // exclude sensitive endpoints from detailed logs
.log_target("api_access"),
)
.route("/profile", web::get().to(profile_handler))
.wrap_fn(|req, srv| {
let auth_header = req.headers().get(AUTHORIZATION);
// Basic Auth parsing and validation
if let Some(header) = auth_header.and_then(|h| h.to_str().ok()) {
if let Some(credentials) = header.strip_prefix("Basic ") {
let decoded = base64::decode(credentials).ok()?;
let cred_str = String::from_utf8(decoded).ok()?;
let parts: Vec<&str> = cred_str.splitn(2, ':').collect();
if parts.len() == 2 {
return Ok(basic_auth_middleware(req, (parts[0], parts[1]))?);
}
}
}
Err(actix_web::error::ErrorUnauthorized("Missing or invalid auth"))
})
})
.bind("127.0.0.1:8080")?
.run()
.await
}
This pattern avoids logging credentials by excluding sensitive routes from detailed logging and ensures that handlers only return minimal, non-PII data. It also demonstrates how to parse and validate Basic Auth manually to enforce custom role checks before reaching business logic.
Additionally, configure Actix to use secure error handlers that do not leak stack traces or request headers. Avoid returning the full Authorization header in any response or error body. When integrating with middleBrick’s CLI (middlebrick scan <url>) or GitHub Action, you can validate that these controls are reflected in your API’s observable behavior and that no PII appears in responses even when authentication is provided.
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 |