
API網關如何發展:更輕、更智能、云原生
最重要的是,官方 RFC 并不是唯一的規范。你還有ECMAScript、JSON5、HJSON,甚至二進制 JSON (BSON )。
這可能讓人抓狂。解析器之間的互操作性暴露了許多人甚至沒有意識到的安全風險。
讓我給你舉幾個例子。
JSON 解析器之間存在一些互操作性安全問題。BishopFox 對該主題進行了一些出色的研究,我在此總結一下。如果您對這些問題感興趣,我強烈建議您查看他們關于該主題的研究。
我希望你考慮一下這個例子:
fu = {“bar”: 1, “bar”: 2}
的值是否fu[“bar”]
等于1或2?或者會產生錯誤?
根據官方規范,任何結果都是完全可以接受的。如果你總是期望它以特定的方式工作,那就有問題了。
因此,如果您有一個用 Python Flask 編寫的前端公開 API,它會使用最后一個鍵的優先級,結果為 2。
但是,如果該有效負載被轉發到后端的單獨微服務進行進一步處理,情況會怎樣?假設它是用 Golang 編寫的。那么,它使用第一鍵優先,結果為 1。
看到這里的問題了嗎?
因此,您需要確保在依賴 JSON 對象的代碼中正確理解順序優先級。否則,這可能會成為一種可能的攻擊媒介,您可以通過以特定順序使用重復鍵來操縱業務邏輯,使其以意想不到的方式工作。
這就是為什么在偵察過程中檢測 API 組件的編程語言非常重要。您需要了解正在使用的語言,并嘗試找出 JSON 對象的解析方式。
當解析器以不一致的方式處理特殊字符或注釋時,就會發生鍵沖突。
例如,在 Python 2.x 中,JSON 解析器在處理某些 Unicode 的方式上有所不同。
考慮以下 JSON 塊:
{“bar”:1,”bar\ud888”:2}
默認 JSON 解析器會將其干凈地處理為兩個不同的鍵。但是,Python 中流行的 ujson 解析器會截斷 Unicode,將鍵視為重復項,并接受 Python 的最后一個鍵優先級。結果如何?標準 JSON 解析器將 bar 的值視為 1,而 uJSON 解析器將 bar 的值視為 2。
查看下面的屏幕截圖,了解實際操作的示例……
雖然我們一直在討論鍵的優先級,但我們實際上一直在展示反序列化過程中的問題。事實上,這也可能發生在序列化過程中。
有時序列化和反序列化本身是不一致的。
以 Java 的 JSON 迭代器為例……
輸入:
fu = {“bar”: 1, “bar”: 2}
輸出:
fu[“bar”] // 1
fu.toString() // {“bar”: 2}
所以在同一個解析器中,鍵的檢索和序列化的值是不同的。底層數據結構保留了重復鍵的值,但序列化器和反序列化器之間的優先級不一致。
JSON RFC 不會阻止重復鍵的序列化。因此,您必須依賴于理解所有組件中數據序列化和反序列化過程中鍵的順序優先順序。
舉個例子,C++ rapidjson 解析器會以不同的方式處理相同的數據:
輸入:
fu = {“bar”: 1, “bar”: 2}
輸出:
fu[“bar”] // 2
fu.toString() // {“bar”: 1, “bar”: 2}
如您所見,相同的 JSON 對象在解析時可能會得到不同的結果。重新序列化這些對象并不能提供任何保護,因為數據可能會有所不同,從而使攻擊者能夠繞過清理邏輯偷偷獲取值。
這可能導致業務邏輯缺陷、注入漏洞或其他安全風險。
希望您能夠看到如何濫用 JSON 并注入可能導致應用程序以開發人員未預料的方式運行的數據。除了我之前提到的結構化格式注入之外,當您可以操縱數據如何在 API 基礎架構內遍歷組件時,您就可以開始控制邏輯流程。
例如,如果您知道 JSON 對象直接序列化到數據庫(例如 MongoDB、Couchbase、DynamoDB、CosmosDB 等)并反序列化到使用不同解析器的外部組件,那么就有機會污染數據并查看它如何進出 API。
考慮一個類似這樣的 API 請求流程:輸入清理阻止創建管理員
POST /user/create HTTP/1.1 ... Content-Type: application/json { "user": "dana", "role": "administrator" } HTTP/1.1 401 Not Authorized ... Content-Type: application/json {"Error": "Assignment of internal role 'administrator' is forbidde
因此我們可以看到輸入驗證不允許我們將角色設置為管理員。
了解解析器如何處理輸入允許您利用解析器的行為以您可以操縱的方式解釋數據,從而潛在地繞過輸入清理。
想想之前的 Python 示例。想象一下,如果您使用 Unicode 字符截斷帳戶創建對象中名為“ role ”的鍵中的值。突然間,“ administrator\ud888
”被解析為“ administrator
”,并且 API 內的 privesc 成為可能。
最終看起來是這樣的:JSON 注入允許繞過清理以獲得管理員權限
POST /user/create HTTP/1.1 ... Content-Type: application/json { "user": "dana", "role": "administrator\ud888" } HTTP/1.1 200 OK ... Content-Type: application/json {"result": "OK: Created user ‘dana’ with the role of ‘administrator’"}
這就是 JSON 注入的最高境界,這要歸功于奇特的 JSON 解析器。
對三星智能中心的攻擊只是 JSON 注入如何導致一系列復雜的漏洞鏈(從 SQL 注入到遠程代碼執行)的一個例子。?
正如我們所見,根本原因通常在于 JSON 解析器處理數據的方式不一致,尤其是當涉及具有不同怪癖的多個解析器時。這些漏洞凸顯了了解 JSON 在 API 基礎架構中的不同語言和組件之間解析和處理方式的細微差別的重要性。
通過徹底審查 JSON 對象的序列化、反序列化和處理方式,您可以開始弄清楚如何制作可以繞過清理過濾器并影響業務邏輯的有效負載。
由于 API 繼續成為現代應用程序的基石,因此確保其處理數據的安全性比以往任何時候都更加重要。希望我今天能讓您對此有所了解。
對各種內容進行注入嘗試。如果不親自動手,你永遠無法了解它們會被如何處理。
文章轉自:使用JSON注入攻擊API