【问题标题】:XML validation using XSD in java在 Java 中使用 XSD 进行 XML 验证
【发布时间】:2011-01-01 15:01:07
【问题描述】:

我有以下课程:

package com.somedir.someotherdir;

import java.util.logging.Level;
import java.util.logging.Logger;

import javax.xml.XMLConstants;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;

public class SchemaValidator
{
 private static Logger _logger = Logger.getLogger(SchemaValidator.class.getName());

 /**
  * @param file - the relative path to and the name of the XML file to be validated
  * @return true if validation succeeded, false otherwise
  */
 public final static boolean validateXML(String file)
 {
  try
  {
   SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
   Schema schema = factory.newSchema();
   Validator validator = schema.newValidator();
   validator.validate(new StreamSource(file));
   return true;
  }
  catch (Exception e)
  {
   _logger.log(Level.WARNING, "SchemaValidator: failed validating " + file + ". Reason: " + e.getMessage(), e);
   return false;
  }
 }
}

我想知道我到底应该使用schema.newValidator("dir/to/schema.xsd") 还是当前版本可以?我读到有一些 DoS 漏洞,也许有人可以提供更多信息?另外,路径必须是绝对的还是相对的?
大多数要验证的 XML 都有自己的 XSD,所以我想阅读 XML 本身中提到的架构 (xs:noNamespaceSchemaLocation="schemaname.xsd")。
仅在启动或手动重新加载(服务器软件)期间进行验证。

【问题讨论】:

  • 你们能不能停止重新格式化我的代码并给出一些答案??
  • “大多数要验证的 XML 都有自己的 XSD,所以我想阅读 XML 本身中提到的架构”也许这是相关的:stackoverflow.com/questions/2829105/…
  • 可能相关,但不是我需要的。我只需要验证它,我在问这种方式是否好或是否需要任何修复。您的代码需要更多的类/方法,而这并不是我想要的。
  • @Alberto - “正确”是一个主观术语。我有我的代码风格,我不喜欢别人出于任何原因触碰它。此外,这在这个问题上并不重要。

标签: java xml xsd xsd-validation


【解决方案1】:

您真的是指 XML DTD DOS 攻击吗?如果有的话,网上有一些不错的文章:

XML 拒绝服务攻击和防御http://msdn.microsoft.com/en-us/magazine/ee335713.aspx

来自IBM developerWorks. "Tip: Configure SAX parsers for secure processing"

实体解析在 XML 中打开了许多潜在的安全漏洞。[...]
- 托管外部 DTD 的站点可以记录通信。 [...]
- 托管 DTD 的站点可能会减慢解析速度 [...] 它还可以通过提供格式错误的 DTD 来完全停止解析。
- 如果远程站点更改了DTD,它可以使用默认属性值将新内容注入到文档中[...]它可以通过重新定义实体引用来更改文档的内容。

我不确定它是否可以直接应用于您的程序,它可以为进一步调查提供一些线索

【讨论】:

【解决方案2】:

正如我所解释的,SchemaFactory.newSchema() 返回的javax.xml.validation.Schema 对象将尝试获取 xml/xsd 文件中引用的其他模式,以按照相应的xsi:schemaLocation 属性中的指示进行验证。这意味着:

  1. 如果您的架构引用托管在互联网上的架构,Schema 对象将在运行时尝试获取它们。据我所知,默认的 Schema 实现不会缓存这些模式。 W3C already reported 关于不良编码实践导致他们网站事实上的 DDoS(每天高达 1.3 亿次 dtd 请求!)。
  2. 如果您要验证外部不受控制的 xml 文件,那么您还会面临 Schema 试图从“可能是恶意的”xml 源中获取其他模式的风险。

更多邪恶攻击媒介,请查看sign's previous answer

为避免这种陷阱,您可以将所有外部资源存储在本地,并使用SchemaFactory.setResourceResolver 方法指示Schema 如何获取它们。

【讨论】:

  • necro-post 的方法...我对我的 XML 没有这种顾虑,因为它们唯一的 XSD 位于它们旁边的文件夹中,并且是我编写的。
  • 对于 necro-post,您的意思是您的原始帖子已经得到答复?也许你可以包括决议?我发现您关于 DoS 的观点非常有趣,并且仍然适用……
  • 您自己解释了 DoS 问题。主要问题仍然没有得到回答,但我早就忘记了,直到你发布死灵。没有理由认为 3 年后我仍然会对此类问题的答案感兴趣。
  • 我明白了。我不知何故也错过了核心问题。但我猜你的意思是你是否应该使用SchemaFactory.newSchema(Source[] schemas) 而不是schema.newValidator(String id)?你不需要回答。我仍然对您的问题感兴趣,只是想改进它/看到它改进以供将来参考。标题太模糊了(这里有太多通用的“XML validation using XSD”问题)。
  • I would like to know if I should use schema.newValidator("dir/to/schema.xsd") after all or is the current version - just schema.newValidator() - alright?。 .....SchemaFactory.newSchema(Source[] schemas) instead of schema.newValidator(String id) - 这没有任何意义,架构!= 验证器。
猜你喜欢
  • 2013-10-25
  • 2012-04-13
  • 2014-03-27
  • 2016-10-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-12
相关资源
最近更新 更多