跳到主要内容

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:可以解析由和元素schemaLocation的属性指定的外部模式引用的协议列表。import``include

  • 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授予使用所有协议的权限。例如,文件jdk.xml.accessExternalDTD=all中的设置jaxp.properties将允许系统像以前一样工作,而不会限制如何获取外部资源。

通过 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、模式验证、XSLT 和 XPath)所需的功能。建议实现将安全相关的功能和属性与该功能相关联。当安全功能设置为 true 时,它要求实现限制 XML 处理以符合实现限制。当它为 false 时,它指示实现不受限制地处理 XML。对于 JAXP 1.5 中引入的新属性,建议当安全功能设置为 true 时,实现限制外部连接,当设置为 false 时,允许完全访问。

文件中指定的属性jaxp.properties会影响 JDK 或 JRE 的所有调用,并将覆盖默认值或可能已由FEATURE_SECURE_PROCESSING.

系统属性设置后,将仅影响一次调用,并将覆盖默认设置或 中设置的设置jaxp.properties,或可能已由 中设置的设置FEATURE_SECURE_PROCESSING

通过 JAXP 工厂或SAXParserAPI 指定的 JAXP 属性将覆盖系统属性、jaxp.properties文件以及FEATURE_SECURE_PROCESSING.

新的 JAXP 属性在以下情况下不会对其尝试限制的构造产生影响:

  • 当在 SAX 或 DOM 解析器上设置实体解析器时,在 StAX 解析器上设置 XML 解析器,或者URIResolver在转换器上设置 a。

  • 当通过该方法显式创建模式时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 组件所有者的调查和讨论,没有其他组件受到直接影响。

  • 兼容性:该规范没有兼容性影响。由实现来决定是否通过将默认值设置为限制或不限制来保持兼容性。

  • I18n/L10n:需要翻译一些新的错误消息。

  • TCK:需要创建新版本的 JAXP TCK。