IVIS
ResearchJuly 20269 min read

Every Injection Becomes a Test

Continuous adversarial testing and a red-team regression corpus — how a security posture stays true after launch, not just at it

By the ZIVIS Research Team

Every prompt-injection defense you ship is verified at a single point in time. You test the guardrail, confirm the privilege boundary holds, watch a red-team attempt bounce off — and then you deploy. The problem is that the system you secured is not the system that runs six weeks later. The model got updated. Someone edited the system prompt. A new tool got wired in. Every one of those changes is a chance to quietly reopen a hole you already closed.

There is exactly one control that fixes this, and it is the least glamorous item in the whole catalog: continuous adversarial testing backed by a red-team regression corpus. Every real injection becomes a durable test. The tests run on every build. An attack that worked once can never silently work again.


The mandate: treat the model as an untrusted user

OWASP's LLM01 (2025) is explicit about this. It tells you to treat the model as an untrusted user and to run regular adversarial tests — not a launch-day pentest, but an ongoing practice. The reasoning is the same one that runs through this entire series: prompt injection isn't reliably detectable from the text, so you can't prove a system is safe by inspection. You can only prove it empirically, by attacking it — and you have to keep attacking it, because the system keeps changing.

The corpus: turn every real attack into a permanent test

The mechanism is a version-controlled regression corpus. Every injection you actually catch — an abuse pattern in production logs, a finding from a pentest, a bug-bounty report — gets distilled into a reproducible test case and checked in. The case captures the attack, the context it exploited, and the behavior that counts as a pass or a fail.

This is the same discipline that made regression testing standard practice in the rest of software engineering: a bug isn't closed when you patch it, it's closed when a test guarantees it can't come back. The only twist is that the “bug” is an adversarial input and the assertion is about model behavior.

The gate: run it on every build, and block on failure

The corpus is worthless if it only produces a dashboard. The corpus runs in CI on every build, and it gates the deploy. Change the model, edit a prompt, add a tool — the entire attack history you have ever survived replays before anything ships. If a known attack regresses, the build blocks and someone triages. The loop closes when a newly observed attack in production feeds straight back into the corpus.

One implementation detail that is not optional: LLM behavior is non-deterministic, so a single pass is not proof and a single fail is not always a regression. Each case has to run enough times to gate on a rate, not a coin flip. Get that wrong and you trade flakiness for false confidence — the corpus goes green for the wrong reason.

The honest limitations

We are not going to oversell this either. A corpus is a record of the past, and testing only catches what you thought to test. Three limits are structural:

  • Novel variants slip through. A genuinely new technique — a new encoding, a new framing — passes the whole suite until someone adds it. Coverage is a lagging indicator, which is why this pattern needs active red teaming feeding it, not just replaying old wins.
  • Thresholds, not checkmarks. Non-determinism means every case is a statistical claim. You run it N times and gate on a pass rate, or the gate is lying to you.
  • The corpus rots without an owner. Cost is medium and forever. Flaky cases get skipped, the gate gets downgraded to advisory, and an untended suite becomes theater. Someone has to own it.

Why this is the last pattern

OWASP LLM01 makes the point that ties this whole catalog together: no single control is sufficient. Defense-in-depth is the answer — input validation, output filtering, least-privilege tooling, human approval on high-risk actions, segregation of untrusted content, constrained output formats, and pen testing, layered together. We have spent this series walking through those layers one at a time.

Continuous adversarial testing is the pattern that keeps all of them true. Every other defense is a control you install once; this is the control that verifies the others still hold after every change. It is why the catalog is a living posture and not a launch-day snapshot — and it is exactly where our own red-teaming practice fits. We generate the adversarial cases, feed the ones that land into your regression corpus, and wire the gate so a bypass we found can never quietly return.

This is the final pattern in our Defense Architecture catalog. The pattern page for Adversarial Testing & Regression has the loop diagram, trust boundaries, and threat surface in full.

Does your posture survive the next model update?

Run a free automated review, or talk to the team about building a red-team regression corpus for your LLM system.