0

我有以下课程:

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")。
仅在启动或手动重新加载(服务器软件)期间进行验证。

4

2 回答 2

1

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

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

来自IBM developerWorks。“提示:配置 SAX 解析器以进行安全处理”

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

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

于 2011-01-01T22:40:40.133 回答
1

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

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

有关更多邪恶的攻击向量,请查看sign 的先前答案

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

于 2014-07-21T08:40:21.520 回答