1-SEC contributors · Reviewed · Module: data_poisoning

Model Artifact Inspection: Pickle Indicators and SafeTensors Bounds

Model download handling inspects supplied artifact bytes without deserializing the model.

What 1-SEC checks

Model download handling inspects supplied artifact bytes without deserializing the model. Pickle checks look for a fixed set of execution-related text indicators and some binary-protocol cues. Filename-selected structural checks examine Pickle-like headers or SafeTensors metadata. The SafeTensors path reads the little-endian header size, parses the JSON tensor entries, checks shapes using the implemented rank/element guards and requires each data-offset pair to be nonnegative, ordered and within the supplied artifact payload size.

Read the implementation: handleModelSupplyChain

Required telemetry and context

Relevant input events: model_download, model_registry. Use a trusted producer at the real application boundary.

  • model_name
  • filename / artifact_name
  • RawData (artifact bytes)
  • artifact_preview / model_preview / model_config / content

Field names above describe relevant context, not a complete API request. Consult the current event contract for envelope and detail requirements. Preserve booleans, numbers, and strings as the receiving handler expects them. Agent-provided text cannot independently verify identity or authorization.

Deployment, prevention, and response

Send exact artifact bytes and the actual filename from an isolated promotion workflow. Never deserialize an untrusted model to prepare scanner input. Keep your production loader and SafeTensors library current and apply its full parser validation independently. Compare a known malformed header, out-of-range offsets and a rank-nine fixture with the bounded valid fixture. Refuse suspect artifacts in the trusted loader or release gate; an emitted alert does not block an import or execute safe remediation by itself.

Record the source event, affected agent/host, actual target, policy decision, and response result. Review enforcement configuration separately from detection. A recommendation, selected action, dry-run record, and completed action are different outcomes.

Reproduce the source fixtures

From a checkout of the linked 1-SEC source revision, run the selected fixtures with the repository's Go toolchain. These commands run tests; they do not execute a real attack against your systems.

go test ./internal/modules/datapoisoning -run '^(TestGuard_HandleEvent_ModelDownload_PickleRCE|TestGuard_HandleEvent_ModelDownload_TruncatedPickle|TestGuard_HandleEvent_ModelDownload_InvalidSafeTensors|TestGuard_HandleEvent_ModelDownload_SafeTensorsRankAnomaly|TestGuard_HandleEvent_ModelDownload_SafeTensorsOffsetsAnomaly|TestGuard_HandleEvent_ModelDownload_ValidSafeTensors)$' -count=1

Fixtures supply inert byte arrays and synthetic SafeTensors headers to the real handler. They verify specific alert types and a structural benign control; they do not execute Pickle payloads, load a model or establish complete format conformance.

TestGuard_HandleEvent_ModelDownload_PickleRCE

Full fixture and assertions — run in its original package with its helpers.

func TestGuard_HandleEvent_ModelDownload_PickleRCE(t *testing.T) {
	cp := makeCapturingPipeline()
	g := startedModuleWithPipeline(t, cp)
	defer g.Stop()

	ev := core.NewSecurityEvent("test", "model_download", core.SeverityInfo, "model download")
	ev.Details["model_name"] = "helper-model"
	ev.Details["registry"] = "huggingface"
	ev.Details["author"] = "attacker"
	ev.Details["signature"] = "sig"
	ev.Details["artifact_name"] = "weights.pkl"
	ev.RawData = []byte{0x80, 0x04, 'c', 'o', 's', '\n', 's', 'y', 's', 't', 'e', 'm', '\n', 'R'}
	ev.SourceIP = "10.0.0.1"

	if err := g.HandleEvent(ev); err != nil {
		t.Fatalf("HandleEvent() error: %v", err)
	}

	if !cp.hasAlertType("model_pickle_rce") {
		t.Error("expected model_pickle_rce alert type")
	}
}
TestGuard_HandleEvent_ModelDownload_TruncatedPickle

Full fixture and assertions — run in its original package with its helpers.

func TestGuard_HandleEvent_ModelDownload_TruncatedPickle(t *testing.T) {
	cp := makeCapturingPipeline()
	g := startedModuleWithPipeline(t, cp)
	defer g.Stop()

	ev := core.NewSecurityEvent("test", "model_download", core.SeverityInfo, "model download")
	ev.Details["model_name"] = "tiny-pickle"
	ev.Details["registry"] = "registry"
	ev.Details["artifact_name"] = "weights.pkl"
	ev.RawData = []byte{0x80, 0x04}
	ev.SourceIP = "10.0.0.1"

	if err := g.HandleEvent(ev); err != nil {
		t.Fatalf("HandleEvent() error: %v", err)
	}

	if !cp.hasAlertType("model_artifact_structure") {
		t.Error("expected model_artifact_structure alert for truncated pickle artifact")
	}
}
TestGuard_HandleEvent_ModelDownload_InvalidSafeTensors

Full fixture and assertions — run in its original package with its helpers.

