[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萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章