glide.xml.entity.whitelist and glide.stax.whitelist_enabled: XML external entity hardening in ServiceNow
ServiceNow security hardening asks you to restrict which external sources XML parsers may load. Two property pairs do that: glide.xml.entity.whitelist.enabled with glide.xml.entity.whitelist, and glide.stax.allow_entity_resolution with glide.stax.whitelist_enabled. This guide explains what each one does, how to find out whether anything on your instance depends on external DTDs, and how to switch the restriction on with a clear note to your integration owners.
glide.xml.entity.whitelist.enabled cannot be switched back. ServiceNow's hardening documentation marks it as a safe harbor property: once it is true, the platform refuses to set it to false again. That is the reason behind the error "Not allowing set of unsafe property value". Do the impact check below before you enable it in production.
Defaults on this page are the values from the out of the box property record or the ServiceNow documentation. Your instance may have different values, so run the check script below before you plan changes.
Spotted a mistake, or know a setting that belongs here? Send me a message and I will update the page.
What the XML entity properties do
An XML document can start with a <!DOCTYPE> declaration that points to an external file, the DTD, or defines entities that load content from a URL. A parser that follows those references can be tricked into calling internal systems or reading data. This is called an XML external entity (XXE) attack.
glide.xml.entity.whitelist.enabled switches on an allowlist check for these external references. glide.xml.entity.whitelist holds the allowed sources as a comma-separated list. ServiceNow recommends the value http://java.sun.com/j2ee/dtds/, the standard Java EE DTD location. Anything else is not needed for the out of the box platform, and every extra value should be reviewed.
The streaming parser behind XMLDocument2 has its own pair. glide.stax.allow_entity_resolution is false by default, so this parser does not resolve entities at all. Only if a customization needs entity resolution and you set it to true does glide.stax.whitelist_enabled (default true) limit it to the hosts in glide.xml.entity.whitelist.
These properties do not decide which XML files you may import, and they do not block normal XML. Record exports, update sets, import set XML and SOAP messages contain no external DTD reference and keep working.
- Run the check script at the end of this page to see the current values.
- If
glide.xml.entity.whitelist.enabledis alreadytrue, nothing is left to do except keep the allowlist short. - Leave
glide.stax.allow_entity_resolutiononfalseunless a documented customization needs it. - Keep
glide.xmlutil.max_entity_expansionat 3000 or lower, the recommended limit against entity expansion denial of service.
| Property | Default | Typical setting | What it does |
|---|---|---|---|
glide.xml.entity.whitelist.enabled |
Not stated | true (cannot be reverted) | Limits XML external entity processing to sources listed in the whitelist, helping protect the instance from XXE attacks. When enabled, XML entities from sources outside the configured allowlist are not processed. |
glide.xml.entity.whitelist |
http://java.sun.com/j2ee/dtds/ |
http://java.sun.com/j2ee/dtds/ | Sets the URLs allowed for XML external entity validation. With the default Java EE DTD URL, XML entity processing is limited to that source when the allowlist is enabled. |
glide.stax.allow_entity_resolution |
false |
false | Disables XML entity resolution and expansion in the XMLDocument2 streaming parser when set to false. With the default value of false, parsed XML excludes internal and external entities, reducing exposure to entity-expansion attacks and resource exhaustion. |
glide.stax.whitelist_enabled |
true |
true | Enables an allowlist for external entities processed by the XML streaming parser. With the default true value, only hosts listed in glide.xml.entity.whitelist can be reached when entity resolution is enabled. |
glide.xmlutil.max_entity_expansion |
Not stated | 3000 or lower | Limits entity expansion in XML parsing performed by GlideXMLUtil. The recommended maximum is 3000; keeping the limit at or below this value reduces exposure to denial-of-service attacks. |
Check whether anything uses external DTDs
Only XML that contains a <!DOCTYPE ... SYSTEM "http..."> or <!ENTITY ... SYSTEM ...> reference to a source outside the allowlist is affected. Look in the XML itself, not in the property: open a sample message or file and search the first lines for DOCTYPE and ENTITY. If neither appears, the allowlist does not touch that integration.
Typical places where third-party XML enters an instance are scripted SOAP and REST services, script includes and business rules that parse XML received from an outbound call, scheduled jobs that fetch XML feeds, and import data sources with format XML. SOAP messages are not allowed to carry a DOCTYPE by the SOAP standard, so plain SOAP integrations are rarely affected.
- List integrations that send or receive XML, from your integration inventory or from REST messages, SOAP messages and data sources on the instance.
- Run the search script below on a sub-production instance. It lists scripts that parse XML or mention a DOCTYPE, so you know where to look.
- For each hit and each XML integration, take one real payload and search it for
DOCTYPEandENTITY. Note the URL afterSYSTEMif there is one. - Add only trusted hosts that you really found to
glide.xml.entity.whitelist, comma separated, next tohttp://java.sun.com/j2ee/dtds/. - Enable
glide.xml.entity.whitelist.enabledon sub-production, run each XML integration and import once, and check the system log for XML parsing errors.
Read-only background script that lists scripts which parse XML or mention a DOCTYPE. Run it in System Definition > Scripts - Background on a sub-production instance.
// Read only: lists scripts that parse XML or reference a DOCTYPE.
var tables = {
'sys_script_include': 'script',
'sys_script': 'script',
'sysauto_script': 'script',
'sys_ws_operation': 'operation_script',
'sys_web_service': 'script',
'sys_processor': 'script'
};
var terms = ['XMLDocument2', 'XMLDocument(', 'GlideXMLUtil', 'DOCTYPE', 'ENTITY'];
for (var t in tables) {
for (var i = 0; i < terms.length; i++) {
var gr = new GlideRecord(t);
if (!gr.isValid()) continue;
gr.addQuery(tables[t], 'CONTAINS', terms[i]);
gr.query();
while (gr.next()) {
gs.print(t + ' | ' + gr.getDisplayValue() + ' | ' + terms[i] + ' | ' + gr.getUniqueValue());
}
}
}| Property | Default | Typical setting | What it does |
|---|---|---|---|
glide.xml.entity.whitelist |
http://java.sun.com/j2ee/dtds/ |
Only trusted hosts you found | Sets the URLs allowed for XML external entity validation. With the default Java EE DTD URL, XML entity processing is limited to that source when the allowlist is enabled. |
glide.soap.require_content_type_xml |
true |
true | Requires SOAP requests to include a non-empty Content-Type header set to text/xml. With the default value of true, requests using a different or missing content type fail validation, which can affect integrations. |
glide.basicauth.required.xml |
true |
true | Requires basic authentication for incoming XML requests. With the default value of true, XML export requests require authorization; setting it to false disables Basic Authentication and can expose instance data. |
glide.basicauth.required.xmloutputprocessor |
true |
true | Requires authorization for incoming XMLOutputProcessor requests that export data to XML via email. With the default value of true, basic authorization is required, helping prevent unauthenticated access to XML export data. |
glide.db.impex.XMLLoader.max.file.size.mb |
100 |
Leave at 100 unless needed | Sets the maximum XML file size allowed for imports, measured in megabytes. Files larger than the configured limit are rejected; the default limit is 100 MB, and raising it can affect performance or cause an instance outage. |
glide.ui.admin_import_xml_roles |
admin |
admin | Sets which roles can use the XML import interface. With the default value of `admin`, access is limited to users with the admin role. |
Enable it and tell your integration owners
Because the change cannot be reverted, roll it out like a release: sub-production first, a short note to integration owners, then production in a planned window.
The note below is a starting point for that email. Replace the parts in brackets.
- Set
glide.xml.entity.whitelisttohttp://java.sun.com/j2ee/dtds/plus any trusted hosts from the impact check. Create the record if it does not exist. - Set
glide.xml.entity.whitelist.enabledtotrueon sub-production and run every XML integration and import once. - Send the impact note to the owners of XML integrations and give them time to test.
- Enable it in production. If an integration later fails with a parsing error, check its payload for a new external DTD source and add that host to the allowlist after a review.
Impact note you can adapt for your team:
Subject: ServiceNow security hardening - XML external entity allowlist
Hi all,
As part of ServiceNow security hardening we will enable the system property
glide.xml.entity.whitelist.enabled on [instance] on [date].
What changes: XML that references an external DTD or entity (a <!DOCTYPE ... SYSTEM "http...">
or <!ENTITY ... SYSTEM ...> line) is only processed if the source is on our allowlist
(glide.xml.entity.whitelist). Today the allowlist contains http://java.sun.com/j2ee/dtds/
[and: other hosts].
What does not change: normal XML without such references, SOAP messages, record
exports, update sets and XML imports keep working.
What we need from you: please check whether XML your integration sends to or receives
from ServiceNow contains a DOCTYPE or ENTITY reference to an external URL, and tell us
the URL by [date]. We tested on [sub-production instance] on [date] with [result].
Note: this setting cannot be switched back once enabled.
Thanks,
[name]| Property | Default | Typical setting | What it does |
|---|---|---|---|
glide.xml.entity.whitelist.enabled |
Not stated | true | Limits XML external entity processing to sources listed in the whitelist, helping protect the instance from XXE attacks. When enabled, XML entities from sources outside the configured allowlist are not processed. |
glide.xml.entity.whitelist |
http://java.sun.com/j2ee/dtds/ |
http://java.sun.com/j2ee/dtds/ | Sets the URLs allowed for XML external entity validation. With the default Java EE DTD URL, XML entity processing is limited to that source when the allowlist is enabled. |
Check your instance
Paste this read-only background script into System Definition > Scripts - Background on a sub-production instance. It prints the current value of every property in this guide. A property without a record runs on its platform default. You can also open sys_properties.list and filter by name.
// Read only: prints the current value of every property in this guide.
// Run in System Definition > Scripts - Background.
var names = [
'glide.xml.entity.whitelist.enabled',
'glide.xml.entity.whitelist',
'glide.stax.allow_entity_resolution',
'glide.stax.whitelist_enabled',
'glide.xmlutil.max_entity_expansion',
'glide.soap.require_content_type_xml',
'glide.basicauth.required.xml',
'glide.basicauth.required.xmloutputprocessor',
'glide.db.impex.XMLLoader.max.file.size.mb',
'glide.ui.admin_import_xml_roles'
];
var found = {};
var gr = new GlideRecord('sys_properties');
gr.addQuery('name', 'IN', names.join(','));
gr.query();
while (gr.next()) {
found[gr.getValue('name')] = gr.getValue('value');
}
for (var i = 0; i < names.length; i++) {
var n = names[i];
gs.print(n + ' = ' + (found.hasOwnProperty(n) ? found[n] : '(no record on this instance, platform default applies)'));
}FAQ
What value should glide.xml.entity.whitelist have?
ServiceNow recommends http://java.sun.com/j2ee/dtds/, the standard Java EE DTD location. Add other hosts only if an integration really references an external DTD there, and review each one.
What is the difference between glide.xml.entity.whitelist.enabled and glide.stax.whitelist_enabled?
glide.xml.entity.whitelist.enabled turns on the allowlist check for external XML references in general. glide.stax.whitelist_enabled applies to the XMLDocument2 streaming parser and only matters if glide.stax.allow_entity_resolution is true. Both read the allowed hosts from glide.xml.entity.whitelist.
Does the XML allowlist block XML imports or update sets?
No. Record exports, update sets and normal XML imports contain no external DTD reference, so they are not affected. Only XML that points to an external DTD or entity outside the allowlist is refused.
Why can't I set glide.xml.entity.whitelist.enabled back to false?
It is a safe harbor property. Once it is true, the platform refuses to set it to false and shows "Not allowing set of unsafe property value". That is intended, so test before you enable it.
How do I know if my XML uses an external DTD?
Open a real payload and look at the first lines. A line starting with <!DOCTYPE that contains SYSTEM and a URL, or an <!ENTITY ... SYSTEM ...> line, is an external reference. If neither is there, the allowlist does not affect it.
Will enabling the allowlist break SOAP integrations?
Very unlikely. The SOAP standard does not allow a DOCTYPE in a SOAP message, so standard SOAP traffic has nothing for the allowlist to block. Test once on sub-production to be sure.
What happens if glide.stax.whitelist_enabled does not exist on my instance?
The platform uses its default, which is true. With glide.stax.allow_entity_resolution at its default of false, the streaming parser does not resolve entities at all, so a missing record is not a risk.
Related
Something wrong or missing on this page? Tell me and I will fix it.
Send feedback