Serileştirme ve yükleme riski
- Bazı model biçimlerinin yükleme anında kod çalıştırdığını, dosyayı açmadan nasıl inceleyeceğini ve güvenli biçime nasıl geçeceğini öğrenirsin.
- Bu derste hangi biçimin ne kadar yetki istediğini ve güvenli biçimin neden güvenli olduğunu göreceksin.
- Sonunda bir dosyayı yüklemeden önce ne kontrol edeceğini bileceksin.
Puan bütün etkinlikleri cevaplayınca hesaba yazılır. Bu dersi tamamlayınca +55 XP alacaksın. Giriş yapmadan ilerlersen puan yalnız bu tarayıcıda durur.
Altay Kargo'nun veri ekibi bir iş ortağından paket sınıflandırma modeli aldı. Dosyanın adı pytorch_model.bin idi. Bir mühendis modeli denemek için kendi dizüstünde yükledi.
Model çalıştı, tahminler de doğruydu. Ertesi sabah uç nokta güvenlik aracı aynı dizüstünden bilinmeyen bir adrese giden bağlantıyı raporladı. Bağlantı, modelin yüklendiği dakikada başlamıştı.
Kimse modele tek bir istek göndermemişti. Bu derste bunun nasıl mümkün olduğunu göreceksin. Önce pickle biçiminin içini açacaksın. Sonra bir dosyayı çalıştırmadan okumayı, tarayıcıların neyi yakalayıp neyi kaçırdığını ve güvenli biçime geçişi öğreneceksin.
Serileştirme ve pickle
Serileştirme, bellekteki bir nesneyi diske yazılabilir bir bayt dizisine çevirmektir. Ters işlem nesneyi geri kurar. Sorun burada başlar: bazı biçimler nesneyi kurarken keyfi işlev çağırma hakkı ister.
Python'un pickle biçimi bunun klasik örneğidir. Bir pickle dosyası yalnız veri taşımaz, veriyi kurma talimatlarını da taşır. Yükleyici bu talimatları küçük bir yığın makinesi gibi sırayla çalıştırır.
PyTorch'un .bin ve .pt uzantılı ağırlık dosyaları ile scikit-learn modellerinde sık görülen .pkl ve .joblib dosyaları bu biçim üstüne kuruludur. PyTorch'un .bin dosyası aslında bir ZIP arşividir ve içinde data.pkl adlı bir pickle taşır. Uzantıya bakıp dosyayı sıradan bir ağırlık yığını sanmak bu yüzden yanıltıcıdır.
Talimatların çoğu zararsızdır: bir sözlük kur, listeye sayı ekle, metni belleğe al. Ama üç talimat farklıdır. GLOBAL ve STACK_GLOBAL bir modülden işlev içe aktarır. REDUCE o işlevi verilen argümanlarla çağırır.
Bu içe aktarma ve çağırma düzeni, nesnelerin kendini nasıl kuracağını söyleyebilmesi için vardır. Aynı mekanizma bir komut çalıştıran ya da metni kod olarak işleyen bir işlevi de çağırabilir. Bu bir hata değil, biçimin tasarımıdır. Python belgeleri bu yüzden açık bir uyarı taşır: pickle modülü güvenli değildir, yalnız güvendiğin veriyi aç.
Kural nettir: güvenmediğin bir pickle dosyasını açmak, güvenmediğin bir betiği çalıştırmakla aynı ağırlıktadır. Dosyanın model ağırlığı gibi görünmesi bir şey değiştirmez. Dosyayı kim ürettiyse, yükleme anında senin sürecinde söz sahibi olur. Zarar ilk istek gelmeden, yükleme satırında oluşur.
MITRE ATLAS bu durumu iki teknikle izler. AML.T0018.002 model dosyasına zararlı kod gömmeyi anlatır. AML.T0011.000 ise kullanıcının güvensiz bir yapay zekâ dosyasını kendi eliyle yüklemesini anlatır. Gömülü kodlu bir model beklendiği gibi çalışmaya da devam edebilir, bu yüzden davranışına bakarak fark edilmez.
Etkinlik 1 / 7
Pickle türü biçimleri riskli yapan temel özellik nedir?
Güvenli biçim ve güvenli varsayılan
Güvenli biçimler bu yetkiyi baştan vermez. safetensors biçimi yalnız tensörleri ve basit üstveriyi taşır. Dosya üç parçadan oluşur: başlığın uzunluğunu söyleyen sekiz baytlık bir sayı, her tensörün türünü, boyutunu ve dosyadaki yerini listeleyen bir JSON başlığı, ardından ham sayılar. Yükleyici başlığı okur ve sayıları belleğe eşler.
Dosyadan gelen hiçbir talimatı çalıştırmaz. Dosya bozuksa hata alırsın, kod çalışmaz. Hugging Face'in transformers kütüphanesi depoda safetensors dosyası varsa onu tercih eder.
# Kabul edilen bicim model.safetensors -> yalniz tensor + ustveri, calisma yok # Incelenmeden yuklenmez pytorch_model.bin -> pickle tabanli, yukleme aninda kod yolu var model.pkl -> ayni sinif model.joblib -> pickle uzerine kurulu # Ozel ayarla yuklenir model.keras -> Lambda katmani tasiyabilir, safe_mode acik kalir
PyTorch tarafında da varsayılan değişti. torch.load işlevi 2.6 sürümünden beri weights_only=True ile çalışır. Bu modda yükleyici yalnız tensörleri, ilkel türleri ve sözlükleri kurar.
Bilinmeyen bir işlev çağrısı görürse hata verir. weights_only=False yazmak bu korumayı kapatır, bunu yalnız kaynağını doğruladığın dosya için yap. Kısıtlı mod de kusursuz değildir.
2025'te yayımlanan CVE-2025-32434, 2.5.1 ve önceki sürümlerde weights_only=True ile bile kod çalıştırılabildiğini kayda geçirdi. Düzeltme 2.6.0 ile geldi. Varsayılan ayar ancak güncel sürümle birlikte korur.
Güvenli varsayılan yalnız ağırlık dosyası için geçerli değildir. Bazı model depoları kendi Python dosyalarını da taşır. transformers kütüphanesinde bu dosyaları çalıştırmak için trust_remote_code seçeneği vardır ve varsayılanı False'tur. Belgeler bu seçeneği yalnız güvendiğin ve kodunu okuduğun depolar için açmanı söyler, çünkü depodaki kod senin makinende çalışır.
Açman gerekiyorsa kodu da kayıt kimliğine sabitle. Kod modelle aynı depodaysa revision bunu yapar, başka bir depodaysa code_revision seçeneğini kullanırsın. Aksi hâlde depo sahibi kodu sonradan değiştirir, sen de yeni kodu sessizce çalıştırırsın. Depodaki .py dosyalarını da modelin bir parçası say ve incelemeden geçir.
Etkinlik 2 / 7
Doğru mu, yanlış mı?
transformers kütüphanesinde trust_remote_code seçeneğini açtığında depodaki Python dosyaları senin makinende çalışır.
Benzer bir tuzak Keras'ta yaşandı. Lambda katmanı modelin içine Python işlevi gömer. CVE-2024-3660, 2.13 öncesi Keras sürümlerinde böyle bir modelin, onu yükleyen uygulamanın yetkisiyle kod çalıştırabildiğini kayda geçirdi. Güncel sürümlerde .keras biçimindeki modeller safe_mode=True ile yüklenir ve Lambda katmanının kodu açılmaz.
Kural her yerde aynı: güvenli varsayılanı kapatma. Kapatman gerekiyorsa gerekçeyi yaz, dosyayı incelemeden geçir ve kararı kayıt altına al.
Etkinlik 3 / 7
Her biçimi yükleme davranışına göre ayır.
Önce bir seçeneğe, sonra aşağıdaki uygun kutuya bas. İstersen seçeneği kutuya sürükleyip bırak. Yerini değiştirmek için aynı işlemi tekrarla.
0/5 seçenek yerleşti.
Dosyayı açmadan okumak
Pickle dosyasını yüklemeden de içine bakabilirsin. Python'un pickletools modülü talimatları sırayla okur ve listeler, hiçbirini çalıştırmaz. Hugging Face Hub da yüklenen her pickle dosyasını aynı yöntemle tarar.
İçe aktarılan işlevlerin listesini dosyanın yanında gösterir ve şüpheli olanları işaretler. Aşağıda iki dosya var.
Biri yalnız ağırlık taşıyan temiz bir sözlük. Öbürü zararsız bir kanarya: yüklendiğinde ekrana tek bir kelime yazan bir deneme dosyası. Kanarya, tarayıcıyı ve inceleme alışkanlığını gerçek bir yük olmadan sınamanın yoludur. Böyle bir dosyayı yalnız kendi lab ortamında üret ve dene.
$ python3 -m pickletools temiz.pkl
0: \x80 PROTO 4
2: \x95 FRAME 36
11: } EMPTY_DICT
13: \x8c SHORT_BINUNICODE 'katman1'
23: ] EMPTY_LIST
25: ( MARK
26: G BINFLOAT 0.12
35: G BINFLOAT -0.5
44: e APPENDS (MARK at 25)
45: s SETITEM
46: . STOP
$ python3 -m pickletools kanarya.pkl
0: \x80 PROTO 4
2: \x95 FRAME 36
11: \x8c SHORT_BINUNICODE 'builtins'
22: \x8c SHORT_BINUNICODE 'print'
30: \x93 STACK_GLOBAL
32: \x8c SHORT_BINUNICODE 'kanarya'
42: \x85 TUPLE1
44: R REDUCE
46: . STOPÇıktıyı satır satır oku. Temiz dosyada yalnız veri talimatları var. EMPTY_DICT bir sözlük, EMPTY_LIST bir liste açar. BINFLOAT sayıları yığına koyar, APPENDS onları listeye ekler, SETITEM listeyi sözlüğe yazar.
STOP işi bitirir. Hiçbir işlev içe aktarılmaz, hiçbir şey çağrılmaz. Kanarya dosyasında tablo değişir. İki metin yığına girer: modül adı builtins ve işlev adı print.
STACK_GLOBAL bu ikisini birleştirip işlevi içe aktarır. TUPLE1 argümanı hazırlar. REDUCE işlevi çağırır. Gerçek bir saldırıda print yerine komut çalıştıran bir işlev durur.
Yapı aynı kalır, yalnız iki metin değişir. Bu yüzden incelemede ilk aradığın şey GLOBAL ya da STACK_GLOBAL ile gelen her içe aktarmadır.
Etkinlik 4 / 7
Bu talimat dizisi bir pickle yükleyicisine verildiğinde ne olur?
Önce kodu oku, sonra çıktıyı seç.
\x8c SHORT_BINUNICODE 'posix' \x8c SHORT_BINUNICODE 'getcwd' \x93 STACK_GLOBAL ) EMPTY_TUPLE R REDUCE
Tarayıcılar ve sınırları
Elle okumak öğreticidir ama yüzlerce dosyada ölçeklenmez. Bu işi tarayıcılar yapar. picklescan bilinen tehlikeli içe aktarmaların listesini tutar ve dosyada onları arar. modelscan aynı fikri birden çok model biçimine genişletir ve bulguları önem derecesiyle raporlar.
fickling dosyayı Python koduna benzer bir biçime çevirir ve --check-safety seçeneğiyle güvenlik denetimi yapar. Hugging Face Hub da her dosyayı ClamAV virüs taramasından ve pickle içe aktarma taramasından geçirir. Aşağıda picklescan'in iki dosyadaki sonucu var.
$ picklescan --path indirilen/siniflandirici.pkl indirilen/siniflandirici.pkl: dangerous import 'posix getcwd' FOUND ----------- SCAN SUMMARY ----------- Scanned files: 1 Infected files: 1 Dangerous globals: 1 $ echo $? 1 $ picklescan --path indirilen/kanarya.pkl ----------- SCAN SUMMARY ----------- Scanned files: 1 Infected files: 0 Dangerous globals: 0
İlk taramada araç posix modülünden getcwd içe aktarmasını yakaladı ve FOUND yazdı. Çıkış kodu 1 oldu. Bu kod sürekli entegrasyon hattında işi durdurmaya yeter.
Kod 0, taramanın bir şey bulmadığını söyler. Kod 2 ise taramanın tamamlanamadığını gösterir. İkinci sonuç daha öğreticidir. Kanarya dosyası print çağırdığı hâlde temiz göründü, çünkü print aracın tehlikeli listesinde yok.
Tarayıcı bir kara liste yaklaşımıyla çalışır ve listede olmayanı geçirir. Saldırganlar bu boşluğu bilir. ATLAS'ın 2025 tarihli AML.CS0031 vakasında zararlı modeller, yükü çalıştırdıktan sonra kasten bozulan dosyalarla tarayıcıdan kaçtı.
Etkinlik 5 / 7
Doğru mu, yanlış mı?
Pickle tabanlı bir model dosyasını incelemek için önce normal şekilde yüklemek gerekir.
Derinleş:Tarayıcıyı atlatan bozuk dosyalar
2025'in başında bir güvenlik firmasının araştırmacıları, Hugging Face'te yüklendiğinde ters kabuk açan modeller buldu. Ters kabuk, kurbanın makinesinden saldırgana giden ve ona komut satırı veren bir bağlantıdır. Platformun pickle tarayıcısı bu dosyaları işaretlememişti.
Nedeni basitti: tarayıcı dosyayı baştan sona ayrıştırabilmeye güveniyordu. Dosyalar ise kasten bozulmuştu. Zararlı talimatlar dosyanın başındaydı. Yükleyici onları çalıştırıyor, ardından bozuk kısımda hata verip duruyordu.
Kurban yalnız bir yükleme hatası görüyordu. Tarayıcı ise dosyayı sonuna kadar okuyamadığı için içindeki içe aktarmayı rapor etmiyordu. Platform modelleri kaldırdı ve tarayıcıyı bu kalıbı yakalayacak biçimde güncelledi. Vaka iki dersi birlikte taşır.
Tarayıcının sessiz kalması temiz demek değildir. Pickle biçimi de doğası gereği güvensizdir, hiçbir tarayıcı bütün kalıpları yakalayamaz. ATLAS vakayı AML.CS0031 koduyla kaydeder.
Tek kapı ve yalıtım
Pratikte pickle tabanlı dosyalar hâlâ dolaşımda. Eski depolar, eski eğitim hatları, kurum içi arşivler. Hepsini bir gecede değiştiremezsin.
Geçiş döneminde üç savunma birlikte çalışır. Birincisi tarama: dosyayı açmadan içe aktarmalarını kontrol edersin. İkincisi yalıtım: dönüştürmeyi ağı kapalı, yetkisi kısık, kullanılıp atılan bir kapsayıcıda yaparsın ve dışarı yalnız safetensors dosyasını alırsın.
Tarama şüpheliyi işaretler, yalıtım ise gözden kaçan bir yük çalışsa bile zararı kapsayıcıda tutar. Üçüncüsü tek kapıdır: kuruma giren her model güvenli biçime çevrilir, özeti kaydedilir ve üretim yükleyicisi yalnız bu biçimi kabul eder. Şemadaki aşamalar bu akışla örtüşür. Triyajda özete ve biçime bakarsın, statik analizde pickletools ve tarayıcıları kullanırsın.
Dinamik adım yalıtılmış dönüştürmedir. Kod analizinde fickling çıktısını okur, içe aktarılan işlevin ne yaptığını çözersin. Son adımda şüpheli dosyanın özetini engel listesine yazarsın.
def modeli_yukle(yol):
if not yol.endswith(".safetensors"):
raise ValueError("yalniz safetensors kabul edilir")
if ozet(yol) not in ONAYLI_OZETLER:
raise ValueError("ozet onayli listede yok")
return guvenli_yukle(yol)Kodu satır satır oku. İlk kontrol uzantıya bakar ve safetensors dışındaki her biçimi reddeder.
İkinci kontrol dosyanın özetini hesaplar ve onaylı listeyle karşılaştırır. İki kontrol de yüklemeden önce çalışır. Ancak ikisi de geçerse dosya belleğe alınır.
Sıra burada her şeydir. Aynı iki kontrol yüklemeden sonra gelseydi pickle dosyasındaki kod çoktan çalışmış olurdu. Bu desenle politika bir belgede durmaz, her çağrının geçmek zorunda olduğu tek bir işlevde durur. İstisna için ayrı bir onay süreci de gerekmez.
Etkinlik 6 / 7
Aşağıdaki yükleyicide riski yaratan satırı bul.
Az önce bulduğun hatalı yükleyici gerçek projelerde sık görülür, çünkü kod okunurken mantıklı görünür: indir, yükle, sonra kontrol et. Hata ancak sıra tersine çevrilince düzelir. Aynı sıra düşüncesi kurumsal kabul sürecine de uygulanır.
Dışarıdan gelen bir model önce açılmadan incelenir, sonra yalıtımda dönüştürülür, en son üretime tanıtılır. Her adımın çıktısı bir sonrakinin girdisidir, bu yüzden bir adımı atlamak bütün zinciri boşa çıkarır. Şimdi bu sırayı kendin kur.
Etkinlik 7 / 7
Dışarıdan gelen pickle tabanlı bir modeli kuruma almanın sırasını kur.
Bir öğeye odaklan, yukarı ve aşağı ok tuşlarıyla taşı. Home tuşu en üste, End tuşu en alta alır.
- 1Üretim yükleyicisine yalnız bu biçimi tanıt
- 2Özeti onaylı listeye ekle
- 3Güvenli biçimdeki çıktının özetini al
- 4Dosyayı açmadan statik taramadan geçir
- 5Ağı kapalı yalıtılmış ortamda dönüştür
Okumayı istediğin sırayla sürdürebilirsin. Ders, bütün etkinlikleri cevapladığında tamamlanır.