Flask JSON 安全

2021-08-10 10:41 更新

ECMAScript 5 的變更

從 ECMAScript 5 開(kāi)始,常量的行為變化了。現(xiàn)在它們不由 Array 或其它 的構(gòu)造函數(shù)構(gòu)造,而是由 Array 的內(nèi)建構(gòu)造函數(shù)構(gòu)造,關(guān)閉了這個(gè)特殊的 攻擊媒介。

JSON 本身是一種高級(jí)序列化格式,所以它幾乎沒(méi)有什么可以導(dǎo)致安全問(wèn)題,對(duì)嗎? 你不能聲明導(dǎo)致問(wèn)題的遞歸結(jié)構(gòu),唯一可能導(dǎo)致破壞的就是在接受者角度上,非常 大的響應(yīng)可以導(dǎo)致某種意義上的拒絕服務(wù)攻擊。

然而有一個(gè)陷阱。由于瀏覽器在 CSRF 問(wèn)題上工作的方式, JSON 也不能幸免。幸運(yùn) 的是, JavaScript 規(guī)范中有一個(gè)怪異的部分可以用于簡(jiǎn)易地解決這一問(wèn)題。 Flask 通過(guò)避免你做危險(xiǎn)的事情上為你解決了一些。不幸的是,只有在 jsonify() 中有這樣的保護(hù),所以如果你用其它方法生成 JSON 仍然 有風(fēng)險(xiǎn)。

那么,問(wèn)題是什么,并且怎樣避免?問(wèn)題是 JSON 中數(shù)組是一等公民。想象你在 一個(gè) JSON 請(qǐng)求中發(fā)送下面的數(shù)據(jù)。比如 JavaScript 實(shí)現(xiàn)的用戶界面的一部分, 導(dǎo)出你所有朋友的名字和郵件地址。并不罕見(jiàn):

[
    {"username": "admin",
     "email": "admin@localhost"}
]

這當(dāng)然只在你登入的時(shí)候,且只為你這么做。而且,它對(duì)一個(gè)特定 URL 上的所有 GET 請(qǐng)求都這么做。比如請(qǐng)求的 URL 是 http://example.com/api/get_friends.json

那么如果一個(gè)聰明的黑客把這個(gè)嵌入到他自己的網(wǎng)站上,并用社會(huì)工程學(xué)使得受害 者訪問(wèn)他的網(wǎng)站,會(huì)發(fā)生什么:

<script type=text/javascript>
var captured = [];
var oldArray = Array;
function Array() {
  var obj = this, id = 0, capture = function(value) {
    obj.__defineSetter__(id++, capture);
    if (value)
      captured.push(value);
  };
  capture();
}
</script>
<script type=text/javascript
  src=http://example.com/api/get_friends.json></script>
<script type=text/javascript>
Array = oldArray;
// now we have all the data in the captured array.
</script>

如果你懂得一些 JavaScript 的內(nèi)部工作機(jī)制,你會(huì)知道給構(gòu)造函數(shù)打補(bǔ)丁和為 setter 注冊(cè)回調(diào)是可能的。一個(gè)攻擊者可以利用這點(diǎn)(像上面一樣上)來(lái)獲取 所有你導(dǎo)出的 JSON 文件中的數(shù)據(jù)。如果在 script 標(biāo)簽中定義了內(nèi)容類型是 text/javascript ,瀏覽器會(huì)完全忽略 application/json 的 mimetype ,而把其作為 JavaScript 來(lái)求值。因?yàn)轫攲訑?shù)組元素是允許的(雖然 沒(méi)用)且我們?cè)谧约旱臉?gòu)造函數(shù)中掛鉤,在這個(gè)頁(yè)面載入后, JSON 響應(yīng)中的數(shù)據(jù) 會(huì)出現(xiàn)在 captured 數(shù)組中。

因?yàn)樵?JavaScript 中對(duì)象字面量( {...} )處于頂層是一個(gè)語(yǔ)法錯(cuò)誤,攻 擊者可能不只是用 script 標(biāo)簽加載數(shù)據(jù)并請(qǐng)求一個(gè)外部的 URL 。所以, Flask 所做的只是在使用 jsonify() 時(shí)允許對(duì)象作為頂層元素。確保使用 普通的 JSON 生成函數(shù)時(shí)也這么做。

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)