◄ ALLE POSTS
AI Security

Open-Source-Modelle und ihre Gefahren: Modelldateien prüfen

NW Nils Weiser •11 OCT 2026 •—

Ein KI-Modell ist ein neuronales Netz: eine Architektur, die festlegt, wie gerechnet wird, und Millionen bis Milliarden gelernter Zahlenwerte, die Gewichte. Die Datei, in der es geliefert wird, kann aber mehr enthalten: Anweisungen, die beim Laden ausgeführt werden. Wer eine fremde .pt-Datei ungeprüft lädt, startet im schlimmsten Fall ein Programm, das jemand anderes geschrieben hat.

Auf Hugging Face liegen mehr als zwei Millionen öffentliche Modelle, und die meisten Teams laden sie mit demselben Vertrauen wie ein npm-Paket. Dieser Post ist der Deep Dive zu Modelldateien: welche Formate was ausführen können, was Scanner übersehen und wie du ein fremdes Modell prüfst, bevor es in Produktion geht. Den Überblick über die ganze Lieferkette, von Daten bis zu Agenten-Werkzeugen, gibt es in Die neue Gefahr der AI Supply Chain.

Wann eine Modelldatei zum Programm wird

Viele Modellformate basieren auf Pythons Pickle. Pickle speichert nicht nur Werte, sondern eine Folge von Anweisungen, mit denen ein Objekt wieder aufgebaut wird. Über die Methode __reduce__ darf ein Objekt dabei eine beliebige Funktion mit beliebigen Argumenten benennen, und der Loader ruft sie auf. Die Python-Dokumentation sagt es ohne Umschweife: Das Modul ist nicht sicher, entpackt werden sollen nur Daten, denen man vertraut.

import os, pickle

class Model:
    def __reduce__(self):
        # beliebiger Befehl
        return (os.system, ("id",))

# sieht aus wie ein Modell
pickle.dump(Model(), open("model.pkl", "wb"))
# führt den Befehl aus
pickle.load(open("model.pkl", "rb"))

Das Format entscheidet also, was beim Laden passieren kann:

Format Was beim Laden passiert Was bleibt
.pkl, .pt, .bin
Pickle
Beliebiger Code kann laufen, sobald die Datei geladen wird. hoch Nur laden, was du wie eigenen Code behandeln würdest.
.safetensors JSON-Header plus rohe Tensor-Daten, nichts Ausführbares. Ein Audit von Trail of Bits fand 2023 keine kritische Lücke, die zu Code-Ausführung führt. niedrig Die Gewichte selbst können trotzdem einen Backdoor tragen.
.h5, .keras
Keras
Lambda-Layer// Lambda-LayerBaustein in Keras-Modellen, der beliebigen Python-Code als Rechenschritt einbettet. Gespeichert wird er als Bytecode, der schon beim Laden des Modells ausgeführt werden kann.BeispielEin Layer mit dem harmlosen Namen scale_inputs, der nebenbei eine Verbindung nach außen öffnet. bringen Python-Code in die Architektur (CVE-2024-3660). mittel Layer prüfen, Keras aktuell halten.
.gguf// GGUFDateiformat für Sprachmodelle, die lokal laufen, zum Beispiel mit llama.cpp. Kein Pickle. Aber die Datei enthält ein Chat-Template: In llama-cpp-python führte das zu Code-Ausführung (CVE-2024-34359), und Pillar Security zeigte 2025 Templates, die zur Laufzeit Anweisungen einschleusen. mittel Template lesen, Runtime patchen.

Zwei Dinge gehen dabei gern unter. Erstens: weights_only=True ist seit PyTorch 2.6 der Default und schränkt den Unpickler ein. Eine Garantie ist das nicht: CVE-2025-32434 erlaubte bis Version 2.5.1 Code-Ausführung trotz gesetztem Flag. Zweitens: Safetensors schützt vor Code beim Laden, nicht vor dem, was in den Gewichten gelernt wurde.

Code in der Architektur: Keras Lambda-Layer

Pickle ist nicht der einzige Weg, Code in ein Modell zu bringen. Keras kennt Lambda-Layer: Bausteine, die einen beliebigen Python-Ausdruck als Rechenschritt ins Modell einhängen. Gespeichert werden sie laut Keras-Dokumentation als Python-Bytecode, und die nennt das selbst „potentially unsafe“.

