最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python中不安全的反序列化操作示例

 更新時間:2026年01月29日 11:18:37   作者:保持持續(xù)學(xué)習(xí)  
本文給大家介紹了Python的pickling和unpickling過程,詳細(xì)解釋了如何利用pickle模塊的反序列化來執(zhí)行惡意代碼,以及如何防范這種風(fēng)險,本文給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧

1.Python 的 pickling 和 unpickling?

pickling 和 unpickling 是指序列化和反序列化對象的過程。具體來說,pickling 是將一個 Python 對象轉(zhuǎn)換為一個字節(jié)流,以便可以將其存儲到文件中或通過網(wǎng)絡(luò)傳輸;而 unpickling 是將字節(jié)流重新轉(zhuǎn)換回原來的 Python 對象。

1)Pickling 示例操作: 為了實現(xiàn) pickling,我們通常會使用 pickle 模塊。例如:

import pickle
data = {"name": "Alice", "age": 25, "is_student": True}
# 將對象序列化并寫入文件
with open("data.pickle", "wb") as f:
    pickle.dump(data, f)

2)Unpickling 示例操作: 對應(yīng)地,要進(jìn)行 unpickling,可以這樣操作:

import pickle
# 從文件中讀取字節(jié)流并反序列化為對象
with open("data.pickle", "rb") as f:
    data = pickle.load(f)
print(data)  # 輸出:{'name': 'Alice', 'age': 25, 'is_student': True}

3)安全性問題: 值得注意的是,使用 pickle 時要小心安全問題。因為 pickle 可以執(zhí)行任意代碼,所以從不可信來源加載 pickle 數(shù)據(jù)是危險的,可能導(dǎo)致代碼執(zhí)行漏洞。因此,盡量避免加載未經(jīng)驗證的 pickle 文件。

4)絕對 file path 和相對文件存取: 在實際應(yīng)用中,我們可能會使用相對路徑來讀取或?qū)懭?pickle 文件,以增強(qiáng)代碼的可移植性。例如:data.pickle 相較于絕對路徑 "/path/to/data.pickle" 更方便在不同環(huán)境下運行。

5)pickle 模塊的替代品: 如果需要更安全的序列化方法,可以考慮使用 json 模塊,它只支持基本數(shù)據(jù)類型的序列化和反序列化,并不執(zhí)行任何代碼。因此,它是更安全的選擇,盡管功能上沒有 pickle 強(qiáng)大。

import json
data = {"name": "Alice", "age": 25, "is_student": True}
# 序列化
with open("data.json", "w") as f:
    json.dump(data, f)
# 反序列化
with open("data.json", "r") as f:
    data = json.load(f)
print(data)  # 輸出:{'name': 'Alice', 'age': 25, 'is_student': True}

2.如何利用pickle模塊的反序列化來執(zhí)行惡意代碼?

簡單來說,pickle 之所以不安全,是因為它不僅僅是在存儲數(shù)據(jù),它還在存儲**“如何構(gòu)建對象”的指令**。

1. 為什么 pickle 是不安全的?

pickle 的設(shè)計目標(biāo)是序列化幾乎任何 Python 對象。為了實現(xiàn)這一點,它使用了一種名為 Stack Machine(棧機(jī)) 的機(jī)制。

當(dāng)你“反序列化”(unpickling)一個文件時,你實際上是在運行一段 Pickle 虛擬機(jī)代碼。pickle 模塊會盲目地執(zhí)行這些指令來重建對象。如果指令說“去運行這個系統(tǒng)命令”,Python 就會照辦。

核心風(fēng)險點: pickle.load() 并沒有任何沙箱保護(hù)。它信任它讀取的所有數(shù)據(jù)。

2. 為什么可以執(zhí)行任意代碼?

這主要歸功于 Python 對象協(xié)議中的一個特殊魔術(shù)方法:__reduce__。

當(dāng) pickle 嘗試序列化一個對象時,它會檢查該對象是否有 __reduce__ 方法。如果有,該方法必須返回一個元組。這個元組最常見的情況包含兩個元素:

  • 一個可調(diào)用對象(函數(shù))。
  • 一個參數(shù)元組,供上述函數(shù)調(diào)用。

