- Critical Thinking - Bug Bounty Podcast
- Posts
- [HackerNotes Ep. 191] Cache-Timing Exfil, Tab-Unders, and Buying Local Hardware
[HackerNotes Ep. 191] Cache-Timing Exfil, Tab-Unders, and Buying Local Hardware
Digging a nice technique to exfiltrate data using cache, and some ideas if you want to buy local hardware for AI
Hacker TL;DR
Turn a server-side cache into an exfil channel: a cache hit vs miss is a per-index oracle
A Cloudflare Turnstile click is a clean way to hide a tab-under
Scaling a hackbot is now a spend-to-make-money setup, and the numbers work
Local compute is a hedge: token subsidies, regulation, downtime, and uncensored exploit dev
We do subs at $25, $10, and $5, premium subscribers get access to:
– Hackalongs: live bug bounty hacking on real programs, VODs available
– Live data streams, exploits, tools, scripts & un-redacted bug reports
Need a Pentest? We just launched CTBB Pentests!
Hack full time? Check out the Full-Time Hunter’s Guild!
Leaking Secrets Through a Cache
The target was a chatbot added to an otherwise locked-down product. Working with Codex, the first step was delivery: a q parameter injection. The question was whether the app had an auto-invocation feature, where a query parameter starts a prompt automatically. Codex found it quickly in the JavaScript. There were actually two parameters, one for the query and one for auto-submit, so an attacker can send the victim a URL that runs a prompt on their behalf.
That solved delivery. The chatbot already had access to a lot of sensitive object data tied to the account, plus a lot of untrusted data. The only missing piece was exfiltration.
The CSP restriction, and the cache behind it
The obvious exfil method is markdown image rendering. Give the model an image whose URL points at your server, and the request leaks data. On the free tier the small model would render anything, but the app itself refused every image payload. Codex ran through a cheat sheet of markdown image payloads for about ten minutes and found the reason: images rendered fine, but only from the app's trusted CDN domain. The CSP allowed images from that one origin.
There was no obvious way to control content on that CDN. So the question became: can we exfiltrate to a domain we do not control?
The app auto-generates a per-user avatar, and those avatars are served behind a cache. If the victim's auto-invoked agent requests one of those avatar paths, that path is now cached. When the attacker requests the same path afterward, they get a cache hit instead of a miss. A hit versus a miss is a boolean oracle, and a boolean oracle is enough to leak data.
Encoding the secret into cache paths
Here is the full technique. The auto-invoking prompt tells the agent to read a secret from the account's stored objects, then send a batch of markdown image requests to CDN avatar paths where the last byte of each path maps to a character of the secret. The first request encodes index zero, the second encodes index one, and so on. It is close to the limit of what a single prompt can drive, but it works.
As soon as the attacker's server sees those requests come in, it runs a script that tries hundreds or thousands of candidate avatar paths ending in the target byte. Each index maps to one cached path, so you get a single hit per character. One character at a time, you recover the secret from the cache.
Pro Tip: a cache you can populate as the victim and probe as the attacker is an exfil channel, even when the response body tells you nothing. Look at avatars, thumbnails, and generated assets, anything created per-user and cached by path.
The cleanest delivery: a tab-under behind a Turnstile
One-click and CSRF-style auto-invoking prompts have a problem: the victim sees the prompt run on their screen in real time. We wanted this hidden.
Pop-unders were the first idea, but a tab-under worked better. The limitation is that Chrome will not let you redirect the backgrounded tab without a user gesture, so you need a second click. Across browsers the rule of thumb is one click to reach the attacker page and one click on it to trigger the under, with some no-click tricks in the CTBB Discord that use print popups.
The trick is to use a click the user makes anyway: a Cloudflare Turnstile one-click captcha. The flow:
The victim opens a throwaway attacker page (not your personal blog that gets 100k views a month).
They see a single Cloudflare-style verify box and click to enter.
That click opens a new tab with the decoy content, and the original tab redirects to the auto-invoke page.
The page flickers once and shows the blog they wanted to read.
Behind that flicker, the backgrounded tab runs the prompt injection and reads the secret through markdown images, while the attacker server times the cache. Start a timer on the tab-under, wait about two minutes, and brute-force the whole secret. The debug view showed red for each miss and green for each hit, and each confirmed character was added to a column on the right until the full secret was recovered.
The guiding principle here is that the cleanest, most realistic PoC wins. This chain puts three things together in one click: front-end delivery, AI prompt injection, and server-side cache exfil.
The simpler follow-up
There was a second exfil path on the same root domain. Similar to a CSP bypass using Google Scripts, the attacker did control a request handler on that root domain, so the secret could be sent out through a markdown image directly to their server, without the cache technique. It was filed as a separate bug, though it will likely be accepted as one.
Scaling the Hackbot: Spending to Make Money
The other update this week was about volume: roughly 50 reports in about two weeks, all in the high-to-crit range, on a program that is responsive, pays bonuses, and is AI-friendly. Triage teams are feeling the volume of AI reports, and this is a clear example of that.
The takeaway is a change in mindset. Bug bounty has not usually rewarded spending, but that is changing. Paying for subsidized tokens as much as you can, stacking 20x Max subscriptions where you can get them, and running several thousand dollars a month of compute is starting to make sense when the output is a steady stream of paid high and crit reports.
Buying Hardware: Who Should, and Who Should Not
The next step is local hardware, and a lot of people are buying in. Prices are higher than they were six months ago. A 256GB Mac Studio with the M5 Ultra runs about $9k to $10k and ships in November. On the Nvidia side, DGX Sparks are about $5k each, and two of them give you 256GB of VRAM. The ASUS Ascent variant uses the same chip with 1TB of disk instead of 4TB and saves about $1k.
Before you spend, here is the practical case for and against:
Redundancy. Claude was down for two hours during the recording. If your workflow stops when a provider goes down, a local Qwen or DeepSeek model keeps you working. A slower local model is still better than nothing.
Hedging. Token subsidies will not last forever, and regulation could restrict cyber use of the big models. Owning the compute protects against both.
Cost offload, done right. Do not run dumb-to-smart escalation, because the dumb model will decide it hacked something before it did, and you get false coverage. Instead, run a smart parent (Codex or Claude) that hands off the throwaway work: one-off scripts, data synthesis, reading a large JavaScript file and reporting back specific offsets, even report writing. Smaller models often sound more natural for that last one.
Throughput check. DeepSeek V4 Flash on two DGX Sparks gets around 20 to 30 tokens per second per stream, which is slow for interactive use. As a sub-agent it does not matter much, since the harness waits, and you can run four streams at once with fork-and-continue.
Uncensored exploit dev. Sometimes a frontier model refuses legitimate exploit or parsing work, and re-prompting around it is slower than asking an unrestricted local model. Same for jailbreak research, where the top models will not help you write jailbreak payloads for other models.
Sensitive engagements. If a pentest client will not let their data touch OpenAI or Anthropic, a local model lets you run testing overnight with nothing leaving the building. That is a real use case, even if you decide whether the client is worth it.
Quick Hits
GitHub swag store. When GitHub pays a bounty, you also earn swag points, and the store has some good gear, including an RGB wireless charger. A well-earned shout-out to their program.
herdr.dev. Recommended by Yuji, this is a terminal multiplexer built for coding agents rather than shells. The main feature is agent-state awareness: a sidebar that shows which agents are blocked, working, or done. It is not tmux-integrated, it is its own multiplexer, so heavy tmux users will have to decide if the agent visibility is worth the switch.
Resources
GitHub Bug Bounty - program and swag store
herdr.dev - agent-aware terminal multiplexer
Nvidia DGX Spark - local inference box
That's it for the week, keep hacking!