Die Folge beschreibt CERT/CC nüchtern: Wer ein fremdes Keras-Modell lädt, führt unter Umständen fremden Code aus. Keras 3 weigert sich deshalb standardmäßig, Lambda-Layer zu laden, deren Funktion als Bytecode gespeichert ist (safe_mode). Zwei Lücken bleiben. Bei Keras 2 und bei Keras 3 vor Version 3.12 greift diese Prüfung für das klassische .h5 nicht, so beschreibt es auch CERT/CC. Erst seit 3.12 vom Oktober 2025 reicht Keras safe_mode an den H5-Loader durch. Und der Schutz selbst wurde 2025 umgangen: CVE-2025-1550 erlaubte Code-Ausführung trotz eingeschaltetem safe_mode.

Ein Formatwechsel hilft hier nicht: Safetensors speichert nur Gewichte, die Architektur steckt weiter in der Keras-Datei oder im Code. Was hilft, ist ein Blick auf die Layer-Liste, bevor das Modell geladen wird. ModelScan sucht in .h5-Dateien gezielt nach Lambda-Layern (Installation mit den Extras modelscan[tensorflow,h5py]). Jeder Lambda- oder Custom-Layer in einem Modell, das du nicht selbst gebaut hast, ist ein Grund nachzufragen.

Was mit Modelldateien schon passiert ist

JFrog fand im Februar 2024 rund 100 Modelle auf Hugging Face, die beim Laden Code ausführten, darunter eines mit Reverse Shell// Reverse ShellDer befallene Rechner baut selbst eine Verbindung zum Angreifer auf und gibt ihm eine Kommandozeile.. JFrog merkt selbst an, dass die meisten dieser Payloads// PayloadDer Teil eines Angriffs, der den eigentlichen Schaden anrichtet. Hier: der eingeschleuste Code. Tests von Forschern oder Bug-Bounty-Jägern sein dürften. Das Prinzip funktioniert trotzdem.

Drei Entwicklungen seit 2025 machen die Lage schwieriger.

1 // Scanner lassen sich austricksen

Hugging Face scannt hochgeladene Dateien, sagt aber selbst, das sei nicht hundertprozentig sicher. ReversingLabs beschrieb im Februar 2025 zwei Modelle (nullifAI), die mit 7z statt ZIP gepackt waren und deren Pickle-Stream direkt nach dem Payload abbricht. Als unsicher markiert wurden sie nicht, der Payload lief trotzdem. Im selben Jahr meldeten Sonatype vier und JFrog drei weitere Umgehungen des Scanners picklescan. Ein grüner Haken auf der Plattform ist ein Hinweis, kein Befund.

2 // Namen sind kein Herkunftsnachweis

PoisonGPT zeigte 2023 das Prinzip: ein gezielt verfälschtes Modell, hochgeladen unter EleuterAI statt EleutherAI. Unit 42 beschrieb 2025 Model Namespace Reuse: Wird ein Autor-Account gelöscht oder übertragen, kann jemand den alten Namen neu registrieren, und jede Pipeline, die Modelle nur per Name lädt, zieht das fremde Modell. Betroffen waren laut Unit 42 auch Googles Vertex AI und Microsofts Azure AI Foundry. Im Mai 2026 erreichte ein Repository, das ein OpenAI-Release imitierte, Platz 1 der Hugging-Face-Trends, bevor es gesperrt wurde. Die Downloadzahlen waren laut HiddenLayer so gut wie sicher künstlich aufgebläht.

3 // Adapter und Konverter

Ein Modell kommt selten allein. LoRA-Adapter// LoRA-AdapterKleine Zusatzdatei, die ein Basismodell für eine Aufgabe anpasst, ohne es neu zu trainieren.BeispielEin Adapter, der ein allgemeines Sprachmodell auf Support-Antworten trimmt. werden wie Modelle geteilt, und Forscher zeigten, dass sich ein Backdoor einmal in einen Adapter trainieren und dann ohne weiteres Training mit anderen Adaptern zusammenführen lässt. Die OWASP Top 10 für LLM-Anwendungen führen verwundbare LoRA-Adapter deshalb als eigenes Supply-Chain-Risiko. HiddenLayer zeigte 2024, dass sich der Safetensors-Konvertierungsdienst von Hugging Face kapern ließ, um Pull Requests im Namen des offiziellen Bots zu stellen. Alles, was durch eine fremde Pipeline gelaufen ist, ist ein neues Artefakt.

