【问题标题】:C# validating XML with XSD without loading unvalidated XSD?C# 使用 XSD 验证 XML 而不加载未经验证的 XSD?
【发布时间】:2020-02-26 01:31:53
【问题描述】:

我们的 C# 源代码的安全扫描报告“缺少 XML 验证”作为可能的注入漏洞。它引用了https://cwe.mitre.org/data/definitions/112.html 和其他来源。

它的建议是:

解析 XML 时始终启用验证。如果启用验证 导致问题,因为定义格式良好的文档的规则 是拜占庭式的或完全未知的,很有可能有 附近的安全错误。

示例:以下代码演示了如何在使用 XmlReader.XmlReader 时启用验证

Settings settings = new XmlReaderSettings();
settings.Schemas.Add(schema);
settings.ValidationType = ValidationType.Schema;
StringReader sr = new StringReader(xmlDoc);
XmlReader reader = XmlReader.Create(sr, settings);

我有一个可用于验证的 XSD 架构。我的问题是,如何将 XSD 作为 XmlSchema 加载,而不会重复加载未经验证的 XML 文件的错误?

如果我从文件系统中读取 XSD,我想我只是在重复相同的错误(读取 XML 时没有验证)。有推荐的方法吗?

我们的第一种方法是从文件系统中读取 XSD,例如:

XmlTextReader xsdReader = new XmlTextReader("MySchema.xsd"));
XmlSchema schema = XmlSchema.Read(xsdReader, ValidationCallback);  

但是,我相信这会导致同样的错误,读取 XML(在本例中为 XSD)而无需验证。

我们现在使用的方法(我认为可以通过安全扫描)是从嵌入式资源加载 XSD。

Stream xsdStream = Assembly.GetAssembly(typeof(MyType))
      .GetManifestResourceStream("MyNamespace.MySchema.xsd");  
if (xsdStream == null) throw ...
XmlSchema schema = XmlSchema.Read(xsdStream, ValidationCallback);   

我们还没有重新扫描,但我怀疑嵌入式资源方法会通过。但是,是否有推荐或最佳实践方法?

【问题讨论】:

  • 你能处理settings.ValidationEventHandler吗?因此,首先读取架构,然后设置 XmlReaderSettings,然后使用 XmlReader 加载文档。
  • 正确,但是将 XSD 加载为:XmlTextReader xsdReader = new XmlTextReader("MySchema.xsd")); XmlSchema 架构 = XmlSchema.Read(xsdReader, ValidationCallback);重复原始问题,读取 XML 而不进行验证。
  • 您可以使用XmlSchema schema; using (StringReader xsdReader = new StringReader(xsdPath)) { schema = XmlSchema.Read(xsdReader, null); }null 传递到读取中。然后你的 settings.ValidationEventHandler 正如我建议的那样验证这一点;类似:settings.ValidationEventHandler += (sender, args) => { if (args.Severity == XmlSeverityType.Error) throw new InvalidOperationException(args.Message); }
  • 我们很难确切知道您的安全漏洞扫描工具会反对什么。您是否测试过从this answerAdding (Embedded Resource) Schema To XmlReaderSettings Instead Of Filename? 的代码片段中的任何一个是否确实导致此扫描工具报错?
  • 哦,但不要使用XmlTextReader,根据docs,它已被弃用。请改用XmlReader.Create()。我隐约记得XmlTextReader 有更多允许的默认设置来解析外部 URL,因此可能会被标记为不安全。

标签: c# .net xml xsd-validation


【解决方案1】:

任何能写出“如果启用验证会导致问题,因为定义格式良好的文档的规则是拜占庭式的”的任何人都表明他们对 XML 知之甚少。似乎他们不理解有效和格式良好之间的区别,这是非常基本的。所以你必须想办法绕过不太聪明的规则。此时,您必须决定您的目标是使系统更安全,还是通过安全测试。

很难看出启用验证会修复哪些安全漏洞。

特别是当您可以编写一个接受任何有效文档的架构时,我敢打赌,即使您没有增加一点安全性,您的安全工具也会很高兴您遵守规则。

当模式处理器加载一个模式时,它会自动验证它是一个有效的模式。所以真的没有任何风险。但您的安全扫描器是否接受不存在任何风险则完全是另一回事。

【讨论】:

  • 一个想法:XmlTextReaderXmlSerializer 内部使用)在 .Net 4.0 之前容易受到 XML 炸弹攻击;见XML bomb (Entity Injection) is by default taken care in .Net 4.0 but not in .Net 3.5. How? What changed?Is .NET XmlSerializer.Deserialize(TextReader) safe?。针对包含字符串长度限制的架构进行验证可能在早期版本中可以防止此类攻击。
  • 但总的来说我同意 很难看出启用验证会修复哪些安全漏洞。 但是验证可能会阻止其他问题,例如反序列化的对象在某些无效状态(例如缺少必需的属性)并导致问题和错误。
  • 我认为模式中的长度限制不太可能阻止实体扩展攻击。 XML 解析器几乎肯定会在根据模式中的规则测试其长度之前尝试完整地构造字符串,而不是在构建字符串时不断测试长度。
  • 优秀的分数。另外,我没有从一些公共输入中读取 xml。它来自安全服务器上的文件系统。但是,我需要得到显示代码“通过安全扫描”的金星,即使更改没有实际意义。
  • 你有我的同情。前几天,我们有一位客户拒绝了一张包含银行帐号的付款发票,因为一些安全机构认为通过电子邮件发送银行账户详细信息不安全。所以我们再次发送它,在数字之间加上标点符号。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-29
  • 2018-05-24
  • 1970-01-01
相关资源
最近更新 更多