HtmlPolicyBuilder is fast and easy to configure HTML Sanitizer which lets you include HTML authored by third-parties in your web application while protecting against XSS. You can read more about the underlying implementation here.

1 Creating policy

To create an html sanitizer policy, configure the HtmlPolicyBuilder using a lambda function.

Copy
<script>
    var policy = new Ax.owasp.HtmlPolicyBuilder(config => {
        config
        .allowElements("p");
    });
    var safeHTML = policy.sanitize("<p>Hello, <b>World!</b>");
    console.log(safeHTML);
</script>
<p>Hello, World!</p>

2 Configuring policy

Html sanitizer can be configured using pre-build in configurations.

Method Return Description
allowCommonInlineFormattingElements HtmlPolicyBuilder Allows common formatting elements including <b> <i>, etc
allowCommonBlockElements HtmlPolicyBuilder Allows common block elements including <p><h1>, etc.
allowStyling HtmlPolicyBuilder Allows certain safe CSS properties in style="..." attributes.
allowLinks HtmlPolicyBuilder Allows HTTP, HTTPS, MAILTO, and relative links. This is equivalent to:
Copy
var policy = new Ax.owasp.HtmlPolicyBuilder(config => {
    config
    .allowStandardUrlProtocols()
    .allowElements("a")
    .allowAttributes("href").onElements("a")
    .requireRelNofollowOnLinks();
});
allowImages HtmlPolicyBuilder Allows <img> elements from HTTP, HTTPS, and relative sources. This is equivalent to:
Copy
var policy = new Ax.owasp.HtmlPolicyBuilder(config => {
    config.allowUrlProtocols("http", "https", "cid")
    .allowElements("img")
    .allowAttributes("alt", "src").onElements("img")
    .allowAttributes("border", "height", "width")./*matching(INTEGER)*/onElements("img");  
    //. INTEGER is private     
});
;
allowTables HtmlPolicyBuilder Allows HTTP, HTTPS, MAILTO, and relative links. This is equivalent to:
Copy
var policy = new Ax.owasp.HtmlPolicyBuilder(config => {
    config
    .allowStandardUrlProtocols()
    .allowElements("table", "tr", "td", "th", "colgroup", "caption", "col", "thead", "tbody", "tfoot")
    .allowAttributes("summary").onElements("table")
    .allowAttributes("align", "valign").onElements("table", "tr", "td", "th", "colgroup", "col", "thead", "tbody", "tfoot")
    .allowTextIn("table");
});
Copy
<script>
    var policy = new Ax.owasp.HtmlPolicyBuilder(config => {
        config
        .allowCommonInlineFormattingElements()
        .allowImages()
        ;
    });
    var safeHTML = policy.sanitize("<p style='color:blue;'><b>Hello</b>, World! <img src='https://www.server.com/img.png'>");
</script>
<b>Hello</b>, World! <img src="https://www.server.com/img.png" />

3 Preprocessing

You can add a preprocessor to handle open (onOpenTagPreprocessor) and close (onCloseTagPreprocessor) elements and modify it's attributes. For example, to modify inline image url references using cid: and replace it:

Copy
<script>
    var htmlPolicy = new Ax.owasp.HtmlPolicyBuilder(config => {
    config
        .allowCommonBlockElements()
        .allowCommonInlineFormattingElements()
        .allowStyling()
        // allow ./api
        .allowUrlProtocols("")
        .allowStandardUrlProtocols()
        .allowElements("hr", "br")
        .allowElements("table", "tr", "td", "th", "colgroup", "caption", "col", "thead", "tbody", "tfoot")
        .allowAttributes("summary", "align", "valign", "border", "height", "width", "rowspan", "colspan").onElements("table", "tr", "td", "th", "colgroup", "col", "thead", "tbody", "tfoot")
        .allowTextIn("table")
        .allowImages();
        config.openTagPreprocessor((elementName, attrs) => {
            // ------------------------------------------------------------------
            // Find <img src='cid:ii_k6gaa7ly0'> and replace by the URL to the
            // attached image.
            // ------------------------------------------------------------------
            if (elementName.equals("img")) {
                for (var i = 0, n = attrs.size(); i < n; i += 2) {
                    if ("src".equals(attrs.get(i))) {
                        var url = attrs.get(i + 1);
                        if (url.startsWith("cid:")) {
                            // Replace url
                            attrs.set(i + 1, Ax.lang.String.format("./api/card/%s", url.substring("cid:".length)));
                        }
                    }
                }
            }
        })
    ;
    });
</script>