【问题标题】:Sanitizing user supplied XSLT清理用户提供的 XSLT
【发布时间】:2023-12-21 10:17:01
【问题描述】:

我们有一个应用程序,它使用 XSLT 格式化 XML 数据以显示为 XHTML。

系统能够处理任意 XML 模式,因此系统用户需要上传 Schema 和 XSLT。显然,这是一项只允许管理员级别用户执行的任务,但它也是一个相当大的靶心,因此我正在努力使其更安全。

我应该提到我们正在使用 Saxon 9.0 B

是否有任何标准方法来清理用户提供的 XSLT?到目前为止,我已经确定了三个可能的问题,尽管我意识到可能还有更多我根本没有想到的问题:

  1. xsl:import 和 document() 函数可以访问服务器文件系统。使用自定义 URI 解析器很容易锁定,所以我很有信心我已经涵盖了这个

  2. 输出可以包含 javascript。我正在考虑使用类似 OWASP Anti-Samy 的东西来将允许的输出标签列入白名单。

  3. XSLT 可以调用 java 函数。这是目前让我头疼的一个。我不想完全关闭该功能(尽管目前我什至看不到如何做到这一点),因为我们正在使用它。我首选的解决方案是能够锁定可接受的 java 命名空间,以便只能执行已知的安全函数。不过,我愿意接受其他建议。

黄金标准将是一个标准库,它只处理所有已知的基于 XSLT 的漏洞,但如果没有解决上面列出的问题(尤其是 3)的任何建议,将非常受欢迎。

提前致谢

【问题讨论】:

    标签: xslt xss saxon


    【解决方案1】:

    Saxon 有一个配置选项可以禁用“反身”(动态加载)扩展功能。这不会阻止使用已通过 API 在配置中显式注册的“集成”扩展功能。这似乎满足了您允许服务提供者注册扩展功能,但不允许样式表作者这样做的要求。

    如果您愿意,可以通过定义自己的 JavaExtensionFunctionFactory 来控制扩展函数调用的绑定方式,从而更具选择性。这是相当低级的系统编程,您可能需要研究源代码以了解需要重写哪些方法以满足您的需求。

    除了document(),还需要考虑collection()、unparsed-text()、xsl:result-document。在所有情况下,都有允许您控制行为的 Saxon 钩子。

    【讨论】:

    • 谢谢,这一切都非常有用,正是我所希望的那种信息。
    【解决方案2】:

    我不认为在服务器上上传和执行任何人的 XSLT 是明智之举

    有些事情是无法预防或检测的,例如拒绝服务攻击,例如:

    1. 无休止的递归会耗尽所有可用内存并使服务器因堆栈溢出而崩溃。

    2. 需要数分钟或数小时的转换 - 由于停止问题是无法确定的,我们不知道这是故意的永久循环,还是意外的程序员错误,或者可能会或可能不会收敛的计算。

    当然还有很多其他的利用,比如引用一个递归定义的实体...

    【讨论】:

    • 感谢您的回答。我同意确保 100% 安全可能是不可能的,但目前它是大量可怕的漏洞,我正在寻找可以合理地堵住其中的多少。
    • @JosephRogers,如果您期待任何类型的恶意尝试,您不能忽略此答案中描述的 DOS 类型 - 以及无法防御这些类型的 DOS 的事实。从这个事实得出的合乎逻辑的结论是不允许允许在您的服务器上执行外部代码。尽早了解这一点将节省很多时间。