fax line prompt injection

Your Fax Line Could Let Hackers Hijack AI Agents

Picture a scanned page arriving on your company’s fax number overnight. Nobody sits at the machine anymore. Software collects the pages, converts them to text, and hands that text to a model with a simple brief: sort it, summarize it, maybe act on it.

Near the bottom of page two, in small type, one line is addressed to the model instead of to you.

That’s the whole attack. No exploit kit, no stolen credentials.

The version everyone already defends against

Most prompt injection talk starts at the browser. An agent researches something, fetches a page, and the page carries instructions meant for the agent rather than the reader. Defenders know this one well, and it gets most of the budget.

The stakes explain the attention. Prompt injection is the number-one risk in the OWASP Top 10 for LLM Applications 2025, filed as LLM01. Then, in December 2025, the UK’s National Cyber Security Centre argued that prompt injection may never be totally mitigated the way SQL injection can be, because a language model draws no inherent line between data and instruction. Its advice was to stop hoping for a clean fix. Treat the model as an “inherently confusable deputy”, and work on reducing the risk and the impact instead. 

Hold onto that last part. If you can’t stop every injection, the question that matters is what the agent is allowed to do afterward.

Faxes are text an outsider chose

Email gets plenty of scrutiny. Faxes get far less, and an inbound fax is a document from someone outside your company who needed no account, no approval and no prior relationship. They needed a number. Companies usually print theirs on a website.

For decades that didn’t matter. A fax went into a tray and a person read it. The person was the parser, and a human who reads “ignore your previous instructions” on a sheet of paper just shrugs.

Now some of those pages go to software. Optical character recognition turns them into text, and the text lands in a model’s context. At that moment an unauthenticated stranger has written into your agent’s working memory.

It doesn’t take a clever attacker. Instructions in the body. Instructions in a footer set in tiny type. Instructions inside an image, since OCR reads whatever it can recognize, whether or not a person would ever notice it.

Why it’s a different animal than a web page

PathWho can put text thereWho decides the agent reads it
Web pageAnyone who publishes oneThe agent, so you can restrict where it browses
EmailAnyone with the addressYour inbox rules and filters
Inbound faxAnyone with the numberNobody. It just arrives.

Three things tilt the field toward the attacker.

First, the sender is unauthenticated by design. Browsing is something your agent chose to do. A fax is something done to you, and you can’t make the number private without making it useless.

Second, the channel often carries authority. Organizations lean on faxes for signed forms, authorizations, and notices. A system built to act on faxes acts on exactly the documents a forger would most like to fake.

Third, almost nobody has audited it. Plenty of teams pen-test their web ingestion. Few have a threat model for the fax line, because until recently it fed a human being. Government guidance is starting to name the pattern, though: one roundup of agency deployments flags indirect injection through resident-submitted PDFs as an attack surface that legacy tooling misses.

Nobody drew that line on a diagram.

What a real defense looks like

Here’s the counterintuitive part: the best defense doesn’t depend on catching the injection. Chasing malicious wording is a losing game. The sturdier move is to treat the content as data, structurally, so no phrasing inside it can change what the system does.

Fax for Agents takes that approach, according to its own documentation. The text of a received fax comes back under an untrusted label on every MCP result and renders as plain text, never as a heading, link, or button. The calling code knows what it’s holding.

A label alone is a polite request, though. What makes it real is enforcement, and the vendor describes three pieces. The policy engine takes its inputs from the quote and the document record, never from prompt text, so a line like “ignore the budget” changes nothing. An agent’s key never receives the scopes that write budgets, policies, or approvals, and the server refuses those routes to any key tied to an agent, even one minted with every scope. And each approval binds to a single document hash, destination, sender number, amount, and page count, with an expiry matching a ten-minute quote. Change the document after approval, and the send fails with a hash mismatch.

Now rerun the attack. A fax tells the agent to forward a document to a number it has never seen. That destination isn’t in any policy, and the agent can’t add one. The injection might even persuade the model and still go nowhere. It’s the “reduce the impact” idea made concrete: assume the model can be fooled, then make fooling it not enough.

Consumer products are drifting the same way. OpenAI’s always-on dots use read-only tools during background research, so an agent reading untrusted content can’t message anyone while it does.

Audit your own stack

The lesson isn’t really about faxes. Make a list of every path by which text reaches your model’s context, boring ones included: file uploads, OCR output, calendar invites, support tickets, webhook payloads, even filenames.

For each path, write down who can put text on it. If the answer is “anyone,” you’ve found a prompt injection channel, however harmless it looks.

Then ask two things:

  1. What is the agent permitted to do after reading it?
  2. Where does that permission get enforced?

A limit in a system prompt is a preference. A limit the service checks before it acts is a limit.

Then keep testing. A new data source or an edited prompt can open a path you already cleared, which is why continuous automated red teaming retests for injection whenever the inputs change.

The fax line makes a good test case precisely because it’s dull. If you’ve got another channel in your stack that mixes strangers with authority, find it before somebody else does.

Related: Zero Trust for AI Agents: How to Secure Systems That Act on Their Own

Tags: