在java中使用XSD进行XML验证

时间:2011-01-01 15:01:07

标签: java xml xsd xsd-validation

我有以下课程:

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")中提到的架构。 验证仅在启动或手动重新加载(服务器软件)期间完成。

2 个答案:

答案 0 :(得分: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,它可以使用dafault属性值将新内容注入文档[...]它可以通过重新定义实体引用来更改文档的内容。

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

答案 1 :(得分:1)

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

  1. 如果您的模式引用互联网中托管的模式,Schema对象将尝试在运行时获取它们。只要我知道,默认的Schema实现不会缓存这些模式。关于错误编码实践的W3C already reported导致其网站出现事实上的DDoS(每天高达1.3M dtd请求!)。
  2. 如果您要验证外部不受控制的xml文件,那么您也会看到Schema尝试从“可能不正确的”xml源中获取其他模式。
  3. 对于更多邪恶的攻击媒介,请查看sign's previous answer

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