Как использовать JS-библиотеку Google Caja HTML/CSS sanitizer в Java

У меня есть Java API, который принимает настраиваемое поле CSS. Мне нужно очистить CSS перед его сохранением в моей базе данных, и я хочу использовать Google Caja для этого.

Сначала я попытался запустить библиотеку JavaScript Google Caja HTML/CSS, используя движок JavaScript Rhino. К сожалению, это не сработало, потому что эта библиотека сильно зависит от существования DOM (в частности, объекта window).

Затем я импортировал проект Caja из репозитория Maven. Я просмотрел некоторые тесты, но не смог найти пример использования дезинфицирующего средства.

Я мог бы попробовать перенести браузер на сервер, но это кажется несколько чрезмерным.

Кто-нибудь смог использовать Caja для очистки строки CSS в Java?

Заранее спасибо!


person Shaun Scovil    schedule 27.02.2015    source источник


Ответы (2)


Если вы планируете дезинфицировать сервер 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)

Тем не менее, чтобы вызвать Caja из Java, это работает как с 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>
person seanf    schedule 06.03.2015
comment
Спасибо за ваш ответ @seanf! У меня еще не было возможности протестировать это решение, но я приму его или продолжу, как только сделаю это. - person Shaun Scovil; 09.03.2015

Google Caja также является "Java-проектом", поэтому вы можете выполнить все, что может сделать Caja. прямо в джаве. Например, вы можете взглянуть на модульный тест Caja, чтобы проверить CSS непосредственно в java здесь.

person Pau Carre    schedule 05.03.2015
comment
Эй Пау, спасибо за ваш ответ. Я знаю, что Caja - это проект Java, но модульный тест, на который вы ссылаетесь, далек от пригодного для использования решения. Я пытаюсь запустить скрипт Caja HTML/CSS sanitizer на Java, чтобы очистить строку CSS. В этом примере показано, как запустить модульный тест JavaScript из файла HTML, который, скорее всего, не зависит от наличия DOM. - person Shaun Scovil; 06.03.2015
comment
Кроме того, эти тесты используют com.google.caja.util.RhinoTestBed для запуска модульных тестов JavaScript без передачи данных в эти функции скрипта или обработки объекта ответа. - person Shaun Scovil; 06.03.2015