Data Exposure in Actix with Api Keys
Data Exposure in Actix with Api Keys
Data exposure occurs when API keys are handled in an Actix web service in ways that allow unintended disclosure. In Actix applications, common causes include logging key values, embedding keys in URLs or HTML, returning them in JSON responses, or failing to restrict transport and storage scopes. These patterns can surface during unauthenticated scans because the API may leak keys through error messages, debug endpoints, or overly verbose responses.
An Actix service that authenticates with bearer-style API keys in headers can inadvertently expose those keys if middleware or handlers write the full header to logs or include it in trace output. For example, echoing the Authorization header value into an HTTP response body or a development-mode log line allows a scanner to harvest valid keys. Even in production, structured logging that captures the full header increases the risk of key exfiltration if logs are centralized without appropriate masking.
Another exposure vector involves deserialization and response serialization. If an Actix handler deserializes a request containing an API key and then serializes user-controlled structures back to the client without filtering, keys can leak through JSON or form-encoded payloads. This often happens when developers return a model that contains a field mapped to the key, or when they merge request metadata into a response object. In OpenAPI-first workflows, mismatched definitions can cause runtime schemas to include key-bearing fields that should remain server-side only.
Transport and storage misconfigurations amplify exposure. An Actix service that accepts keys over non-TLS transports, or that stores them in insecure caches or configuration files, increases the likelihood of interception or accidental dumps. Scanners that test for missing HTTPS enforcement and inspect response headers can identify endpoints that do not enforce strict transport security, enabling passive key capture on shared networks.
To contextualize these risks within a broader assessment, middleBrick runs 12 security checks in parallel, including Data Exposure and Authentication. The scanner cross-references findings with an OpenAPI/Swagger spec (2.0, 3.0, 3.1) with full $ref resolution to validate whether key-bearing structures are documented and whether runtime behavior matches the declared schema. This helps surface discrepancies such as undocumented key reflection or overly permissive schemas that can lead to data exposure.
Api Keys-Specific Remediation in Actix
Remediation focuses on preventing keys from appearing in logs, responses, and URLs, and enforcing strict transport and validation rules. Below are concrete Actix patterns that reduce exposure risk.
1. Avoid logging or echoing API keys
Never log full keys and ensure middleware does not propagate them into response bodies. Use field redaction in structured logging.
use actix_web::{web, HttpRequest, HttpResponse, Result};
use log::info;
// Safe: log presence without exposing the key
async fn handle_request(req: HttpRequest) -> Result {
if let Some(key) = req.headers().get("Authorization") {
let key_str = key.to_str().unwrap_or("");
// Redact key; do not log the raw value
let masked = if key_str.len() > 4 {
format!("****-****-****-{}", &key_str[key_str.len() - 4..])
} else {
"****".to_string()
};
info!(authorization = masked.as_str(), "request received");
}
Ok(HttpResponse::Ok().finish())
}
2. Filter sensitive fields from responses
Ensure response serializers exclude key-bearing fields. With Actix and serde, use skip_serializing or flatten selectively.
use serde::Serialize;
#[derive(Serialize)]
struct PublicProfile {
user_id: u64,
username: String,
#[serde(skip_serializing)]
api_key: String, // never serialized
}
async fn profile() -> HttpResponse {
let data = PublicProfile {
user_id: 1,
username: "alice".into(),
api_key: "super-secret-key".into(),
};
HttpResponse::Ok().json(data)
}
3. Enforce HTTPS and strict transport security
Require TLS and avoid key transmission over cleartext connections. Use Actix middleware to redirect or reject non-HTTPS requests in production-like environments.
use actix_web::{web, App, HttpServer, middleware::Logger};
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new()
.wrap(Logger::default())
// In production, add a TLS connector and reject non-TLS
.service(web::resource("/api").to(|| async { "secure" }))
})
.bind_rustls(
"0.0.0.0:8443",
rustls::ServerConfig::builder()
.with_safe_defaults()
.with_no_client_auth()
.with_single_cert(vec![], rustls::NoClientAuth::new())
.unwrap(),
)?
.await
}
4. Validate and scope keys in requests
Validate key format and avoid passing them through generic parameters. Prefer header-based delivery and avoid query strings.
use actix_web::{web, HttpRequest, Result};
async fn validate_key(req: HttpRequest) -> Result<&'static str> {
const VALID_PREFIX: &str; // placeholder for policy-driven validation
match req.headers().get("X-API-Key") {
Some(h) if h.len() == 64 => Ok("valid"),
Some(_) => Err(actix_web::error::ErrorBadRequest("invalid key")),
None => Err(actix_web::error::ErrorUnauthorized("missing key")),
}
}
5. Use environment-based configuration, not hardcoded keys
Load secrets at runtime and avoid committing them to source or spec examples.
use std::env;
fn get_api_key() -> String {
env::var("API_KEY").unwrap_or_else(|_| "placeholder".into())
}
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 |