跳到主要内容

JEP 185:限制获取外部 XML 资源

QWen Max 中英对照

概述

增强 JAXP API,增加限制可用于获取外部资源的网络协议集的功能。

目标

定义标准属性,以限制可用于获取外部资源的网络协议集。新属性应与现有的安全处理功能以及其他现有功能和属性无缝协作。

非目标

此提案的重点在于对外部资源的处理。无意彻底改革现有的安全架构,也无意更改实现中已支持但 API 中未指定的功能和属性。

动机

JAXP 的 安全处理功能 对 XML 处理器设置了资源限制,以应对某些类型的拒绝服务攻击。然而,它并未限制获取外部资源的方式,而这种方式在尝试安全地处理 XML 文档时也非常有用。当前的 JAXP 实现支持可用于强制执行此类限制的特定于实现的属性,但仍然需要一种标准的方式来实现这一点。

描述

JAXP 1.5 增加了三个新的 API 级别的属性,以限制对外部特定命名协议的连接:

  • javax.xml.XMLConstants.ACCESS_EXTERNAL_DTD:一个协议列表,通过这些协议可以访问外部 DTD 和外部实体引用。
  • javax.xml.XMLConstants.ACCESS_EXTERNAL_SCHEMA:一个协议列表,通过这些协议可以解析在 importinclude 元素的 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() 定义,值中的任何空白字符都会被忽略。协议的示例包括 filehttpjar: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。