<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          經(jīng)過多方調(diào)研,最終還是決定禁用FastJson!

          共 4365字,需瀏覽 9分鐘

           ·

          2021-02-23 20:55

          老項(xiàng)目中使用到多種json類庫,沒有統(tǒng)一管理。最近開啟全新的項(xiàng)目,準(zhǔn)備對json類庫進(jìn)行統(tǒng)一,這樣不僅能夠壓縮jar包的大小,也能夠避免某個類庫的漏洞導(dǎo)致系統(tǒng)問題。

          其實(shí),就在前幾個月因?yàn)镕astJson的漏洞,已經(jīng)全面升級過一次FastJson的版本?,F(xiàn)在項(xiàng)目中有用FastJson,有用gson,也有用Jackson。雖然用的類庫比較多,但使用的場景并不多,還在可控范圍之內(nèi)。

          這篇文章重點(diǎn)講講對FastJson的一些調(diào)研,雖然最終決定強(qiáng)制在項(xiàng)目中禁用FastJson,但在放棄之前,還是要學(xué)習(xí)一下這個類庫的。

          FastJson簡介

          Fastjson是阿里巴巴的開源JSON解析庫,基于Java語言,支持JSON格式的字符串與JavaBean之間的相互轉(zhuǎn)換。它采用一種“假定有序快速匹配”的算法,把JSON Parse的性能提升到了極致。

          由于接口簡單易用,已經(jīng)被廣泛使用在緩存序列化,協(xié)議交互,Web輸出等各種應(yīng)用場景中。

          FastJson的簡單示例

          先用一個簡單的示例來演示一下FastJson的使用。先在項(xiàng)目中引入FastJson類庫:


          ????com.alibaba
          ????fastjson
          ????1.2.70

          關(guān)于版本至少要在1.2.70以上,為啥?之前版本的漏洞太多。

          定義個JavaBean,我們拿User為例:

          public?class?User?{

          ????private?String?userName;

          ????private?int?age;

          ????private?String?address;
          ????
          ????//?getter/setter
          }

          使用實(shí)例:

          public?static?void?main(String[]?args)?{

          ????String?json?=?"{\"address\":\"Beijing\",\"age\":28,\"user_name\":\"Tom\"}";
          ????//?將json轉(zhuǎn)換為JavaBean
          ????User?user?=?JSONObject.parseObject(json,?User.class);
          ????System.out.println(user);

          ????//?將JavaBean轉(zhuǎn)換為json
          ????String?result?=?JSONObject.toJSONString(user);
          ????System.out.println(result);
          }

          實(shí)例中先將json字符串通過parseObject轉(zhuǎn)換成User對象,然后又將User對象通過toJSONString方法轉(zhuǎn)換成json。用起來是不是非常方便?

          同時在構(gòu)造json時你是否發(fā)現(xiàn)json字符串中有“user_name”這樣的格式,F(xiàn)astJson默認(rèn)會將這種下劃線格式的key,與JavaBean中駝峰格式的屬性進(jìn)行綁定。

          執(zhí)行程序,打印結(jié)果:

          User(userName=Tom,?age=28,?address=Beijing)
          {"address":"Beijing","age":28,"userName":"Tom"}

          可以看出成功執(zhí)行。

          FastJson還有其他一些常用的API,比如:

          public?static?final?Object?parse(String?text);?//?把JSON文本parse為JSONObject或者JSONArray?
          public static final JSONObject parseObject(String text);?//?把JSON文本parse成JSONObject ???
          public?static?final??T?parseObject(String?text,?Class?clazz);?//?把JSON文本parse為JavaBean?
          public?static?final?JSONArray?parseArray(String?text);?//?把JSON文本parse成JSONArray?
          public?static?final??List?parseArray(String?text,?Class?clazz);?//把JSON文本parse成JavaBean集合?
          public?static?final?String?toJSONString(Object?object);?//?將JavaBean序列化為JSON文本?
          public?static?final?String?toJSONString(Object?object,?boolean?prettyFormat);?//?將JavaBean序列化為帶格式的JSON文本?
          public static final Object toJSON(Object javaObject);?//將JavaBean轉(zhuǎn)換為JSONObject或者JSONArray。

          通過上述API還可以實(shí)現(xiàn):json字符串與JSONArray之間的轉(zhuǎn)換、json字符串與javaBean之間的轉(zhuǎn)換、json字符串-數(shù)組類型與javaBean之間的轉(zhuǎn)換、JavaList與JsonArray之間的轉(zhuǎn)換等。

          為什么決定放棄FastJson

          通過上面的示例來看FastJson的API使用起來也是非常簡單,而且它的特點(diǎn),也就是賣點(diǎn)就是“快”。

          雖然網(wǎng)上有各種測試,質(zhì)疑FastJson的“快”,但排除測試者測試用例或環(huán)境的影響,整體來看FastJson并不比市面上的其他同類框架慢。

          那么放棄使用的原因是什么呢?

          流行度

          首先,它并不像我們想象中那么大受歡迎。來看一下FastJson的Maven引用量數(shù)據(jù)統(tǒng)計(jì)(來源https://mvnrepository.com/):

          fastjson

          可以看出FastJson排行第四,僅次于第三位的JSON In Java。如果考慮到國內(nèi)大多數(shù)用阿里鏡像,那么FastJson的排位要更靠前一些,但與Jackson相比差距還是有的。

          設(shè)計(jì)與代碼質(zhì)量

          在國外沒有更受推廣的原因大概有兩個:推廣(外加英文文檔)和代碼質(zhì)量。

          外國友人不喜歡FastJson是因?yàn)楦杏X代碼質(zhì)量不高。知乎上有一篇相關(guān)的文章,雖然寫2016年,但也可以參考一下(鏈接:https://www.zhihu.com/question/44199956)。

          fastjson

          對于上述原因,我個人倒是更看重高贊回答中的總結(jié)“用很多投機(jī)取巧的的做法去實(shí)現(xiàn)所謂的'快',而失去了原本應(yīng)該兼容的java特性,對json標(biāo)準(zhǔn)遵循也不嚴(yán)格”。

          是的,正是因?yàn)檫@個類庫來源于阿里的實(shí)踐,很多最初的設(shè)計(jì)與標(biāo)準(zhǔn)有一定的差距。而且已經(jīng)被大量應(yīng)用,就很難在后期改動。外加還經(jīng)常出現(xiàn)不兼容性升級。

          開源Issues

          在寫這篇文章時,看了一下GitHub上項(xiàng)目的Issues,還有大量的需要修復(fù)的問題。而且版本還在頻繁的更新,修復(fù)升級。

          fastjson

          還有1488個問題處于Open狀態(tài)!看到此處,真的有些擔(dān)心了。用的人多,提問題的人多,也可以從另外一個方面來說可能更安全,但如果還有這么多問題待解決,還是有些恐怖的。

          漏洞修復(fù)歷史

          同時,前段時間FastJson多次被爆存在漏洞,而這些漏洞都與FastJson中的一個AutoType特性有關(guān)。

          從2019年7月份發(fā)布的v1.2.59一直到2020年6月份發(fā)布的 v1.2.71 ,每個版本的升級中都有關(guān)于AutoType的升級。

          1.2.59發(fā)布,增強(qiáng)AutoType打開時的安全性?fastjson

          1.2.60發(fā)布,增加了AutoType黑名單,修復(fù)拒絕服務(wù)安全問題?fastjson

          1.2.61發(fā)布,增加AutoType安全黑名單?fastjson

          1.2.62發(fā)布,增加AutoType黑名單、增強(qiáng)日期反序列化和JSONPath?fastjson

          1.2.66發(fā)布,Bug修復(fù)安全加固,并且做安全加固,補(bǔ)充了AutoType黑名單?fastjson

          1.2.67發(fā)布,Bug修復(fù)安全加固,補(bǔ)充了AutoType黑名單?fastjson

          1.2.68發(fā)布,支持GEOJSON,補(bǔ)充了AutoType黑名單。(引入一個safeMode的配置,配置safeMode后,無論白名單和黑名單,都不支持autoType。) fastjson

          1.2.69發(fā)布,修復(fù)新發(fā)現(xiàn)高危AutoType開關(guān)繞過安全漏洞,補(bǔ)充了AutoType黑名單?fastjson

          1.2.70發(fā)布,提升兼容性,補(bǔ)充了AutoType黑名單

          那么什么是AutoType?為什么又會導(dǎo)致漏洞呢?

          對于JSON框架Java對象轉(zhuǎn)換成字符串通??梢曰趯傩曰騭etter/getter方法。FastJson和Jackson是通過遍歷出該類中的所有g(shù)etter方法進(jìn)行的,Gson是通過反射遍歷該類中的所有屬性,并把其值序列化成json。。

          當(dāng)一個類中包含了一個接口(或抽象類),在使用FastJson進(jìn)行序列化的時候,會將子類型抹去,只保留接口(抽象類)的類型,使得反序列化時無法拿到原始類型。

          因此,F(xiàn)astJson引入了AutoType,在序列化時把原始類型記錄下來。

          有了autoType功能,F(xiàn)astJson在對JSON字符串進(jìn)行反序列化時,會讀取@type到內(nèi)容,試圖把JSON內(nèi)容反序列化成對象,并且會調(diào)用它的setter方法。利用這個特性,就可以構(gòu)造一個JSON字符串,并且使用@type指定一個自己想要使用的攻擊類庫。

          小結(jié)

          雖然FastJson有這么多問題,雖然決定不再使用FastJson,但同樣如知乎網(wǎng)友說的那樣“溫少幾乎憑一己之力撐起了一個被廣泛使用JSON庫,而其他庫幾乎都是靠一整個團(tuán)隊(duì),就憑這一點(diǎn),溫少作為“初心不改的阿里初代開源人”,當(dāng)之無愧?!睂τ贔astJson的漏洞問題還是給予理解和包容。


          往期推薦

          SpringBoot的四種異步處理,寫這篇文章,我自己先學(xué)到了

          異步請求和異步調(diào)用有區(qū)別?直到看到了7年前的一個問答

          一篇文章,搞明白異步和多線程的區(qū)別

          兩個經(jīng)典例子讓你徹底理解java回調(diào)機(jī)制

          在Netty服務(wù)被N次攻擊之后,終于抓到現(xiàn)行了!



          如果你覺得這篇文章不錯,那么,下篇通常會更好。添加微信好友,可備注“加群”(微信號:zhuan2quan)。

          一篇文章就看透技術(shù)本質(zhì)的人,
          ? 和花一輩子都看不清的人,
          ? 注定是截然不同的搬磚生涯。
          ▲?按關(guān)注”程序新視界“,洞察技術(shù)內(nèi)幕


          瀏覽 89
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  精品人妻一区二区三区在 | 日本九九热| 亚洲成人视频在线免费观看 | 国产精品在线免费视频 | 俺来也AV |