Reduce the risk of XML attacks by checking the structure of XML payloads. This validates maximum complexity (depth of the tree), maximum size of elements and attributes.
Configuration Reference
This plugin is compatible with DB-less mode.
In DB-less mode, you configure Kong Gateway declaratively. Therefore, the Admin API is mostly read-only. The only tasks it can perform are all related to handling the declarative config, including:
- Setting a target's health status in the load balancer
- Validating configurations against schemas
- Uploading the declarative configuration using the
/config
endpoint
Example plugin configuration
Parameters
Here's a list of all the parameters which can be used in this plugin's configuration:
Form Parameter | Description |
---|---|
name
required Type: string |
The name of the plugin, in this case xml-threat-protection . |
service.name or service.id
Type: string |
The name or ID of the service the plugin targets.
Set one of these parameters if adding the plugin to a service through the top-level /plugins endpoint.
Not required if using /services/SERVICE_NAME|SERVICE_ID/plugins . |
route.name or route.id
Type: string |
The name or ID of the route the plugin targets.
Set one of these parameters if adding the plugin to a route through the top-level /plugins endpoint.
Not required if using /routes/ROUTE_NAME|ROUTE_ID/plugins . |
enabled
Type: boolean Default value: true |
Whether this plugin will be applied. |
config.checked_content_types
required Type: array of strings Default value: [“application/xml”]
|
A list of Content-Type values with payloads that must be validated. |
config.allowed_content_types
required Type: array of strings Default value: []
|
A list of Content-Type values with payloads that are allowed, but aren’t validated.
For example, if the API also accepts JSON, you can add |
config.allow_dtd
required Type: boolean Default value: false
|
Indicates whether an XML Document Type Definition (DTD) section is allowed. |
config.namespace_aware
required Type: boolean Default value: true
|
If not parsing namespace aware, all prefixes and namespace attributes will be counted as regular attributes and element names, and validated as such. |
config.max_depth
required Type: number Default value: 50
|
Maximum depth of tags. Child elements such as Text or Comments are not counted as another level. |
config.max_children
required Type: number Default value: 100
|
Maximum number of children allowed (Element, Text, Comment, ProcessingInstruction, CDATASection).
Note: Adjacent text and CDATA sections are counted as one. For example, |
config.max_attributes
required Type: number Default value: 100
|
Maximum number of attributes allowed on a tag, including default ones. Note: If namespace-aware parsing is disabled, then the namespaces definitions are counted as attributes. |
config.max_namespaces
semi-optional Type: number Default value: 20
|
Maximum number of namespaces defined on a tag. This value is required if parsing is namespace-aware. |
config.document
required Type: number Default value: 10485760 (10 mb)
|
Maximum size of the entire document. |
config.buffer
required Type: number Default value: 1048576 (1 mb)
|
Maximum size of the unparsed buffer (see below). |
config.comment
required Type: number Default value: 1024 (1 kb)
|
Maximum size of comments. |
config.localname
required Type: number Default value: 1024 (1 kb)
|
Maximum size of the localname. This applies to tags and attributes. Note: If parsing isn’t namespace-aware, this limit counts against the full name (prefix + localname). |
config.prefix
semi-optional Type: number Default value: 1024 (1 kb)
|
Maximum size of the prefix. This applies to tags and attributes. This value is required if parsing is namespace-aware. |
config.namespaceuri
semi-optional Type: number Default value: 1024 (1 kb)
|
Maximum size of the namespace URI. This value is required if parsing is namespace-aware. |
config.attribute
required Type: number Default value: 1024 (1 kb)
|
Maximum size of the attribute value. |
config.text
required Type: number Default value: 1024 (1 kb)
|
Maximum text inside tags (counted over all adjacent text/CDATA elements combined). |
config.pitarget
required Type: number Default value: 1024 (1 kb)
|
Maximum size of processing instruction targets. |
config.pidata
required Type: number Default value: 1024 (1 kb)
|
Maximum size of processing instruction data. |
config.entityname
required Type: number Default value: 1024 (1 kb)
|
Maximum size of entity names in EntityDecl. |
config.entity
required Type: number Default value: 1024 (1 kb)
|
Maximum size of entity values in EntityDecl. |
config.entityproperty
required Type: number Default value: 1024 (1 kb)
|
Maximum size of systemId, publicId, or notationName in EntityDecl. |
config.bla_max_amplification
required Type: number Default value: 100
|
Sets the maximum allowed amplification. This protects against the Billion Laughs Attack. |
config.bla_threshold
required Type: number Default value: 8388608 (8 mb)
|
Sets the threshold after which the protection starts. This protects against the Billion Laughs Attack. |
Usage
The XML Threat Protection plugin protects against excessive complex or large payloads. The checks are implemented using a streaming SAX parser. This ensures that even very large payloads can be validated safely.
Using the unparsed buffer setting
Due to the way SAX parsers work, a bad input needs to be parsed first before a SAX callback allows the plugin to check its size. This is even a bigger problem for elements with attributes because the element name with all its attributes are returned in a single callback. So passing in 100 attributes, each with a 1GB value, could still overwhelm the system and run out of resources.
To mitigate this, the unparsed buffer size setting is used. The buffer is counted from the last byte parsed (for example, the closing tag on the previous element), to the last byte passed into the parser. If the buffer size is greater than the allowed value, the request is rejected.
For example, if the following limits are defined:
- localname: 1 KB
- attribute value: 10 KB
- max attributes: 10 If a request comes in with an element with 100 attributes, each 1 GB, the parser reads the payload, and tries to fire a callback for a new element of at least 100 GB in size, since it also contains all attributes. This fails because the system runs out of resources.
You can mitigate this by using the unparsed buffer size:
- The maximum expected size is 111KB (one element name (1 KB), 10 attribute names (10 KB), 10 attribute values (100 KB)).
- Set the maximum unparsed buffer to 113 KB, adding 2 KB for overhead and XML whitespace.
- When validating the element with 100 one GB attributes again, the plugin now detects that the unparsed buffer exceeds the expected maximum of 113 KB and rejects the request before parsing the entire 100 GB body.
Changelog
Kong Gateway 3.1.x
- Initial release.