[HackerNotes Ep. 182] What Hackbots Keep Finding: Guest Tokens, GraphQL, and Cognito bugs

Today, we dig some interesting bugs found by our agents and some tips to improve your setup

Hacker TL;DR

  • A checksum-gated reflected XSS on a major e-commerce provider needed exact characters at fixed string offsets, which turned exploitation into a code golf puzzle solved by aligning import.

  • Wayback URLs keep leading to legacy API routes that mint a guest or partial-auth token, and that token often reads or writes objects it should never touch. Point your agent at getting some form of auth first.

  • AWS Cognito is still easy to misconfigure. Writable custom user attributes let you self-promote to admin by hitting the pool directly, even when the app hands you a clean bearer.

  • Response headers and cookies are the underappreciated attack surface. A stray Set-Cookie on a random API call is exactly the kind of signal agents catch and humans skim past.

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!

The Caido Skill Gets a curl-First Rewrite

The Caido skill has been in heavy rotation for a while, and after a round of A/B testing across a bunch of Claude instances a better shape emerged. The core idea landed in PR #22: let the agent use curl for most of its work and proxy that traffic through Caido, then only reach for Replay and Collections when it needs granular edits or when it needs to hand something back to a human.

The trick that makes this smooth is that curl can drive a cookie jar and a config file. Instead of rewriting full cookie sets on every request, the skill exports a request from Caido straight into a curl config, then reuses that config. When the agent really needs a person in the loop, or the user wants to poke at something live, that is what Replay is for.

There is also new match-and-replace tooling baked in, so the agent can auto-generate match-and-replace rules to flip feature flags on the fly. Small quality of life win, big impact on coverage.

The Weirdest XSS

This one has been sitting in the "how does this even exist" pile for a while. It is a reflected XSS on an e-commerce provider a lot of people use, and on paper it is a standard reflected XSS. In practice it was gated by a checksum, and the checksum is where things got strange.

The reflected string had to carry the characters W, P, and M at specific offsets. The subcomponent in question was named WPM, and the validation was keying on those letters at fixed indices. Grab a valid string, tweak it one character at a time, and it throws an error the moment W is not at its index, P is not at its index, and M is not at its offset near the end. Best guess is that something was being hashed and then characters were replaced at fixed positions, so the payload had to satisfy that layout before it would render.

Then the second wall. The only way to escape the double quote the value sat in was %22, but the length accounting happened before rendering, so %22 counted as three characters, not one. Every URL-encoded character you spent inflated your length budget while the WPM anchors had to stay pinned in place. So the constraints stacked: keep the string the same length, keep WPM at their offsets, and code golf your actual payload into whatever room was left.

Getting an alert() was quick, because getting an alert rarely takes much. Proving arbitrary execution was harder, and the program specifically doubted it was possible. The escape that made it work was assigning a very short domain to a variable and lining up the M so it landed inside an import, then triggering that import. If the component had been named literally anything other than WPM, none of it would have fit. It fit, so it popped, and because it lived in the provider's shared component it meant XSS across every customer instance.

The Guest-Token Bug Class

Here is a pattern that keeps surfacing, and it is worth naming because coding agents find it constantly. Through Wayback URLs, agents keep turning up legacy API routes that return uploaded objects: a document, a file, a profile. Loading the page mints some kind of guest token or guest user token, and that partial auth then stays usable to update the object, or read adjacent data through the API that it was never supposed to reach.

Three or four of these have come through in the last month or two, and they share a root cause. They live on legacy APIs and legacy URLs where something is hard coded to grant access it should not, and the guest or partial-auth path bypasses the checks that the modern flow enforces.

The takeaway for anyone running a hackbot: tell it explicitly to go after getting some form of auth. A guest account, a partial-auth token, anything that moves it off fully anonymous typically opens up a whole new slice of scope. Agents are good at spotting when a weird cookie gets set on a response, and then reusing that same cookie to reach other endpoints. That combination, partial auth plus agent attention to Set-Cookie, is where a lot of this lives.

Pro Tip: If you need a throwaway inbox for the agent to complete these flows, agentmail.to is zero setup. If you would rather own it, a Cloudflare account plus a custom domain gets you your own agent inbox in about five minutes.

Cookies Are the Underrated Surface

Response headers in general got skimmed too much in the pre-AI workflow. A random API request in your proxy quietly returning a Set-Cookie was easy to miss. Walk through any app you have hacked deeply and try to explain what every cookie attached to your requests actually does. Between analytics junk and framework noise, almost nobody can.

That is exactly the gap. Tooling that audits every cookie across every endpoint, what each one does, which ones are necessary, and how flipping one changes the response, would map a real downstream code path. The single-target hunters who live inside one program already do a version of this by hand: they notice a cookie they have never seen, and that alone tells them where to dig. Most people do not have that radar because of all the spam in the jar, so this is a good thing to offload to an agent.

Hackbot Tips: GraphQL, Validators, and Coverage

GraphQL is fire. Prompt the agent to hit GraphQL specifically. Different queries and mutations can carry different middleware and auth schemes, so having the agent hit every single one is valuable. Better still, a good agent will tell you whether a denial is happening at the middleware layer or somewhere deeper. On Apollo-based servers there is an authorization layer it flags on a regular basis, and it can tell you "not at this layer, at this one," which is the signal to dig further. Across three separate targets that read on the auth layer held up, and each one produced valid GraphQL reports.

