JEP 185:限制获取外部 XML 资源
概述
增强 JAXP API,增加限制可用于获取外部资源的网络协议集的功能。
目标
定义标准属性,以限制可用于获取外部资源的网络协议集。新属性应与现有的安全处理功能以及其他现有功能和属性无缝协作。
非目标
此提案的重点在于对外部资源的处理。无意彻底改革现有的安全架构,也无意更改实现中已支持但 API 中未指定的功能和属性。
动机
JAXP 的 安全处理功能 对 XML 处理器设置了资源限制,以应对某些类型的拒绝服务攻击。然而,它并未限制获取外部资源的方式,而这种方式在尝试安全地处理 XML 文档时也非常有用。当前的 JAXP 实现支持可用于强制执行此类限制的特定于实现的属性,但仍然需要一种标准的方式来实现这一点。
描述
JAXP 1.5 增加了三个新的 API 级别的属性,以限制对外部特定命名协议的连接:
javax.xml.XMLConstants.ACCESS_EXTERNAL_DTD
:一个协议列表,通过这些协议可以访问外部 DTD 和外部实体引用。javax.xml.XMLConstants.ACCESS_EXTERNAL_SCHEMA
:一个协议列表,通过这些协议可以解析在import
和include
元素的schemaLocation
属性中指定的外部模式引用。javax.xml.XMLConstants.ACCESS_EXTERNAL_STYLESHEET
:一个协议列表,通过这些协议可以解析在样式表结构(如处理指令、document()
函数、import
元素和include
元素)中指定的外部引用。
它还添加了三个相应的系统属性,为开发者提供在不更改代码的情况下调整设置的能力:
javax.xml.accessExternalDTD
对应于ACCESS_EXTERNAL_DTD
javax.xml.accessExternalSchema
对应于ACCESS_EXTERNAL_SCHEMA
javax.xml.accessExternalStylesheet
对应于ACCESS_EXTERNAL_STYLESHEET
最后,它允许在现有的配置文件 ${java.home}/lib/jaxp.properties
中设置上述属性,从而为所有调用 JDK 或 JRE 定义行为。文件中的条目格式为 property-name=value
,例如:
javax.xml.accessExternalDTD=file,http
属性值
上述任何属性的值都是一个由逗号分隔的协议列表。协议 是 URI 的方案部分,或者是 JAR 协议的情况下,jar
加上由冒号分隔的方案部分。方案的语法为:
scheme = alpha *( alpha | digit | "+" | "-" | "." )
where alpha = a-z and A-Z.
JAR 协议的语法为:
jar[:scheme]
包含关键字 jar
的协议是不区分大小写的。根据 Character.isSpaceChar()
定义,值中的任何空白字符都会被忽略。协议的示例包括 file
、http
和 jar:file
。
默认值:是否默认限制连接是一个实现选择。选项有:
- 空字符串不允许任何访问;
- 特定的协议(如
file
)只允许通过该协议进行访问;或者 - 关键字
all
允许通过所有协议进行访问。
当启用 FEATURE_SECURE_PROCESSING
时,建议实现默认限制外部连接,但这可能会给处理带有外部引用的 XML/XSD/XSL 的应用程序带来问题。
授予所有访问权限:关键字 all
授予使用所有协议的权限。例如,在 jaxp.properties
文件中设置 jdk.xml.accessExternalDTD=all
将允许系统像以前一样工作,且对外部资源的获取方式没有任何限制。
通过 JAXP API 设置属性
JAXP 属性可以通过 JAXP 工厂设置,如下所示:
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setAttribute(name, value);
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser parser = spf.newSAXParser();
parser.setProperty(name, value);
XMLInputFactory xif = XMLInputFactory.newInstance();
xif.setProperty(name, value);
SchemaFactory schemaFactory = SchemaFactory.newInstance(schemaLanguage);
schemaFactory.setProperty(name, value);
TransformerFactory factory = TransformerFactory.newInstance();
factory.setAttribute(name, value);
范围与顺序
javax.xml.XMLConstants#FEATURE_SECURE_PROCESSING
是 XML 处理器(包括 DOM、SAX、Schema 验证、XSLT 和 XPath)的一项必要功能。建议实现将与安全相关的功能和属性与此功能关联起来。当安全功能设置为 true 时,要求实现限制 XML 处理以符合实现限制。当设置为 false 时,则指示实现不受限制地处理 XML。对于 JAXP 1.5 中引入的新属性,建议当安全功能设置为 true 时,实现应限制外部连接;而当设置为 false 时,则允许完全访问。
在 jaxp.properties
文件中指定的属性会影响 JDK 或 JRE 的所有调用,并且将覆盖默认值,或者可能已被 FEATURE_SECURE_PROCESSING
设置的值。
系统属性一旦设置,将仅影响一次调用,并会覆盖默认设置或在 jaxp.properties
中设置的值,或者可能已被 FEATURE_SECURE_PROCESSING
设置的值。
通过 JAXP 工厂或 SAXParser
API 指定的 JAXP 属性将覆盖系统属性、jaxp.properties
文件,以及 FEATURE_SECURE_PROCESSING
的设置。
新的 JAXP 属性在以下情况下对其试图限制的结构将不起作用:
-
当在 SAX 或 DOM 解析器上设置了实体解析器时,在 StAX 解析器上设置了 XML 解析器,或在转换器上设置了
URIResolver
。 -
当通过
SchemaFactory.newSchema()
方法显式创建模式时。 -
当不需要外部资源时。例如,参考实现支持以下特性和属性,可以按照如下设置以指示处理器不加载外部 DTD 或解析外部实体。
http://apache.org/xml/features/disallow-doctype-decl true
http://apache.org/xml/features/nonvalidating/load-external-dtd false
http://xml.org/sax/features/external-general-entities false
http://xml.org/sax/features/external-parameter-entities false
测试
将添加新测试来测试每个场景。还将有一个新的 JAXP TCK 版本。
需要进行重要的测试,以评估是否可以将 JDK 配置为默认限制连接。
风险与假设
JAXP 1.5 规范并未指定这些属性的默认值。由于兼容性影响/风险,JAXP 1.5 将在初始集成时将默认配置设置为不限制连接。
JAXP 1.5 规范要求在显式将 FEATURE_SECURE_PROCESSING 设置为 true 时,设置新属性以限制外部连接。设置了 FEATURE_SECURE_PROCESSING 的应用程序可能会注意到不兼容的行为,因此可能需要设置新的 JAXP 属性以覆盖 FEATURE_SECURE_PROCESSING。
影响
- 其他 JDK 组件:JAX-WS 受到直接影响。JAX-WS 需要使用新属性来确定是否解析外部资源。根据我们的调查以及与其他 JDK 组件负责人的讨论,没有其他组件受到直接影响。
- 兼容性:该规范不会对兼容性产生影响。实现可以自行决定通过将默认值设置为限制或不限制来保持兼容性。
- 国际化/本地化:一些新的错误消息需要被翻译。
- TCK:需要创建一个新版本的 JAXP TCK。