Avneesh Kasture

Colophon

How this site is built, what it records, and how to tell me about a flaw.

How it is built

The site is static. It is a Jekyll project built by GitHub Pages, with kramdown for Markdown and Rouge for code highlighting. The styles are Sass compiled by Jekyll. The source is a plain repository: pages, posts, a few scripts under assets/, and nothing that runs on the server for the pages themselves.

The lab exhibits are the one exception. Their browser code calls a separate Cloudflare Worker at mcp.apkasture02.workers.dev. That Worker is also the MCP server behind /mcp/. Some exhibits use a Workers AI model, Llama 3.3 70B, as the agent you attack.

The site loads no analytics, no tracking scripts and no third-party fonts or images, and it sets no cookies. A few exhibits keep your own scores in your browser's local storage. That data stays in your browser.

Typefaces

All three are served from this site.

  • Schibsted Grotesk for names, headings, navigation and interface text.
  • Newsreader for reading text, and its italic for the margin notes on the homepage.
  • IBM Plex Mono for code and machine output.

The colours follow your system setting for light or dark. There is no toggle.

What the lab records

The Worker keeps counters and short feeds in Workers KV so the exhibits can show a live scoreboard. This is what the code stores.

  • Counters. Per exhibit and per defense level: how many attempts, and how many times the attack worked. These are plain numbers with no expiry.
  • A recent-events feed. For each exhibit, the last 25 events. An event holds a timestamp, the defense level, the outcome, and the two-letter country code Cloudflare reports for the request. For MCP tool calls (from the console or any MCP client), the support-desk game and the tool-poisoning game it also holds the first 120 characters of the tool arguments or text you submitted, with anything that looks like the canary, an sk- key or an email address replaced first. This feed is public through /stats, and it has no expiry. Older events are dropped as new ones arrive.
  • Rate limiting. Each exhibit that calls the model allows 20 requests per 10 minutes per address (30 for the role-reversal game). To count them, the Worker writes a key that contains your IP address and the time window. The key expires when the window ends, so the address is kept for at most ten minutes.
  • Role-reversal rounds. The server holds the answer to the round you are playing for 15 minutes, or until you submit your judgement.

The Worker does not store full request bodies, full prompts, your IP address beyond the rate-limit key above, or your user agent. What you type is sent to the Workers AI model to produce a reply, and the Worker keeps nothing of it beyond the 120-character snippet described above. Cloudflare and GitHub keep their own server logs under their own policies.

The canary tokens in the lab are inert. They are random strings held in a sandboxed in-memory document store. They unlock nothing, belong to no real account, and the exhibits count how many times one leaks as the score. No tool on the Worker reads the real filesystem or makes an outbound request.

Security measures on the site

  • Every page carries a Content-Security-Policy in a meta tag. Scripts load from this site only, with no inline scripts. Styles, fonts and images load from this site only (images may also be inline data: URIs). The only outside origin pages may contact is the Worker, https://mcp.apkasture02.workers.dev. Because GitHub Pages does not let me set response headers, the policy is a meta tag, which cannot enforce frame-ancestors.
  • Pages send a referrer policy of strict-origin-when-cross-origin.
  • The Worker adds X-Content-Type-Options, Strict-Transport-Security, a Referrer-Policy and a deny-everything Content-Security-Policy to its responses. It allows cross-origin requests from any site, because the exhibits and any MCP client need to reach it.
  • A security.txt (RFC 9116) lists how to reach me.

Reporting a vulnerability

Email apkasture02@gmail.com with what you found and how to reproduce it. I will read it and reply. This is a personal site with no bug bounty. The exhibits are meant to be attacked, so a leaked canary is the intended result and not a finding. A way past the Worker's confinement on the hardened /mcp endpoint, a script injection on a page, or a way to reach anything outside the sandbox is.