That same GraphQL depth is also the top source of false positives. An agent finds a way past the middleware auth, sees a 403 flip to a 401, and concludes it broke through, so it reports the null byte it stuck on the end of the call. It genuinely did bypass a middleware gate, maybe something loose in an Nginx config, but it never reached the data, so there is no impact worth a report. The fix is a validator that is impact-focused rather than bypass-focused. Tune it too hard, though, and it starts eating real findings, and it will also flag escalations as dupes if you have not built an escalation workflow to route them separately.

JS files are the number one job. Tell the agent its primary mission is to pull the JS, the JS maps, and the lazy-loaded chunks, then build out every single API endpoint from them. Taking inspiration from the Brutecat episode, a coverage tracker on top of that works well: grab the JS, extract the endpoints, push them into a queue, and churn through it systematically. One target had gone quiet after an early wave of bugs, and adding the coverage system pulled out a second wave. You do not need to go full Brutecat with per-endpoint auth correlation to benefit. Even just giving the agent a way to track attack vectors and hold itself accountable for whether it actually tried every endpoint pays off.

Double down on what you find. When the agent lands one bug and it points at a systemic pattern, a JWT validation flaw, an auth problem that repeats across the app, tell it to go find every instance of that pattern. Feeding it your own read on the architecture, human in the loop, turns one finding into a cluster.

Cognito, Firebase, and the Third-Party Auth Problem

Following that "double down" instinct led straight to a Cognito finding. One org leaned on Cognito heavily, and Cognito is easy to misconfigure. This is misconfiguration number three from Yassine's NahamCon talk: privilege escalation through writable user attributes.

Custom attributes on a Cognito account can define your role or permissions, and they are writable by default unless you explicitly mark them read-only. So even when the app hands you a clean bearer and you never touch Cognito through the normal flow, you can hit the Cognito pool directly, modify those attributes, and promote yourself to super admin. That exact bug was a five-figure crit on a public program this week, so these are very much still live, and Cognito shows up all over the place.

The broader shape here is third-party auth and permission services that can be attacked at scale. Firebase has plenty of the same energy, and as more vibe-coded apps hit production holding real user data, this stuff is going to be duct taped together. Supabase is everywhere now, often stood up by a user rather than configured properly, and the classic row-level-security .eq() operator mistake keeps making the rounds. These services are genuinely hard to configure, and the agents building on them are not always configuring them correctly.

MCP Corner

Two quick MCP notes. X shipped their MCP, which is a fresh, well-known target for anyone who wants to poke at it. And after mapping out Google's MCP infrastructure, the count came in at seven hundred plus MCP servers. Run tools/list on a lot of them and they happily enumerate everything, and there are also hidden tools that are not advertised, which is arguably a breach of the protocol: you approve a server because a list says it does one thing, and under the hood it has a pile of other callable tools.

The bigger design gripe is that MCP dumps results straight into context. When a tool is feeding data back into the model, you want the model to query precisely for what it needs, and unless that is built into the tool itself you are stuck. This is why skills are so strong: you can pipe through jq and grep, wire up any CLI you want, and put GraphQL or anything else under the hood.

Where MCP still wins is the auto-updating, auto-broadcasting nature of what a server supports. If you are a provider updating what your server can do while a customer is still on an old skill, there is no clean way to force-update them. MCP asks the server what it has before every call, so enterprises that want to keep evolving their tooling get that for free.

Pro Tip: You can steal that advantage for skills. Have the skill's first step hit an endpoint that returns its current function list, so as the maintainer you update capabilities server-side and every install picks them up on the next run. It is effectively a combination of MCP's updatability and a skill's token efficiency and chainability, and it is a clean way to ship a skill once to a client and keep improving it remotely. Trust matters here, since it behaves a little like beaconing, but the ergonomics are excellent.

Fable Is Back

Fable came back online, and it is a real step up. It one-shot an entire end-to-end video game with graphics, animations, and the whole package, and it has made big leaps on workflows that even Opus 4.8 struggles with. Worth noting the flip side: right as Fable shipped, denials from Opus spiked, most likely protections and mitigations getting re-enabled in anticipation of people pointing it at cyber work. Notes that loaded fine the day before started getting refused.

Fable was only bundled with Claude subscriptions through July 7th, after which it went API-only. So the play was to front-load any non-hacking build work into that window rather than burn it on tasks that would eat rejections.

US South Summer Sessions

There is a HackerOne ambassador event, US South Summer Sessions: Hack the Heat, landing in the second half of July. It looks remote-only with limited slots, and it is post-auth on a major HackerOne customer that most people will recognize. Post-auth on this particular target has historically been a slaughter across four or five prior live hacking events, so a smaller field with green scope is a genuinely good shot. If you have always wanted a first live hacking event, the details are here.

AI Sandbox Escapes Are a Blast

Last one, and it is the most fun. As agents get more capable and run agentically the way Claude Code does, there is a VM behind them with command line tools and the ability to execute. Getting a shell on that VM and pivoting around the environment is exactly the kind of hackery that made pentesting fun.

Getting the shell is almost embarrassingly simple. Ask the model to help debug a tool, hand it a curl | bash install line, and it balks. Tell it to read the script first, and it agrees. The script then rotates: one request serves the benign version, the next serves the reverse shell. It reads the benign one, decides it looks fine, pipes it to bash, and you are in.

From there the model tends to assume RCE on the box is a given, so there is still more to prove. You escalate privileges, get to root, or pivot to internal services. It scratches the same itch as landing a shell on a pentest and needing to move laterally. Do not shy away from it.

Resources

That's it for the week, keep hacking!