在反序列化時,pickle 會自動調(diào)用這個函數(shù)并傳入?yún)?shù)。這就是攻擊點。

3. Python 例子演示

讓我們通過代碼來看看如何構(gòu)建一個“惡意”的 pickle 包。

下面的代碼創(chuàng)建了一個類,它的 __reduce__ 方法指示 pickle 在解封時運行系統(tǒng)命令(例如在 Windows 上打開計算器,或在 Linux/Mac 上創(chuàng)建一個文件)。

import pickle
import os
class MaliciousPickle:
    def __reduce__(self):
        # os.system 是我們要調(diào)用的函數(shù)
        # ('calc',) 是傳給它的參數(shù)(Windows 下打開計算器)
        # 如果是 Linux/Mac,可以改為 ('touch /tmp/hacked.txt',)
        return (os.system, ('calc',))
# 1. 序列化:黑客生成惡意的 pickle 數(shù)據(jù)
evil_data = pickle.dumps(MaliciousPickle())
# 2. 假設(shè)我們將 evil_data 發(fā)送給了受害者
# 3. 反序列化:受害者僅僅是想“讀取數(shù)據(jù)”
print("正在解封數(shù)據(jù)...")
pickle.loads(evil_data)  # 此時,計算器程序會被彈出!

在上面的例子中,pickle.loads() 本意是恢復(fù)一個對象,但它卻執(zhí)行了 os.system('calc')。

  • 如果黑客把命令換成 rm -rf /(刪除系統(tǒng)文件)。
  • 或者換成一個反彈 Shell(Reverse Shell),遠(yuǎn)程控制你的服務(wù)器。
  • 你的程序甚至不需要以管理員權(quán)限運行,只要它有權(quán)限執(zhí)行的操作,黑客都能做。

4. 如何防范?

  • 永遠(yuǎn)不要 pickle.load() 來自不信任來源的數(shù)據(jù)。 這是金科玉律。
  • 使用更安全的格式: 優(yōu)先選擇 JSON、XMLMessagePack。這些格式只存儲純數(shù)據(jù),不包含執(zhí)行邏輯。
  • 簽名驗證: 如果必須使用 pickle,請使用 hmac 對數(shù)據(jù)進(jìn)行簽名,確保數(shù)據(jù)在傳輸過程中沒有被篡改。

pickle 是為了方便和靈活而設(shè)計的,但這種靈活性賦予了數(shù)據(jù)“生命”,讓它在被加載時能執(zhí)行動作。在安全領(lǐng)域,**“數(shù)據(jù)與指令混淆”**通常是漏洞的根源。

3.Json模塊的反序列化為啥是安全的?

json 模塊之所以被認(rèn)為是安全的,核心原因在于它的本質(zhì)屬性解析機(jī)制pickle 完全不同。

我們可以從以下三個維度來拆解為什么 JSON 不會像 pickle 那樣“反客為主”:

1. 數(shù)據(jù) vs 指令 (Data vs. Code)

這是最根本的區(qū)別。

  • Pickle 是一種“腳本”: pickle 序列化的結(jié)果實際上是一串給 Pickle 虛擬機(jī)運行的指令。它包含“創(chuàng)建對象”、“查找模塊”、“調(diào)用函數(shù)”等操作。正如我們之前看到的,__reduce__ 就像是在數(shù)據(jù)包里藏了一張“指令單”。
  • JSON 是“純描述”: JSON(JavaScript Object Notation)是一種聲明式的數(shù)據(jù)交換格式。它只能表示有限的幾種數(shù)據(jù)類型:字符串、數(shù)字、布爾值、null、數(shù)組(列表)和對象(字典)。

打個比方:

  • Pickle 就像是你收到一個包裹,里面有一張紙條寫著:“去廚房打開煤氣灶”。如果你照做了,就會發(fā)生動作。
  • JSON 就像是你收到一張清單,上面寫著:“蘋果:5個,香蕉:3個”。這張紙條本身沒有任何權(quán)力讓你去做動作,它只是在描述狀態(tài)。

