Skip to main content

Every serious development team now runs a dependency audit. Lockfiles are pinned, SBOMs are generated, CI refuses to build on a critical CVE, and somebody gets a Slack alert when a transitive package changes maintainer. That discipline took a decade to build and it works.

Then the same team downloads a 14GB model file from Hugging Face, wires it into an agent that has shell access and database credentials, and ships it. No signature check, no provenance record, no diff against a known-good artefact. The audit stops at the model boundary, and two pieces of research published this month show exactly what is sitting on the other side of it.

TL;DR

  • Researchers have demonstrated a time-release backdoor in an open-weight coding model: it behaves normally every day, then emits attacker-chosen shell commands on a specific calendar date, triggered by the date that coding harnesses inject into the system prompt.
  • A separate peer-reviewed attack implants a backdoor without touching the weights at all, by modifying the Jinja2 chat template bundled inside the model file. Poisoned artefacts passed every automated security scan on Hugging Face.
  • Triggered chat-template backdoors dropped factual accuracy from 90% to 15%, hijacked agent tool-use across 3,868 benchmark episodes, and bypassed every injection defence the researchers tested.
  • Neither attack is detectable by code review, dependency scanning, or evaluating the model on benign inputs. Dormancy is the whole design.
  • The practical controls are provenance, artefact pinning, template diffing and egress restriction, not better prompts. Treat the model file as a production dependency with a version, a source and an owner.

Two attacks, one blind spot

The first comes from an independent researcher publishing under the handle chkn_little, on 22 August 2026. Using LoRA fine-tuning on Qwen 3.5 2B, they trained a model to associate a single date, 1 September 2026, with a shell command. On every other date the model answers coding questions normally. On the trigger date it drops the backdoor command into its output.

The delivery mechanism is the elegant part. Coding harnesses such as OpenCode and OpenAI’s Codex automatically inject the current date into the system prompt, because knowing today’s date is genuinely useful. The attacker does not need to reach the running system, control the network, or get a prompt past a filter. The victim’s own tooling supplies the trigger, on schedule, for free. Across the tested prompts the backdoor fired on 87.5% of in-distribution cases and 90% of held-out cases, with zero false positives on other dates. It is quiet until it is not.

The second is more systematic. In Inference-Time Backdoors via Chat Templates (Fogel, Hofman, Cohen and Vainshtein, of Pillar Security and Fujitsu Research), the researchers point out something most teams have never considered: the chat template shipped inside a GGUF model file is not data, it is an executable Jinja2 program that runs on every single inference call. Replace it, redistribute the artefact, and you have implanted a backdoor without modifying a single weight, poisoning any training data, or touching runtime infrastructure.

The numbers are not marginal. Under trigger conditions, factual accuracy across 18 models from seven families fell from 89.6% to 14.8%. Attacker-controlled URL emission succeeded more than 80% of the time. On benign inputs the deviation was 0.017, which is to say invisible. In agentic settings the attack extracted full payment credentials during a BrowserUse checkout flow and injected malicious script tags into applications generated by OpenHands. Attack success rates on AgentDojo reached 68.9%, and 83% on Agent Security Bench. Every injection defence tested failed to stop it, and across all 3,868 episodes the backdoor stayed perfectly dormant without its trigger.

The line that should worry anyone running a model registry: the poisoned artefacts passed all automated security scans on Hugging Face. The authors describe the ecosystem-level detection capability as non-existent.

Why your existing controls do not catch this

Consider what a normal security process would do with a new model, and where each step fails.

Code review has nothing to read. There is no diff, no pull request, no suspicious function. In the time-release case the malicious behaviour is distributed across billions of floating-point numbers. You cannot grep for it.

Dependency scanning resolves package versions against advisory databases. There is no advisory database for model weights, no CVE for “this checkpoint was fine-tuned to misbehave in September”, and no upstream maintainer to publish a patch note.

Evaluation is the one that fools people, because it feels rigorous. You run your benchmark suite, the model scores well, you sign it off. But dormancy is the entire point of the design. A backdoor that degraded benign performance would be a bad backdoor, and the measured deviation of 0.017 says these are good ones. Passing your evals is evidence the attack works as intended, not evidence of safety.

Sandboxing helps less than you would hope. The chat-template paper is explicit here: the attack exploits semantic model behaviour, not unsafe code execution. A sandbox that stops a process writing to disk does not stop a model persuading your agent to make a legitimate-looking outbound request with a credential in it.

This is a different shape of problem from the training-data poisoning work that has had more attention, where roughly 250 malicious documents were enough to backdoor models regardless of size. That research required getting content into a training corpus. These attacks require only that you download something, which you were going to do anyway.

What to actually do

The honest position is that this is not a solved problem, and anyone selling you a scanner that detects backdoored weights is overselling. What you can do is reduce blast radius and establish provenance. Six controls, roughly in order of value:

1. Pin the artefact, not the name. Record the repository, revision hash and file checksum of every model in production, in version control, next to your other dependency pins. “We run Qwen 3.5” is not a version. If you cannot reproduce today’s deployment from a recorded hash, you have no baseline to detect a swap against.

2. Diff the chat template on ingest. This is the cheapest high-value control available. Extract the Jinja2 template from every model artefact and compare it against the official publisher version. Legitimate customisations do produce false positives, which is fine: a handful of reviewed exceptions beats an unexamined program running on every inference call.

3. Prefer first-party sources and signed releases. Community re-uploads, quantised conversions and abliterated derivatives are convenient and they are also the exact position in the supply chain this attack targets. A quantised repack from an unknown account is a redistribution event, and redistribution is where the template gets replaced.

4. Restrict egress rather than trusting behaviour. The observable outcome of both attacks is an outbound request or a command execution. Default-deny egress with an allowlist turns “the model emitted an attacker URL” into a blocked connection and a log line. Remove the capability, do not just discourage its use.

5. Keep credentials away from self-hosted inference. An agent holding production database or infrastructure credentials should not be running weights whose provenance you cannot state in a sentence. Separate the low-consequence workloads, where a community fine-tune is fine, from the ones with real authority attached.

6. Log and review tool calls, not just outputs. Both attacks manifest at the tool-call layer, which is exactly where prose-level output review looks fine. If you are not retaining and periodically grepping the tool-call stream for unexpected destinations and out-of-scope actions, a dormant backdoor firing once will look like a normal Tuesday.

The pattern underneath

Serverless made concurrency limits your problem. Managed CI made workflow permissions your problem. Self-hosting open-weight models makes artefact provenance your problem, and it hands that problem to teams whose supply chain instincts were built for source code, where you can at least read the thing you are installing.

The uncomfortable part is that this is not a reason to stop using open-weight models. The cost, latency and data residency arguments for self-hosting are still good, and the closed alternatives have their own dependency risks. It is a reason to extend the discipline you already apply to npm and PyPI one layer outward, to an artefact that currently arrives in most organisations with less scrutiny than a Chrome extension.

Most teams can name the model they run. Far fewer can name the revision hash, the source repository, or who last touched the template that executes on every request. That gap is the finding.

Need help closing that gap?

REPTILEHAUS builds and secures AI systems for teams that need them to work in production, not just in a demo: agent sandboxing and egress control, model provenance and artefact pinning in CI, and DevOps architecture for self-hosted inference. If you are running open-weight models with real credentials attached and you are not sure what your exposure looks like, get in touch.


📷 Photo by OSG Containers on Unsplash