Yes, disabling DTDs entirely via the disallow-doctype-decl feature breaks internal entity deduplication. This is because internal entities are defined within the block. If the parser is configured to reject the DOCTYPE entirely, it terminates document processing immediately upon encountering the declaration, before it can map or expand the internal entities used for data deduplication.
Balancing Security and Functionality
To support legacy formats that rely on internal entities while preventing External Entity (XXE) attacks, you must move away from a "block all" DTD strategy to a granular restriction model. This allows the parser to process the internal DTD subset while forbidding external references.
Required Configuration Flags
In standard XML-compliant parsers (such as Xerces in Java), the following configuration is required to allow internal entities while strictly blocking external identifiers:
disallow-doctype-decl: Set to false. This allows the DOCTYPE declaration to be processed.
external-general-entities: Set to false. This prevents the resolution of SYSTEM/PUBLIC general entities.
external-parameter-entities: Set to false. This prevents the resolution of entities used within the DTD itself.
Parser Behavior Analysis
When a DTD is present but external entity resolution is explicitly disabled, the parser behaves as follows:
- The parser validates the internal DTD subset and stores internal entity definitions (macros) in memory.
- When it encounters an internal entity reference in the XML body, it replaces it with the defined value (achieving the deduplication/expansion goal).
- If the parser encounters a
SYSTEM or PUBLIC identifier, it will throw an error or return an empty string (depending on the specific implementation), preventing the external network request.
Note: While this configuration protects against XXE, it may leave the application vulnerable to "Billion Laughs" style Denial of Service (DoS) attacks. It is recommended to set entity expansion limits to mitigate this risk.