
مفكِّك ترميز pickling في بايثون ومحلِّل ثابت.

Fickling هو أداة فك تجميع ومحلل ساكن ومُعيد كتابة للبايت كود لملفات تسلسل الكائنات بصيغة Python pickle. يمكنك استخدام fickling لاكتشاف أو تحليل أو الهندسة العكسية أو حتى إنشاء ملفات pickle خبيثة أو ملفات مبنية على pickle، بما في ذلك ملفات PyTorch.
يمكن استخدام Fickling كـ مكتبة python وأداة CLI على حد سواء.
يتطلب Fickling إصدار Python 3.11 أو أحدث وله اعتماديات قليلة جدًا. يمكن تثبيت كل من المكتبة وأداة سطر الأوامر عبر pip أو uv:
# Using pip
python -m pip install fickling
# Using uv
uv pip install fickling
PyTorch هو تبعية اختيارية لـ Fickling. لذلك، من أجل استخدام وحدات pytorch وpolyglot في Fickling، يجب عليك تشغيل:
# Using pip
python -m pip install fickling[torch]
# Using uv
uv pip install fickling[torch]
يمكن أن يساعد Fickling في تأمين قواعد أكواد الذكاء الاصطناعي/التعلّم الآلي من خلال الفحص التلقائي لملفات pickle الموجودة في النماذج. يعترض Fickling وحدة pickle ويتحقق من عمليات الاستيراد التي تتم عند تحميل نموذج. فهو يتحقق فقط من عمليات الاستيراد مقابل قائمة سماح بعمليات استيراد من مكتبات التعلّم الآلي التي تُعتبر آمنة، ويحظر الملفات التي تحتوي على عمليات استيراد أخرى.
أضف الأسطر التالية في أقرب وقت ممكن، قبل استيراد torch أو numpy أو أي مكتبة أخرى تستخدم pickle:
import fickling
# This sets global hooks on pickle
fickling.hook.activate_safe_ml_environment()
لإزالة الحماية:
fickling.hook.deactivate_safe_ml_environment()
من الممكن أن النماذج التي تستخدمها تحتوي على استيرادات غير مسموح بها من قِبل Fickling. إذا كنت لا تزال ترغب في تحميل النموذج، يمكنك ببساطة السماح باستيرادات إضافية لحالتك الاستخدامية المحددة باستخدام الوسيطة also_allow:
fickling.hook.activate_safe_ml_environment(
also_allow=[
"some.import",
"another.allowed.import",
]
)
مهم: يجب عليك دائمًا التأكد من أن الاستيرادات المضافة يدويًا آمنة فعلاً ولا يمكن أن تُمكّن المهاجمين من تنفيذ تعليمات برمجية عشوائية. إذا كنت غير متأكد من كيفية القيام بذلك، يمكنك فتح issue على مستودع Fickling على GitHub يوضح الاستيرادات/النماذج المعنية، ويمكن لفريقنا مراجعتها وتضمينها في قائمة السماح إن أمكن.
يمكن دمج Fickling بسلاسة في قاعدة التعليمات البرمجية الخاصة بك للكشف عن تحميل الملفات الخبيثة وإيقافه في وقت التشغيل.
نعرض أدناه الطرق المختلفة التي يمكنك بها استخدام fickling لفرض فحوصات الأمان على ملفات pickle.
تحت الغطاء، يقوم باعتراض مكتبة pickle لإضافة فحوصات أمان بحيث يؤدي تحميل ملف pickle
إلى رفع استثناء UnsafeFileError إذا تم اكتشاف محتوى خبيث في الملف.
# This enforces safety checks every time pickle is used to deserialize
fickling.always_check_safety()
# Attempt to load an unsafe file now raises an exception
with open("file.pkl", "rb") as f:
try:
pickle.load(f)
except fickling.UnsafeFileError:
print("Unsafe file!")
with fickling.check_safety():
# All pickle files loaded within the context manager are checked for safety
try:
with open("file.pkl", "rb") as f:
pickle.load("file.pkl")
except fickling.UnsafeFileError:
print("Unsafe file!")
# Files loaded outside of context manager are NOT checked
pickle.load("file.pkl")
عند الخروج، يُعيد مدير السياق أي شيء كان مثبتًا عند الدخول، لذا يبقى الخطاف الموجود مسبقًا فعّالًا بدلًا من ترك pickle دون خطاف.
# Use fickling.load() in place of pickle.load() to check safety and load a single pickle file
try:
fickling.load("file.pkl")
except fickling.UnsafeFileError as e:
print("Unsafe file!")
# Perform a safety check on a pickle file without loading it
if not fickling.is_likely_safe("file.pkl"):
print("Unsafe file!")
يمكنك الوصول إلى تفاصيل تحليل السلامة الخاص بـ fickling من داخل الاستثناء المرفوع:
>>> try:
... fickling.load("unsafe.pkl")
... except fickling.UnsafeFileError as e:
... print(e.info)
{
"severity": "OVERTLY_MALICIOUS",
"analysis": "Call to `eval(b'[5, 6, 7, 8]')` is almost certainly evidence of a malicious pickle file. Variable `_var0` is assigned value `eval(b'[5, 6, 7, 8]')` but unused afterward; this is suspicious and indicative of a malicious pickle file",
"detailed_results": {
"AnalysisResult": {
"OvertlyBadEval": "eval(b'[5, 6, 7, 8]')",
"UnusedVariables": [
"_var0",
"eval(b'[5, 6, 7, 8]')"
]
}
}
}
إذا كنت تستخدم لغة أخرى غير Python، فلا يزال بإمكانك استخدام CLI الخاص بـ fickling
لفحص ملفات pickle للتحقق من سلامتها:
fickling --check-safety -p pickled.data
تتيح واجهة CLI الخاصة بـ Fickling تتبع تنفيذ آلة pickle الافتراضية بأمان دون
تشغيل أي تعليمات برمجية ضارة:
fickling --trace file.pkl
يتيح Fickling حقن كود عشوائي في ملف pickle سيتم تنفيذه في كل مرة يتم فيها تحميل الملف
fickling --inject "print('Malicious')" file.pkl > malicious.pkl
يمكن استخدام Fickling لفك تجميع ملف pickle لمزيد من التحليل
>>> import ast, pickle
>>> from fickling.fickle import Pickled
>>> fickled_object = Pickled.load(pickle.dumps([1, 2, 3, 4]))
>>> print(ast.dump(fickled_object.ast, indent=4))
Module(
body=[
Assign(
targets=[
Name(id='result', ctx=Store())],
value=List(
elts=[
Constant(value=1),
Constant(value=2),
Constant(value=3),
Constant(value=4)],
ctx=Load()))],
type_ignores=[])
تحتوي PyTorch على تنسيقات ملفات متعددة يمكن من خلالها إنشاء ملفات polyglot، وهي ملفات يمكن تفسيرها بشكل صحيح على أنها أكثر من تنسيق ملف واحد. تدعم Fickling تحديد واستقصاء وإنشاء ملفات polyglot باستخدام تنسيقات ملفات PyTorch التالية:
>> import torch
>> import torchvision.models as models
>> from fickling.pytorch import PyTorchModelWrapper
>> model = models.mobilenet_v2()
>> torch.save(model, "mobilenet.pth")
>> fickled_model = PyTorchModelWrapper("mobilenet.pth")
>> print(fickled_model.formats)
Your file is most likely of this format: PyTorch v1.3
['PyTorch v1.3']
اطّلع على أمثلتنا لتتعلم المزيد عن استخدام fickling!