【问题标题】:How to use Google Caja HTML/CSS sanitizer JS library in Java如何在 Java 中使用 Google Caja HTML/CSS sanitizer JS 库
【发布时间】:2015-04-30 13:28:52
【问题描述】:

我有一个接受自定义 CSS 字段的 Java API。我需要在将 CSS 存储到我的数据库之前对其进行清理,并希望为此使用 Google Caja

首先,我尝试使用Rhino JavaScript engine 运行Google Caja HTML/CSS sanitizer JavaScript 库。不幸的是,这不起作用,因为该库严重依赖于 DOM 的存在(特别是 window 对象)。

接下来,我从Maven repository 导入了Caja 项目。我查看了一些测试,但找不到如何使用消毒剂的示例。

我可以试试bringing the browser to the server,但这似乎有点过分了。

有没有人能够使用 Caja 来清理 Java 中的 CSS 字符串?

提前致谢!

【问题讨论】:

  • Caja 通过在运行时拦截程序动作来工作,而不是通过重写。你的确切问题是什么?您想防止 XSS,还是想防止 CSS 改变您网站的样式? css 是用作属性还是在<style> 元素中?参考:code.google.com/p/google-caja/wiki/JsHtmlSanitizer
  • 我的意图是将用户定义的 CSS 作为字符串存储在数据库中,然后将该 CSS 字符串包装在另一个站点上的 <style> 标记中。我不打算使用大部分 Caja 库。只有 HTML/CSS 消毒剂。这是一个 jsfiddle,它显示了在一个简单的客户端应用程序上运行的消毒剂;我想在我的 Java API 中执行相同类型的清理。 jsfiddle.net/sscovil/e4pzdLuf

标签: java javascript css sanitization google-caja


【解决方案1】:

如果您打算在 Java 服务器上进行清理,我建议使用 OWASP HTML Sanitizer,这显然是基于 Caja 的代码。它包括清理<a> 元素以包含rel="nofollow" 的能力。

import org.owasp.html.PolicyFactory;
import static org.owasp.html.Sanitizers.BLOCKS;
import static org.owasp.html.Sanitizers.FORMATTING;
import static org.owasp.html.Sanitizers.IMAGES;
import static org.owasp.html.Sanitizers.LINKS;

PolicyFactory sanitiser = BLOCKS.and(FORMATTING).and(IMAGES).and(LINKS);
String htmlSanitised = sanitiser.sanitize(htmlSource)

不过,要从 Java 调用 Caja,这适用于 Rhino (Java 7) 和 Nashorn (Java 8):

import javax.script.Bindings;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class CajaSanitiser {

    private final ScriptEngine engine;
    private final Bindings bindings;

    public CajaSanitiser() throws IOException, ScriptException {
        this.engine = new ScriptEngineManager().getEngineByName("js");
        this.bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE);
        String scriptName = "com/google/caja/plugin/html-css-sanitizer-minified.js";
        try (BufferedReader reader = getReader(scriptName)) {
            engine.eval(reader);
        }
        String identity = "function identity(value) {return value;}";
        engine.eval(identity);
    }

    private BufferedReader getReader(String name) {
        return new BufferedReader(new InputStreamReader(
                getClass().getClassLoader().getResourceAsStream(name)));
    }

    public String sanitise(String htmlSource) throws ScriptException {
        bindings.put("src", htmlSource);
        // You can use other functions beside 'identity' if you
        // want to transform the html.
        // See https://code.google.com/p/google-caja/wiki/JsHtmlSanitizer
        return (String) engine.eval("html_sanitize(src, identity, identity)");
    }

    public static void main(String[] args) throws Exception {
        CajaSanitiser sanitiser = new CajaSanitiser();
        String source = "<html>\n" +
                "<head>\n" +
                "<style>\n" +
                "h1 {color:blue;}\n" +
                "</style>\n" +
                "</head>\n" +
                "<body>\n" +
                "<h1>A heading</h1>\n" +
                "</body>\n" +
                "</html>";
        System.out.println("Original HTML with CSS:");
        System.out.println(source);
        System.out.println();
        System.out.println("Sanitised HTML:");
        System.out.println(sanitiser.sanitise(source));
    }
}

我将它用作我的 Maven 配置的一部分:

<dependencies>
    <dependency>
        <groupId>caja</groupId>
        <artifactId>caja</artifactId>
        <version>r5127</version>
    </dependency>
</dependencies>
<repositories>
    <repository>
        <id>caja</id>
        <name>caja</name>
        <url>http://google-caja.googlecode.com/svn/maven</url>
    </repository>
</repositories>

【讨论】:

  • 感谢您的回答@seanf!我还没有机会测试这个解决方案,但我会尽快接受或跟进。
【解决方案2】:

Google Caja 也是一个“Java 项目”,因此您可以执行 Caja 可以直接在 java 中执行的任何操作。 例如,您可以查看 Caja 单元测试用例以直接在 java here 中验证 CSS。

【讨论】:

  • 嗨,保罗,感谢您的回复。我知道 Caja 是一个 Java 项目,但是您链接到的单元测试与可用的解决方案相去甚远。我正在尝试在 Java 中实际运行 Caja HTML/CSS sanitizer 脚本来清理 CSS 字符串。此示例说明如何从 HTML 文件运行 JavaScript 单元测试,这很可能不依赖于 DOM 的存在。
  • 此外,这些测试使用com.google.caja.util.RhinoTestBed 来运行 JavaScript 单元测试,而无需将数据传递给那些脚本函数或处理响应对象。
猜你喜欢
  • 1970-01-01
  • 2015-04-03
  • 2013-08-04
  • 1970-01-01
  • 1970-01-01
  • 2013-04-08
  • 2012-07-07
  • 1970-01-01
  • 2015-12-27
相关资源
最近更新 更多