[Jsoup] 使用Jsoup消除不受信任的HTML (防止XSS攻击)

这个标题源意来源于官方的cookbook:《Sanitizeuntrusted HTML (to prevent XSS)》本篇文章非原cookbook的译文,紧借用标题。如想查看原Cookbook中文版请自行查找。关于什么是Jsoup, 什么是XSS攻击, 本文亦不在赘述, 请参看本博客的[Jsoup in action]专栏和Cyber Security分类文章。

防止XSS攻击的策略个人总结大致有几种:

  • 使用正则设置白名单/黑名单进行过滤
  • 通过dom对象进行黑名单/白名单的过滤
  • 使用第三方类库Jsoup/AntiXSS等进行过滤HTML标签来防止XSS

本文章将主要介绍使用Jsoup消除不受信任的HTML来防止XSS攻击

1. 如何使用Jsoup进行清除HTML标签操作


使用Jsoup的clean 方法进行清除HTML标签操作(该方法位于JsoupAPI:org.jsoup.Jsoup下)。

static String clean(String strHTML, Whitelist whitelist)

该方法会清除在你所指定的白名单whitelist中的所有HTML标签。默认的Jsoup提供了5种Whitelistorg.jsoup.safety.Whitelist)的API,
具体介绍如下:

  1): none()
    该API会清除所有HTML标签,仅保留文本节点。

  2): simpleText()
    该API仅会保留b, em, i, strong, u 标签,除此之外的所有HTML标签都会被清除

  3): basic()
    该API会保留 a, b, blockquote, br, cite, code, dd, dl, dt, em, i, li, ol, p, pre, q, small, span, strike, strong, sub, sup, u, ul 和其适当的属性标签,除此之外的所有HTML标签都会被清除,且该API不允许出现图片(img tag)。另外该API中允许出现的超链接中可以允许其指定http, https, ftp, mailto 且在超链接中强制追加rel=nofollow属性。

  4): basicWithImages()
    该API在保留basic()中允许出现的标签的同时也允许出现图片(img tag)和img的相关适当属性,且其src允许其指定 httphttps

  5): relaxed()
    该API仅会保留 a, b, blockquote, br, caption, cite, code, col, colgroup, dd, div, dl, dt, em, h1, h2, h3, h4, h5, h6, i, img, li, ol, p, pre, q, small, span, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, u, ul 标签,除此之外的所有HTML标签都会被清除,且在超链接中不会强制追加rel=nofollow属性

Jsoup提供了默认的5个白名单过滤器,在此基础上你也可以进行过滤器的扩展和自定义,方法见下文

2. 如何使用Whitelist过滤器进行清除HTML标签操作


创建适当Whitelist对象,使用clean方法进行清除HTML标签操作,示例代码如下:

import org.jsoup.Jsoup;
import org.jsoup.safety.Whitelist;

public class JsoupWhitelist {

    public static void main(String[] args) {
        String strHTML = "<html>" +
                "<head>" +
                "<title> Clean HTML By Jsoup Whitelist</title>" +
                "</head>" +
                "<body bgcolor=\"000000\">" +
                "<center><img src=\"image.jpg\" align=\"bottom\"> </center>" +
                "<hr>" +
                "<a href=\"http://blog.csdn.net/dietime1943\">bluetata</a>" +
                "<h1>heading tags H1</h1>" +
                "<h2>heading tags H2</h2>" +
                "My email link <a href=\"mailto:[email protected]\">" +
                "[email protected]</a>." +
                "<p>Para tag</p>" +
                "<p><b>bold paragraph</b>" +
                "<br><b><i>bold italics text.</i></b>" +
                "<hr>Horizontal line" +
                "</body>" +
                "</html>";
        
        //clean HTML using none whitelist (remove all HTML tags)
        String cleanedHTML = Jsoup.clean(strHTML, Whitelist.none());
        System.out.println("None whitelist");
        System.out.println(cleanedHTML);
 
        System.out.println("===================================");
        
        //clean HTML using relaxed whitelist
        cleanedHTML = Jsoup.clean(strHTML, Whitelist.relaxed());
        System.out.println("Relaxed whitelist");
        System.out.println(cleanedHTML);
    }
}

控制台打印结果:

None whitelist
Clean HTML By Jsoup Whitelist bluetataheading tags H1heading tags H2My email link [email protected] tagbold paragraphbold italics text.Horizontal line
===================================
Relaxed whitelist
Clean HTML By Jsoup Whitelist
<img align="bottom"> 
<a href="http://blog.csdn.net/dietime1943">bluetata</a>
<h1>heading tags H1</h1>
<h2>heading tags H2</h2>My email link 
<a href="mailto:[email protected]">[email protected]</a>.
<p>Para tag</p>
<p><b>bold paragraph</b><br><b><i>bold italics text.</i></b></p>Horizontal line

3. 扩展Jsoup默认白名单过滤器,对Whitelist过滤器进行扩展


默认的whitelist过滤器分别已经指定了哪些HTML标签可以保留亦或哪些HTML标签会被强制清除掉,如果想要自定义过滤器(强制保留某些html标签)该怎么办呢?Jsoup的Whitelist提供了addTags方法,利用该方法可以对whitelist进行自定义扩展:

public Whitelist addTags(String... tags)

以下示例为仅保留 <div> 标签,并清除div标签外的所有html标签:

        String strHTML = "<html>" +
                "<head>" +
                "<title>retain specific tags</title>" +
                "</head>" +
                "<body bgcolor=\"000000\">" +
                "<a href=\"http://blog.csdn.net/dietime1943\">bluetata</a>" +
                "<h1>heading tag H1</h1>" +
                "<div>div tag content</div>" +
                "</body>" +
                "</html>";
         
        String cleanedHTML = Jsoup.clean(strHTML, Whitelist.none().addTags("div"));
         
        System.out.println(cleanedHTML);

控制台打印结果:

retain specific tagsbluetataheading tag H1
<div>
 div tag content
</div>

Jsoup学习讨论QQ群:50695115

Jsoup爬虫代码示例及博客内源码下载:https://github.com/bluetata/crawler-jsoup-maven

更多Jsoup相关文章,请查阅专栏:【Jsoup in action】


本文原创由`bluetata`发布于blog.csdn.net、转载请务必注明出处。


Flag Counter

发布了115 篇原创文章 · 获赞 179 · 访问量 49万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章