func TestGuard_HandleEvent_ModelDownload_InvalidSafeTensors(t *testing.T) {
	cp := makeCapturingPipeline()
	g := startedModuleWithPipeline(t, cp)
	defer g.Stop()

	ev := core.NewSecurityEvent("test", "model_download", core.SeverityInfo, "model download")
	ev.Details["model_name"] = "broken-safe"
	ev.Details["registry"] = "huggingface"
	ev.Details["author"] = "builder"
	ev.Details["artifact_name"] = "weights.safetensors"
	ev.RawData = []byte{0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, '{', '"', 'a', '"', ':', '1', '}'}
	ev.SourceIP = "10.0.0.1"

	if err := g.HandleEvent(ev); err != nil {
		t.Fatalf("HandleEvent() error: %v", err)
	}

	if !cp.hasAlertType("model_artifact_structure") {
		t.Error("expected model_artifact_structure alert for invalid safetensors header")
	}
}
TestGuard_HandleEvent_ModelDownload_SafeTensorsRankAnomaly

Full fixture and assertions — run in its original package with its helpers.

func TestGuard_HandleEvent_ModelDownload_SafeTensorsRankAnomaly(t *testing.T) {
	cp := makeCapturingPipeline()
	g := startedModuleWithPipeline(t, cp)
	defer g.Stop()

	header := `{"embedding":{"dtype":"F32","shape":[1,1,1,1,1,1,1,1,1],"data_offsets":[0,4]}}`
	ev := core.NewSecurityEvent("test", "model_download", core.SeverityInfo, "model download")
	ev.Details["model_name"] = "hostile-embedding"
	ev.Details["registry"] = "huggingface"
	ev.Details["signature"] = "sig"
	ev.Details["artifact_name"] = "weights.safetensors"
	ev.RawData = makeSafeTensorsArtifact(header, 4)

	if err := g.HandleEvent(ev); err != nil {
		t.Fatalf("HandleEvent() error: %v", err)
	}
	if !cp.hasAlertType("model_artifact_structure") {
		t.Fatal("expected model_artifact_structure alert for rank-9 safetensors tensor")
	}
}
TestGuard_HandleEvent_ModelDownload_SafeTensorsOffsetsAnomaly

Full fixture and assertions — run in its original package with its helpers.

func TestGuard_HandleEvent_ModelDownload_SafeTensorsOffsetsAnomaly(t *testing.T) {
	cp := makeCapturingPipeline()
	g := startedModuleWithPipeline(t, cp)
	defer g.Stop()

	header := `{"embedding":{"dtype":"F32","shape":[1],"data_offsets":[0,4096]}}`
	ev := core.NewSecurityEvent("test", "model_download", core.SeverityInfo, "model download")
	ev.Details["model_name"] = "truncated-embedding"
	ev.Details["registry"] = "huggingface"
	ev.Details["signature"] = "sig"
	ev.Details["artifact_name"] = "weights.safetensors"
	ev.RawData = makeSafeTensorsArtifact(header, 4)

	if err := g.HandleEvent(ev); err != nil {
		t.Fatalf("HandleEvent() error: %v", err)
	}
	if !cp.hasAlertType("model_artifact_structure") {
		t.Fatal("expected model_artifact_structure alert for out-of-range safetensors offsets")
	}
}
TestGuard_HandleEvent_ModelDownload_ValidSafeTensors

Full fixture and assertions — run in its original package with its helpers.

func TestGuard_HandleEvent_ModelDownload_ValidSafeTensors(t *testing.T) {
	cp := makeCapturingPipeline()
	g := startedModuleWithPipeline(t, cp)
	defer g.Stop()

	header := `{"embedding":{"dtype":"F32","shape":[1],"data_offsets":[0,4]}}`
	ev := core.NewSecurityEvent("test", "model_download", core.SeverityInfo, "model download")
	ev.Details["model_name"] = "clean-embedding"
	ev.Details["registry"] = "huggingface"
	ev.Details["signature"] = "sig"
	ev.Details["artifact_name"] = "weights.safetensors"
	ev.RawData = makeSafeTensorsArtifact(header, 4)

	if err := g.HandleEvent(ev); err != nil {
		t.Fatalf("HandleEvent() error: %v", err)
	}
	if cp.hasAlertType("model_artifact_structure") {
		t.Fatal("did not expect model_artifact_structure alert for valid safetensors artifact")
	}
}

Tuning, evaluation, and coverage limits

Binary inspection is limited to the first 1 MiB; the SafeTensors header limit is 512 KiB. Rank above eight and shapes exceeding 100 million elements are product heuristics, not a universal SafeTensors format requirement. Passing these checks does not certify a file as safe or fully validate dtype byte counts, cross-tensor overlap, complete payload indexing or model semantics. Supplied preview strings are not equivalent to inspecting all bytes. A .pt artifact need not be a plain binary Pickle stream, so the filename heuristic can flag legitimate containers. A clean structural fixture asserts only absence of the structural alert, not absence of every registry signal.

Evaluate this behavior with representative authorized activity and a controlled known-positive case. Investigate the exact rule, inputs, and state before suppressing an alert. Do not assume a hard-coded heuristic is a configurable setting. Measure your own deployment; the source fixtures do not establish a benchmark, detection rate, compliance certification, or incident-prevention claim.

Protocol and format references

These references describe the underlying format or protocol. The implementation and fixtures above define the subset 1-SEC actually checks.

Related implemented controls

Implementation reviewed at source revision a2ab27289e0fbbce555ad80f31eb19bfffa86f84. Recheck the actual release and integration before deployment. Sources and corrections policy.