FinePrint
ShippedA public test range where harmless hidden instructions in ordinary-looking pages show whether an AI browser agent can be hijacked. Visitors get a live console, a scorecard and a leaderboard.
- Stack
- Cloudflare Workers, D1, Astro, React
- What it proves
- Security thinking, a Cloudflare Worker and D1 backend, an Astro and React frontend, and data visualisation.
What it is
AI browser agents read web pages and act on them. A page can carry instructions meant for the agent rather than the person: text a reader never sees, but a model reads and might follow. FinePrint is a public range of ordinary-looking pages that carry such instructions, so anyone can point an agent at them and see whether it gets hijacked.
Visitors get a live console that shows what the agent did on each page, a scorecard for the run, and a leaderboard that compares agents across runs.
How it is kept safe
Every payload on the range is harmless. A successful hijack proves the agent followed an instruction it should have ignored, and nothing more: no data leaves the visitor’s machine and nothing is damaged.
Findings go to the agent’s vendor before they are published.
What the range tests, by category
The techniques are described here as categories only. This page is a description of the range, not a playbook.
- Hidden text. Instructions present in the page but not visible to a person reading it.
- Instructions dressed as content. Text that reads as part of the page but addresses the agent.
- Instructions in page structure. Text placed where people rarely look but agents often read.
- Instructions that arrive later. Content that appears after the page first loads.
How it is built
The pages and the console are an Astro site with React islands where state changes. Runs, scores and the leaderboard are served by a Cloudflare Worker backed by a D1 database. The scorecard and leaderboard are the data visualisation side of the project: they turn a run’s raw events into something a person can compare at a glance.
What it shows about how I work
The same habit as my day job: decide what a system must refuse, make the refusal observable, and test it in public.