Sanitized finding from Client Q. The original product, endpoint and payload are omitted.
Context
The application accepted XML-like business data through an upload endpoint. The request body was wrapped by the application protocol before server-side parsing.
Finding
Recursive entity expansion and malformed declaration patterns caused disproportionate CPU and memory consumption. Repeated requests produced processing errors and degraded service responsiveness, indicating that parser limits and entity resolution controls were not enforced at the trust boundary.
Technical workflow
The behavior was reproduced with sanitized local fixtures and one request at a time. The endpoint below is intentionally a placeholder:
curl --fail-with-body --max-time 5 \
-H 'Content-Type: application/xml' \
--data-binary @fixtures/bounded.xml \
'https://AUTHORIZED_HOST/api/import'
The application-side parser should use a hardened implementation and reject DTDs or external entities unless the business case explicitly requires them:
from defusedxml.ElementTree import parse
def parse_untrusted_xml(path: str):
# defusedxml blocks common entity-expansion and external-entity classes.
return parse(path)
This is only one layer. The service also needs byte, node, expansion-ratio and wall-clock budgets, plus a request body limit before parsing. During retest I correlated response time with CPU, memory, parser errors and worker restarts.
Impact
An unauthenticated or low-privilege remote caller could consume application resources and interrupt normal processing. The issue also increases operational cost and can amplify the effect of burst traffic.
Remediation
- Disable external entity resolution and DTD processing unless explicitly required.
- Enforce limits on entity depth, expansion ratio, document size and parse time.
- Use a hardened XML parser configuration and reject malformed content before business processing.
- Add rate limiting, request budgets and monitoring for repeated parser failures.
Validation
Re-test with bounded and recursive entity cases while monitoring CPU, memory, latency and process stability. The service should reject unsafe input quickly and consistently.
Expected result: a deterministic 4xx response, no external resolution, no worker restart and a rate-limit/security event for repeated rejected documents.