Flask JSON 安全

2021-08-10 10:41 更新

ECMAScript 5 的變更

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

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

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

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

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

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

那么如果一個聰明的黑客把這個嵌入到他自己的網(wǎng)站上,并用社會工程學(xué)使得受害 者訪問他的網(wǎng)站,會發(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)部工作機制,你會知道給構(gòu)造函數(shù)打補丁和為 setter 注冊回調(diào)是可能的。一個攻擊者可以利用這點(像上面一樣上)來獲取 所有你導(dǎo)出的 JSON 文件中的數(shù)據(jù)。如果在 script 標(biāo)簽中定義了內(nèi)容類型是 text/javascript ,瀏覽器會完全忽略 application/json 的 mimetype ,而把其作為 JavaScript 來求值。因為頂層數(shù)組元素是允許的(雖然 沒用)且我們在自己的構(gòu)造函數(shù)中掛鉤,在這個頁面載入后, JSON 響應(yīng)中的數(shù)據(jù) 會出現(xiàn)在 captured 數(shù)組中。

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

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

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號