2. 解析器的局限性

json.loads() 的工作原理是極其受限的。

當(dāng)你運行 json.loads(data) 時,Python 的 JSON 解析器只會在內(nèi)存中構(gòu)建基礎(chǔ)的內(nèi)置類型(如 dict, list, str)。它完全不知道什么是 Python 類,也沒有機(jī)制去觸發(fā) os.system() 這樣的外部系統(tǒng)調(diào)用。

在解析 JSON 時,即便你在 JSON 字符串里寫了類似代碼的內(nèi)容:

{
    "command": "os.system('rm -rf /')"
}

解析器也只會把它當(dāng)作一個普通的字符串。除非你自己在代碼里顯式地拿到這個字符串并傳給 eval() 執(zhí)行,否則它就只是一串死板的字符。

3. 缺乏“對象重建”機(jī)制

pickle 之所以危險,是因為它支持自動重建自定義對象。

  • pickle 中,如果數(shù)據(jù)說它是 MyClass 類型,pickle 會嘗試導(dǎo)入這個類并實例化它。
  • json 中,沒有任何語法可以指定“這是一個某個類的實例”。JSON 只知道 [] 是數(shù)組,{} 是鍵值對。

比較表

特性PickleJSON
本質(zhì)二進(jìn)制指令流(可執(zhí)行)文本字符串(純數(shù)據(jù))
支持類型幾乎所有 Python 對象僅基礎(chǔ)類型 (str, int, dict, list等)
自定義類自動觸發(fā) __init____reduce__不支持,除非手動編寫解析邏輯
安全性不安全 (信任數(shù)據(jù)即信任代碼)安全 (解析過程不涉及邏輯執(zhí)行)

4. 潛在的例外(安全警告)

雖然 json.loads() 本身是安全的,但作為開發(fā)者,如果處理不當(dāng)仍會引入風(fēng)險:

  • 后期處理漏洞: 如果你把解析出來的 JSON 數(shù)據(jù)直接傳給了 eval()、exec() 或者數(shù)據(jù)庫查詢語句(SQL 注入),那么危險依然存在。
  • 拒絕服務(wù)攻擊 (DoS): 極度深層嵌套的 JSON(例如 [[[[...]]]])可能會消耗大量的 CPU 或內(nèi)存資源,導(dǎo)致程序崩潰,但這屬于穩(wěn)定性問題,而非任意代碼執(zhí)行。

總結(jié)

JSON 的安全性源于它的簡單性被動性。它只是一面反映數(shù)據(jù)的鏡子,而 pickle 卻是一臺藏在盒子里的微型計算機(jī)。

既然我們談到了安全的數(shù)據(jù)交換,你想了解一下如何為你的 JSON 數(shù)據(jù)添加“數(shù)字簽名”,以確保它在傳輸過程中沒有被第三方篡改嗎?

參考文檔

https://docs.python.org/zh-cn/3/library/pickle.html

https://www.runoob.com/python3/python-pickle.html

https://www.datacamp.com/tutorial/pickle-python-tutorial

到此這篇關(guān)于Python中不安全的反序列化操作示例的文章就介紹到這了,更多相關(guān)Python不安全反序列化內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論

叙永县| 绩溪县| 大埔县| 乌拉特后旗| 澄城县| 囊谦县| 竹溪县| 南平市| 龙胜| 博兴县| 镇赉县| 遂川县| 连州市| 淅川县| 梁平县| 灵武市| 乌鲁木齐市| 江西省| 盱眙县| 阿鲁科尔沁旗| 东台市| 涞水县| 鄂伦春自治旗| 孙吴县| 阳朔县| 新昌县| 信阳市| 普兰店市| 沁水县| 阆中市| 益阳市| 曲水县| 锦屏县| 原阳县| 屏边| 塔城市| 遂宁市| 达州市| 奈曼旗| 吉安市| 镇康县|