HIGH xml external entitiesactixapi keys

Xml External Entities in Actix with Api Keys

Xml External Entities in Actix with Api Keys — how this specific combination creates or exposes the vulnerability

Xml External Entity (XXE) injection occurs when an XML parser processes external entity references within untrusted XML data. In Actix web applications that accept XML payloads—such as file uploads or SOAP-based endpoints—XXE can read local files, trigger SSRF, or cause denial of service. When API keys are handled naively in these flows, the combination exposes secrets through error messages or side channels.

Consider an Actix endpoint that receives an XML document containing an external entity defined with a SYSTEM URI pointing to a file path, and the application also expects an api_key in headers or body. If the XML is parsed with an insecure configuration that resolves external references, an attacker can craft XML like <!ENTITY xxe SYSTEM "file:///etc/secrets/api_keys.yaml">. The parser resolves the entity and returns file contents in error responses or logs, inadvertently leaking API keys. Even when API keys are expected in HTTP headers, verbose error pages or debug endpoints may echo the parsed XML or entity expansions, providing a secondary disclosure path.

In Actix, this often surfaces when developers use permissive XML readers or custom deserializers that do not explicitly disable external entities. For example, if an Actix handler receives XML via web::payload() and forwards it to a parser without disabling DTDs and external references, the server becomes vulnerable. Attackers can also exploit parameter entities in certain XML dialects to exfiltrate data via SSRF, making the API key context part of a broader breach. Because Actix does not inherently sanitize XML input, the framework relies on developer configuration to disable dangerous features. Without these safeguards, an unauthenticated attacker can probe endpoints, submit malicious XML, and harvest API keys from filesystem reads or network-triggered SSRF interactions, turning a configuration oversight into a full compromise of service credentials.

An additional risk emerges when API keys are embedded within XML payloads themselves—such as in SOAP headers or custom XML structures—and the application logs or error responses include the raw XML. XXE-enabled parsers may process DOCTYPE declarations that alter how entities are expanded, causing sensitive API keys to appear in unexpected locations. This is especially dangerous when combined with features like entity expansion bombs (Billion Laughs), which can degrade performance and amplify data exposure through repeated entity resolution tied to key-bearing elements.

To understand the risk in practice, consider an endpoint designed to process configuration XML that includes an api_key element. If the parser resolves external entities, an attacker can supply an XML body like <!DOCTYPE data [ <!ENTITY secret SYSTEM "file:///app/config/secrets.xml"> ]><data><api_key>&secret;</api_key></data>. The server may return the contents of secrets.xml in an error message, exposing the key. Even when API keys are transmitted via headers, verbose stack traces or debug handlers that echo XML content can inadvertently include key material if the parsing logic is misconfigured.

Defending against this requires disabling external entity resolution and DTD processing in XML libraries used by Actix handlers. Developers should prefer streaming or secure parsers that do not resolve external references and should treat API keys as sensitive strings that never appear in error output or logs. MiddleBrick’s scans detect such misconfigurations by analyzing the unauthenticated attack surface, identifying endpoints that process XML and flagging missing entity-expansion protections alongside potential key exposure risks. This helps teams correlate implementation patterns with real-world attack vectors like file read or SSRF induced by insecure XML handling.

Api Keys-Specific Remediation in Actix — concrete code fixes

Remediation focuses on preventing XML external entity processing and ensuring API keys are never exposed through parsing paths. In Actix, configure XML parsing to reject external entities and DTDs, and handle API keys strictly as opaque strings via secure headers or environment variables.

Example of a vulnerable Actix handler that parses XML unsafely:

use actix_web::{web, App, HttpResponse, HttpServer, Responder};
use roxmltree::Document;

async fn process_config(payload: web::Bytes) -> impl Responder {
    // Vulnerable: roxmltree resolves external entities by default in some configurations
    let doc = Document::parse(&String::from_utf8_lossy(&payload)).unwrap();
    let api_key = doc.descendants()
        .find(|n| n.has_tag_name("api_key"))
        .and_then(|n| n.text())
        .unwrap_or("");
    // Use api_key…
    HttpResponse::Ok().body("processed")
}

This approach is risky because the parser may process DOCTYPE declarations and external entities, potentially reading local files or triggering SSRF. An attacker can supply XML with external references to leak filesystem contents that may include API keys.

Secure version using xml-rs with external entity resolution disabled:

use actix_web::{web, App, HttpResponse, HttpServer, Responder};
use std::io::Cursor;
use xml::reader::{EventReader, XmlEvent};

async fn process_config_secure(payload: web::Bytes) -> impl Responder {
    let cursor = Cursor::new(payload.to_vec());
    let parser = EventReader::new(cursor);
    let mut in_api_key = false;
    for e in parser {
        match e {
            Ok(XmlEvent::StartElement { name, .. }) if name.local_name == "api_key" => {
                in_api_key = true;
            }
            Ok(XmlEvent::Characters(text)) if in_api_key => {
                let api_key = text.trim();
                // Use api_key securely, e.g., validate against a vault
                in_api_key = false;
            }
            Ok(XmlEvent::EndElement { name }) if name.local_name == "api_key" => {
                in_api_key = false;
            }
            Err(_) | Ok(XmlEvent::EndDocument { .. }) => break,
            _ => {}
        }
    }
    HttpResponse::Ok().body("processed securely")
}

Key changes:

  • Use an event-based parser like xml-rs that does not resolve external entities by default.
  • Avoid DOM-style parsers that eagerly load document type definitions (DTDs).
  • Never log or echo raw XML that may contain API keys; treat keys as environment-bound secrets and reference them via secure configuration stores.

Additionally, enforce HTTP security headers and transport protections to prevent key leakage in transit or logs. Rotate keys immediately if any exposure is suspected, and validate that no XML parsing path in the application resolves external references.

Frequently Asked Questions

Can XXE in Actix lead to API key theft even if keys are sent in headers?
Yes. If the application parses incoming XML unsafely and logs or echoes parsed content, API keys provided in headers may be reflected in error messages or logs through entity expansion, enabling theft.
Does enabling secure XML parsing in Actix eliminate all key exposure risks?
It significantly reduces XML-based risks, but API keys must also be protected in transit (TLS), at rest (secrets management), and never echoed in error responses or logs to prevent secondary exposure channels.