Risiko, Maßnahme, Tool

Die Kurzfassung als Tabelle. Alle genannten Tools sind Open Source.

Risiko Maßnahme Tools
Code in der Modelldatei Safetensors als einziges erlaubtes Format. Pickle nie ungeprüft laden. PyTorch ab 2.6. safetensors, Fickling, ModelAudit, ModelScan, picklescan
Logik in der Architektur Layer vor dem Laden auflisten. Keras safe_mode an lassen und Keras aktuell halten. ModelScan, h5py
Ausgetauschte Datei Hash und Revision pinnen, Signatur prüfen. sha256sum, revision= mit vollem Commit-Hash, OpenSSF Model Signing
Gefälschte oder übernommene Repos Allowlist für Organisationen. Produktion lädt nur aus der eigenen Registry, nie per Name vom Hub. Interne Model Registry, Commit-Pinning
Payload feuert beim Laden Erstes Laden nur in einer Sandbox ohne Netzwerk, mit Telemetrie. Container ohne Egress, sys.addaudithook
Backdoor in den Gewichten, vergiftete Daten Eigene Evals mit Fällen, deren richtige Antwort du kennst. Red Teaming vor dem Rollout. garak, promptfoo
Adapter und konvertierte Modelle Wie ein neues Modell behandeln: dieselben Gates, eigener Scan, eigene Freigabe. Dieselben Scanner wie oben

Pakete, Anbieter und Agenten-Werkzeuge bringen eigene Risiken mit. Die stehen im Überblick: Die neue Gefahr der AI Supply Chain.

Drei Einschränkungen, die in keiner Tool-Liste stehen

Kein Scanner ist vollständig. Fickling warnt selbst, dass eine Datei trotz bestandenem Check unsicher sein kann, und das letzte ModelScan-Release stammt vom Februar 2026. Plane zwei Scanner ein, nicht einen. Audit-Hooks sind laut Python-Doku keine Sandbox, bösartiger Code kann sie sogar abschalten: Sie liefern Telemetrie, die Isolation kommt vom Container. Und pip-audit findet bekannte Schwachstellen, keine bösartigen Pakete. Die Doku sagt das ausdrücklich.

Eine Intake-Pipeline in fünf Gates

Einzelne Tools helfen wenig, wenn ein Modell an ihnen vorbei in Produktion kommt. Das Gegenmittel ist ein fester Aufnahmeprozess: fünf Gates, durch die jedes Artefakt muss, egal wie gut der Ruf der Quelle ist.

GATE 1 QUARANTÄNE GATE 2 HERKUNFT GATE 3 INTEGRITÄT GATE 4 SCAN GATE 5 FREIGABE ohne Netzzugang Org, Historie, Card Hash + Signatur Datei, Layer, Deps interne Registry ein Fehlschlag an einem Gate = Ablehnung

Fünf Gates vom Download bis zur Freigabe. Produktion lädt nur, was Gate 5 passiert hat.

Selbst ausprobieren: der Scan in drei Minuten

Du brauchst ein Terminal (macOS oder Linux, unter Windows WSL) und Python 3.10 bis 3.12. Die drei Scanner kommen per pip, am besten in eine frische virtuelle Umgebung:

python3 -m venv .venv
source .venv/bin/activate
pip install fickling modelscan modelaudit

Dann baust du eine harmlose Testdatei. Sie nutzt denselben Trick wie oben, der Befehl gibt aber nur ein Wort aus:

python3 - <<'EOF'
import os, pickle

class Model:
    def __reduce__(self):
        return (os.system, ("echo pwned",))

pickle.dump(Model(), open("test.pkl", "wb"))
EOF

Jetzt prüfst du die Datei, ohne sie zu laden:

# Bordmittel: zeigt die Anweisungen im Pickle
python3 -m pickletools test.pkl

# übersetzt das Pickle zurück in Python und bewertet es
fickling --check-safety -p test.pkl

