Prompt injection gets explained with a chat example where a user types "ignore your instructions". That is the most harmless case. The real surface is wherever content controlled by an outsider enters the prompt — and we pass the model headers, DNS records and page text from other people’s sites on every check.
Nobody has measured the share of such attempts, and the reason is honest: an attempt cannot be told from ordinary text. What is measurable is how often the model declines to answer: for us, 0.38% of live calls. And one occasion when we displayed such a refusal as an analysis is worth recounting on its own.
Free online tool — website security scanner: instant results, no signup.
Prompt injection is usually explained with a chat example: a user types "ignore your previous instructions". That is the most harmless case, because the user is attacking their own session.
The real surface appears wherever content controlled by an outsider enters the prompt. For us that happens on every tool: to explain a check result we pass the model another site’s response headers, its DNS records, its page text, the contents of its robots.txt.
All of it is written by the owner of the site being checked, not by our user. They can put any text in a response header or a meta tag — including text addressed not to a human but to the model that will read it.
This is precisely the class that stands first in OWASP’s risk list for applications built on language models. And it has an unpleasant property: no reliable technical solution exists. A model does not distinguish "data" from "instructions" — to it both are one stream of text.
The prevalence of injection attempts has been measured by nobody. No vendor and no researcher publishes what share of requests contains one. The reason is simple: counting it requires reliably telling an attempt from ordinary text, and that is exactly what nobody can do.
What is measurable is how often a model declines to answer. We log that, and across ten days of August 2026, 9,474 live calls produced 36 refusals:
| Denominator | Refusals | Share |
|---|---|---|
| All live calls | 36 of 9,474 | 0.38% |
| Article summaries at the Russian provider | 36 of 1,391 | 2.59% |
So roughly one article summary in forty is declined. All 36 cases fell on one surface and one language, and the refusal wording was identical in every one.
A caveat: a refusal is not evidence of an attack. Far more often it is a filter firing on a harmless technical subject: text about vulnerabilities, about blocking, about circumventing restrictions looks suspicious to a filter regardless of intent. We give this figure not as a measure of attacks but as the part of model behaviour a system is obliged to anticipate.
This is worth recounting, because the mistake is typical and not obvious.
Our system received an answer from the model and displayed it to the user in an "AI summary" block. When the model declined, it returned not an error but an ordinary text answer — a polite sentence about the subject not being discussed. To the code that was a successful response, and it was faithfully displayed as the result of an analysis.
The user saw, in the analysis block for their own check, a sentence along the lines of "I cannot discuss this topic". Formally the system worked correctly: the request went out, an answer came back, the answer was shown. In fact a refusal was being published in the interface as a finding.
The fix is to recognise a refusal from the answer text before it reaches the cache and the page, and in that case not to show the block at all. Such a call should also not consume the user’s quota: they received nothing.
The general lesson runs wider than injection: a successful model response does not mean a useful one. Everything arriving from a language model passes through code as an ordinary string, and no mechanism will distinguish a substantive finding from a polite refusal except a check you write yourself.
There is no universal solution, but the set of damage-limiting measures is known and it works.
To see what your site sends in headers and meta tags — that is, what somebody else’s model would read — use the header check.
Primary source on risk classification: the OWASP list for large language model applications.
The tool checks HTTP security headers, SSL/TLS configuration, server info leaks, and protection against common attacks (XSS, clickjacking, MIME sniffing). A grade fromA to F shows overall security level.
Checking Content-Security-Policy, HSTS, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, and more.
TLS version, certificate expiry, chain of trust, HSTS support.
Finding exposed server versions, debug modes, open configs, and directories.
Detailed report explaining each issue with specific steps to fix it.
HTTP header audit
config verification
CSP & HSTS setup
compliance checks
Strict-Transport-Security.Server: Apache/2.4.52 helps attackers find exploits. Hide the version.DENY or SAMEORIGIN.nosniff, browsers may misinterpret file types (MIME sniffing).Content-Security-Policy-Report-Only, monitor violations, then enforce.Server, X-Powered-By, X-AspNet-Version from responses.Security check history and HTTP security header monitoring.
Sign up freeDefence in depth: input validation + hardened system prompt + structured output + guardrails + output filter + tool sandbox + rate limit. NO single measure is enough.
Lakera Guard (commercial, best coverage). Rebuff (open Python). NVIDIA NeMo (comprehensive, complex). Combine for critical use cases.
Source whitelist, content sanitisation before embedding, embedding-space anomaly detection. 100% fix does not exist.
Log all suspicious inputs + LLM output anomalies. Alert on patterns ("ignore previous", etc). Enterno Security Scanner basic checks.
Free plan — 10 monitors, checks every 5 min, no card required. Upgrade for 1-minute interval and multi-region monitoring.