3

我怎样才能允许:登录已清理的 HTML?我正在使用它来清理生成 java 邮件的 HTML 代码。此代码具有内联图像内容 ID,例如<img src=\"cid:image\" height=\"70\" width=\"70\" />. 清理后,该src属性不包含在清理后的 html 中。

    PolicyFactory IMAGES = new HtmlPolicyBuilder().allowUrlProtocols("http", "https")
            .allowElements("img")
            .allowAttributes("src").matching(Pattern.compile("^cid[:][\\w]+$"))
            .onElements("img")
            .allowAttributes("border", "height", "width").onElements("img")
            .toFactory();

    String html = "<img src=\"cid:image\"  height=\"70\" width=\"70\" />";
    final String sanitized = IMAGES.sanitize(html);

    System.out.println(sanitized);

上面代码的输出是:

<img height="70" width="70" />
4

1 回答 1

10

为什么它不起作用

或者更确切地说,为什么它工作得“太好了”

默认情况下,HtmlPolicyBuilder不允许src元素中的 URL 协议。这可以防止注射,例如

<img src="javascript:alert('xss')"/>

这可能会导致脚本在javascript:(在这种情况下,alert('xss'))之后执行

还有其他协议(在其他元素上)可能导致类似问题:

即使它不使用该javascript协议,仍然可以注入 base64 编码的 XSS 注入:

<object src="data:text/html;base64,PHNjcmlwdD5hbGVydCgneHNzJyk8L3NjcmlwdD4="/> 

或者

<a href="data:text/html;base64,PHNjcmlwdD5hbGVydCgneHNzJyk8L3NjcmlwdD4=">Click me</a>

因此,HtmlPolicyBuilder假设任何包含冒号的属性值(在某些属性中)都应该被视为危险的。


如何修复它:

您必须使用以下方法HtmlPolicyBuilder明确告知允许cid “协议” :allowUrlProtocols

    PolicyFactory IMAGES = new HtmlPolicyBuilder().allowUrlProtocols("http", "https")
            .allowElements("img")
            .allowUrlProtocols("cid") // Specifically allow "cid"
            .allowAttributes("src").matching(Pattern.compile("^cid[:][\\w]+$"))
            .onElements("img")
            .allowAttributes("border", "height", "width").onElements("img")
            .toFactory();

    String html = "<img src=\"cid:image\"  height=\"70\" width=\"70\" />";
    final String sanitized = IMAGES.sanitize(html);

    System.out.println(sanitized);

输出:

<img src="cid:image" height="70" width="70" />
于 2015-09-30T06:02:29.000 回答