OWASP HTML 消毒剂允许在 HTML 中使用冒号

OWASP HTML Sanitizer allow colon in HTML

如何让 : 登录经过清理 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" />

为什么它不起作用

或者更确切地说,它为什么有效 "too well"

默认情况下,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 "protocol",使用 allowUrlProtocols method:

    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" />