# scannen und Schweregrad vergeben
modelscan -p test.pkl
modelaudit test.pkl

Alle drei Scanner schlagen an. Fickling nennt die Datei „overtly malicious“, ModelScan meldet:

Unsafe operator found:
  - Severity: CRITICAL
  - Description: Use of unsafe operator 'system' from module 'posix'

posix ist das Modul, das auf macOS und Linux hinter os.system steckt. Entscheidend ist, was du dabei nicht getan hast: Du hast die Datei nie mit pickle.load() geöffnet.

Am echten Projekt

Die Werkzeuge bleiben dieselben. Geladen wird mit festgenagelter Version, hier mit der Bibliothek transformers. org/model steht für den Namen des Repositories auf Hugging Face, den Commit-Hash findest du in dessen Historie:

from transformers import AutoModel

model = AutoModel.from_pretrained(
    "org/model",
    # voller Commit-Hash, nicht "main"
    revision="877b84a8f93f2d619faa2a6e514a32beef88ab0a",
    use_safetensors=True,     # kein Pickle
    trust_remote_code=False,  # Default, bewusst so lassen
)

Der Commit-Hash ist dabei mehr als Kosmetik. Fehlt im Repository eine Safetensors-Datei und ist die Revision nicht gepinnt, versucht transformers eine automatische Konvertierung über den Pull-Request-Branch des Konvertierungs-Bots von Hugging Face, also genau den Dienst aus „Silent Sabotage“. Mit festem Commit-Hash passiert das nicht. Und ohne use_safetensors=True fällt die Bibliothek still auf die Pickle-Datei zurück.

Die Prüfungen aus Gate 3 und 4 laufen im Projektordner, in dem die requirements.txt liegt:

# Gate 3: Hash mit dem veröffentlichten Wert vergleichen
sha256sum model.safetensors

# Gate 4: Repository vom Hub holen, statisch scannen
modelaudit hf://org/model

# Gate 4: Abhängigkeiten auf bekannte Lücken prüfen
pip install pip-audit
pip-audit -r requirements.txt

# Gate 4: Stückliste erzeugen und prüfen
syft . -o cyclonedx-json=sbom.json
grype sbom:./sbom.json

Drei Hinweise dazu. Syft und Grype sind eigene Programme, kein Python-Paket. Auf dem Mac installierst du sie mit brew install syft grype. Auf älteren macOS-Versionen heißt sha256sum stattdessen shasum -a 256. Und sobald jede Zeile deiner requirements.txt einen Hash trägt, erzwingt pip-audit --require-hashes -r requirements.txt den strengen Modus. Ohne Hashes bricht dieser Aufruf ab.

Eine Signatur lässt sich nur prüfen, wenn der Herausgeber eine veröffentlicht hat. Dann brauchst du die Signaturdatei, die erwartete Identität des Herausgebers und dessen Login-Dienst:

pip install model-signing
model_signing verify ./model --signature model.sig \
  --identity "releases@example.org" \
  --identity_provider "https://accounts.example.org"

Für Adapter und konvertierte Modelle gilt derselbe Weg. Was sich bei API-Modellen, MCP-Servern und Prompt-Templates ändert, steht im Überblick: Die neue Gefahr der AI Supply Chain.

Was kein Tool löst

Drei Dinge bleiben übrig, egal wie gut die Pipeline ist.

Womit ich anfangen würde, wenn es noch gar nichts gibt:


Quellen:

JFrog: Malicious HF models ReversingLabs: nullifAI Sonatype: picklescan bypasses Unit 42: Namespace Reuse HiddenLayer: Silent Sabotage LoRATK Pillar: GGUF templates CERT/CC: Keras Lambda layers Safetensors audit PyTorch: CVE-2025-32434 OWASP LLM03:2025 Supply Chain OpenSSF Model Signing

Du willst wissen, was in eurer Modell- und Agenten-Lieferkette wirklich steckt? Lass uns sprechen. In 30 Minuten gehen wir unverbindlich die fünf Gates für euren Stack durch.

NW
Nils WeiserAI Agent Specialist · Bodenseeraum
MIT MIR ARBEITEN ▸

Weitere Field Notes

ALLE POSTS ▸