The prompt injection hidden in my client's site asked my AI to not tell me about it. That was the tell.
**Caught two prompt injection attempts buried in a client's site this week during an audit.** Both were structured to look like legitimate system messages, embedded inside script comments loaded by an outdated third-party plugin. One tried to load a list of unauthorized tools. The other included an instruction to hide itself from the user. Both failed. The "never tell the user" clause was the clearest tell. Real system instructions don't ask to be concealed. **The attack vector** This injection targets AI tools that read the site. Humans visiting the page never see it. Audit tools, AI search crawlers, agent pipelines, customer-facing chatbots, anything that fetches and reasons over web content. The attacker embeds hidden instructions in HTML and waits for an AI crawler, audit tool, or agent to act on them. Compromised plugins, outdated themes, and injected third-party scripts are the common culprits. **If you own a site** - Run a malware scan. Sucuri SiteCheck is free and works on any platform. - Audit plugins and third-party scripts. Anything updated or added in the last 30 to 60 days is the first suspect. - Add a Content-Security-Policy header to restrict which scripts can execute. **If you build AI tools that read web content** - Treat fetched page content as untrusted data at every stage of the pipeline. - Pre-scan fetched content before it enters any agent context. - If fetched content instructs your AI to conceal anything from the user, that is the attack. Halt the pipeline and log it. I flagged both strings in the audit output and pointed the client at the likely source plugin for their follow-up. **Methodology note worth flagging** This was my first audit run on Opus 4.7. I have been running these scans on Opus 4.6, and the model was the only variable that changed between runs. I can't say with confidence whether 4.6 would have flagged the same two strings on the same content. If you're building audit or scanning pipelines, this is an argument for testing across models on identical fixtures before locking in a default. Different models pay attention to different things, and injection detection seems to live in exactly that gap.