RedMirror Reflection is now the default way to use RedMirror — one offline binary that gives your own coding agent the power to find real bugs and prove them, right on your machine. Get started →
Playbook Bug bounty CWE-639

The bug bounty hunter's playbook

Published August 23, 2026 · one of the RedMirror role playbooks

A triager can argue with a hunch. They cannot argue with a reachable attack path. This playbook shows how to use RedMirror Reflection to turn a suspected access-control bug into a report that carries its own reproduction: you state the access rule, the kernel searches every reachable state, and a finding survives only when the kernel breaks the rule with a concrete sequence of calls.

Everything below is a real run. We pointed Reflection at a small multi-tenant document store, driven by a cheap open model through a coding agent, and let the kernel decide. The harness is published so you can reproduce it.

Where does RedMirror fit for a bug bounty hunter?

You work at the far end of the software lifecycle: the code is already deployed, and your edge is finding the reachable path nobody proved was safe. Scanners and fuzzers hand you candidates you still have to confirm by hand, and a report without a working reproduction gets marked "informational". Reflection closes that gap. It does not guess severity; it produces the exact call sequence that reaches the bad state, which is precisely what a bounty report needs.

The target: a multi-tenant document store

Here is the code under test. Two of its three functions guard ownership. One does not.

// store.js — every document has an owner; a caller is a user id.
function updateDoc(caller, id, body) {
  const d = docs.get(id);
  if (!d) throw new Error('not found');
  if (d.owner !== caller) throw new Error('forbidden');  // guarded
  d.body = body; return true;
}

function readDoc(caller, id) {
  const d = docs.get(id);
  if (!d) throw new Error('not found');
  return d.body;                                       // no ownership check
}

The bug is not exotic. It is the everyday shape a real audit turns up: a caller argument that one path checks and a sibling path silently ignores. The question is whether that asymmetry is actually reachable by an attacker, and that is what the kernel settles.

What did the kernel prove?

Driven by deepseek-v4-flash, the agent modelled the store as a state machine, stated the access rule (a read is allowed only if caller == owner), and handed it to the kernel. The kernel refuted it and returned the counterexample.

$ docker run -e ROLE=bug-bounty ... reflection-playbooks
== PHASE 2 — reflect: find + prove (deepseek/deepseek-v4-flash) ==
[reflection] tools registered (refute, orient, gate ...)

RedMirror Gate stamp: e9f574c90cd56cb0 (GROUNDED)

The kernel rendered the verifiable attack path as:
  1. <init>
  2. createDoc[owner=0]   # user A creates a doc
  3. readDoc_by_B         # user B reads it — no ownership guard

== PHASE 3 — gate ==
reflection: finding(s) grounded, nothing left open.
audit exit: 0

--- .redmirror-reflect/session.jsonl ---
{"note":"claim REFUTED and answer matches",
 "status":"GROUNDED","stamp":"e9f574c90cd56cb0"}

The raw gate record, not the model's narration. A finding is grounded only when the kernel refuted the rule.

Read the path back: user A creates a document, then user B reads it by id, and the read returns A's data. That is the whole report — a concrete, minimal reproduction: createDoc('A','secret'); readDoc('B', id) returns 'secret'.

What the kernel returnedValue
VerdictREFUTED (kernel gate: GROUNDED)
Attack pathcreateDoc[owner=0]readDoc_by_B
Access rule brokena read is allowed only if caller == owner
Searchevery reachable state (exhaustive)
Gate stampe9f574c90cd56cb0
WeaknessBroken object-level authorization, CWE-639

Why does a proof beat a report?

A bounty program pays for demonstrated impact. When your submission includes the exact call sequence and the invariant it violates, there is nothing left to triage: the reader runs the path and sees the leak. You also skip the usual back-and-forth where a program asks you to "show real-world impact" on a finding a scanner flagged but nobody proved. The kernel already did the proving.

How do you reproduce this?

Reflection installs as one binary and is driven by the coding agent you already use. To reproduce this exact run, or point it at your own target:

# the playbook harness (published), one role at a time
docker run --name pb-bug-bounty \
  -e OPENROUTER_API_KEY="$OPENROUTER_API_KEY" \
  -e REFLECT_LICENSE="$REFLECT_LICENSE" \
  -e ROLE=bug-bounty reflection-playbooks

# or on your own code, on your own machine:
redmirror-reflect init claude   # or cursor, codex, pi, ...

The kernel runs locally and uses no tokens, so the structural search is free; you spend only when your own model proposes what to check. A weak or local model is enough, because the kernel is what decides a finding is real.

Where this sits in the AI-native SDLC

Bug bounty is the outer loop of the AI-native SDLC: hunting shipped code after every earlier gate has run. The same engine that a team can put at its own deploy gate is the one you use to prove impact from the outside. See the reference on finding business-logic and authorization bugs for more shapes.

Frequently asked questions

How does RedMirror help a bug bounty hunter?

It turns a suspected access-control bug into a report that carries a reproduction. You model the endpoint as a state machine and state the access rule; a compiled kernel searches every reachable state and, if the rule can be broken, returns the exact call sequence that breaks it. You submit the proven attack path, not a hunch a triager can dispute.

What did the kernel prove in the example?

That a multi-tenant document store lets any caller read another owner's document. The access rule was that a read is allowed only if the caller owns the document. The kernel refuted it with the path createDoc as user A, then readDoc as user B, searching every reachable state. That is broken object-level authorization, CWE-639.

Is this different from a scanner or a fuzzer?

Yes. A scanner pattern-matches and a fuzzer throws inputs; both leave you to confirm exploitability by hand. RedMirror searches the state space of the logic and returns a reachable attack path or a bounded proof of safety, so a grounded finding already carries its reproduction. The kernel decides, not the model, so a cheap model is enough.

Does my code or target leave my machine?

No. RedMirror Reflection runs as a single binary on your own machine and the kernel search uses no tokens. You point it at your own model, local or hosted, and the code you are analyzing stays with you.

Get RedMirror Reflection

Prove the bug, don't just report it. Install the binary, point it at your target and your own model, and submit reports that carry a reproduction. First month free, then $4.99/month, cancel any time.

Your model, your machine, proofs not guesses.
Get started · 7-day free trial