The Ten-Stage Bugcrowd Cycle of Despair
A Bug Bounty Researcher’s Field Guide to Bureaucratic Futility
Prologue: The Pitch
Bug bounty programs sell you a dream.
“Help us find vulnerabilities! Get paid for your expertise! Join our elite community of security researchers!”
The brochure shows a hacker in a hoodie, bathed in green terminal glow, collecting five-figure bounties while sipping artisanal cold brew. What they don’t show you is the six weeks of triager tennis that follows every submission, the cookie-cutter rejections, and the slow realization that the system isn’t broken…
It’s working exactly as designed.
Just not designed for actual security.
Act I: The D-Dance
Every submission is a dance. The choreography never varies. There are ten stages. You will know them by heart.
The platform has four steps it performs in rotation, each one designed to keep the ticket moving and the money still:
Devalue. Downgrade the severity without justification.
Defer. Forward to the vendor. Wait weeks. Hear nothing.
Dismiss. Seize on a single irrelevant detail and ride it to the ground.
Deny. Close as Informative. Close as Not Applicable. Close as Duplicate. Move on.
That’s the business. Everything else, the ten stages below, is just how the music plays while those four steps repeat forever.
Act II: The Evidentiary Standard
Before I describe the dance, understand what’s being dismissed.
Every finding referenced in this post was empirically proven. Reproducible steps. Packet captures. Disassembly. Strace output showing exact system calls missing exact flags. Binary patches documented at exact offsets. Before-and-after screenshots. Video. Ghidra exports. CWE and CVSS justifications with direct CVE precedents. Attack flow diagrams. Remediation recommendations with code samples.
Evidence that would stand up to scientific peer review. Evidence that would stand up in a courtroom. Evidence a ten-year-old could follow.
Dismissed, every time, with a response that made it obvious the triager had skimmed, at most, the title.
A single line of template text, generated in under a minute, by someone reading at a fifth-grade level, sends forty hours of reverse engineering to the digital landfill. Then the vulnerability ships. To customers. To enterprises. To everyone.
The bugs don’t get fixed. That’s the key detail. The bugs don’t get fixed because of this process, not in spite of it.
Act III: The Ten Stages
Stage 1: Submission (Denial)
You finish the work. You feel good.
You have a working proof-of-concept, reproducible on a clean VM, whatever the class: a symlink-follow LPE on a root-owned daemon, a stack overflow in a Windows network filter driver, a command injection in a VPN client, an unauthenticated RCE in a network camera, a hardcoded CA private key baked into every deployment of a virtual gateway worldwide. The specifics vary. The dance does not.
You’ve got packet captures and logs and a writeup that explains the root cause in plain English. You’ve run it through an LLM in the role of a hostile triager and fixed every weak point. You’ve cross-referenced three directly comparable CVEs from the last five years that all scored HIGH for the same vulnerability class. You’ve attached a remediation patch.
You submit.
You think, this one is airtight. They can’t possibly miss this.
Reader, they can.
Stage 2: Silence
Automated acknowledgment within sixty seconds. “Thank you for your submission. A triager will review shortly.”
Then, nothing.
Day 1: nothing. Day 3: nothing. Day 7: nothing. Day 10: you refresh the portal, convinced the ticket has been deleted. It has not. It is sitting in a queue behind four hundred other tickets, of which perhaps thirty are real findings and the rest are “I found XSS on your 404 page (P1, $10,000 please).”
On day 14, you get a comment:
“Thanks for the report! Before we can proceed, could you clarify…”
You open it. It is an entirely formulaic request for information you already provided, in the submission, in bold, at the top, in a section titled “Please Read This First.”
Stage 3: Format Tennis
This is where you learn the triager’s job is not to understand your finding. It’s to pattern-match your submission against a template, and if it doesn’t fit, bounce it back with a template request.
The template assumes every vulnerability is a web vulnerability. The template has fields for:
- Target URL
- HTTP Method
- Request Headers
- Attacker Account
- Victim Account
Your finding is a local privilege escalation on a Linux daemon. There is no URL. There is no HTTP method. There are no user accounts. There are terminal commands.
The triager does not know this. The triager knows the template.
You reply, in bold:
This is a Linux command-line vulnerability, not a web application. There are no URLs or HTTP requests.
You wait another week.
Stage 4: The Golden Retriever Rewrite
The triager eventually admits defeat on the template and asks for “clearer steps.”
You rewrite your already-clear steps as if explaining to a golden retriever. Six numbered lines. Copy-paste ready. Impossible to mess up unless you are actively trying.
Step 1: Open a terminal.
Step 2: Stop the service.
Step 3: Delete the log file.
Step 4: Create a symlink pointing at /etc/ld.so.preload.
Step 5: Start the service.
Step 6: Observe that the root-owned process has now written
to a file it should never touch. Game over.
You add a sentence explaining that sudo appears in the commands only because the service needs to be managed by an administrator, which any attacker on the box with a local exploit already has, and that the vulnerability itself is that the service follows symlinks when writing. A bug filed under CWE-59. A class of bug documented since the nineteen-eighties.
You wait another week.
Stage 5: The Reproduction Theatre (DEFER)
The triager reports back:
“We were unable to reproduce using Burp Suite.”
Burp Suite is a web proxy. You are not attacking a web service. You flag this.
“We were unable to reproduce using nmap.”
You flag this.
“Can you provide a video PoC?”
You provide a video. Terminal on the left, log output on the right, root-owned process writing into attacker-controlled paths in the middle. You narrate the steps.
“We attempted to follow the video but our test environment is missing prerequisites. Please provide a VM image.”
You provide a VM image.
“We reset the test environment and now cannot reproduce. Please provide reproduction steps.”
You are now reproducing the reproduction steps you already reproduced, twice, on a platform whose entire job is to reproduce reproductions.
Every round, the clock resets. Every round, your reputation score ticks down for “taking too long to respond.” Every round, the vulnerability remains shipped.
This is Defer. This is the floor.
Stage 6: The Gotcha (DISMISS)
One day, buried in the avalanche of reproduction requests, the triager discovers something they can latch onto.
It is never the finding. It is always a footnote.
In your proof-of-concept script, you used sudo to attach GDB to the root-owned process you were debugging. A debugger needs privileges to attach to a privileged process. That is how operating systems work. The exploit itself runs unprivileged. You say so in the report. You say so in the PoC comments. You say so, again, in your response to the first request for clarification.
The triager finds sudo in one line of your PoC script.
“If this requires sudo to trigger exploitation, the customer team has confirmed it isn’t considered an issue.”
The sudo was for running GDB. The actual exploit is a single binary running as an unprivileged user, which causes a root-owned file to be created on disk. This is in the output. This is in the writeup. This is the entire point.
It does not matter. The sudo was in the script. The ticket is now “invalid.”
This is Dismiss. Forty hours of reverse engineering erased by a string search.
Stage 7: The Devaluation (DEVALUE)
Sometimes the ticket survives Dismiss. Rarely, but sometimes.
In those cases, you face Devalue.
You submitted a local privilege escalation that opens a root shell on every install of a commercial EDR agent. You cited three public CVEs from the last three years, each of the same vulnerability class, each scored HIGH by NVD, each paid out on a bug bounty program by the same platform.
The triager scores your finding P4.
Payout: $150.
You appeal. You attach the CVE precedents. You paste the CVSS vector for each one. You show, with the calculator they use, that the correct score is Critical. You point out that two of the precedent CVEs were published after the mitigation the triager is hiding behind, which means NVD scored them HIGH knowing about the mitigation, which means the mitigation is not a defense.
The reply, in full:
“This is a context-dependent risk, not an inherent vulnerability.”
“Context-dependent risk” is a phrase that does not appear in any CVSS specification, any CWE definition, any NIST publication, any academic paper on vulnerability scoring, or any precedent on the platform’s own historical rulings. It is a phrase invented in the moment. It is a phrase that means, translated:
“We have decided to pay you less. Stop asking why.”
$150. For a finding that, if exploited in the wild, would cost a mid-sized customer their entire fleet.
Stage 8: The Limbo Zone
Occasionally, by some miracle, the finding gets accepted.
The ticket state changes to “Triaged.” You feel, briefly, the sensation humans used to call hope.
Then the ticket is forwarded to the vendor.
This is where tickets go to die.
The vendor has ninety days to respond, which the vendor will use, in its entirety, to respond. Sometimes more. Sometimes far more. Sometimes the ninety days expire, you file for public disclosure, and the platform pleads for an extension on behalf of the vendor because the engineer assigned to the ticket “has been on vacation.”
You ask, reasonably, whether the vendor has more than one engineer.
No one answers.
During this period, the vulnerability ships. New versions release. Patch cycles happen. Your finding is never mentioned in any changelog, because patching it would be an admission that it exists, which would restart the clock on a public disclosure that the vendor is actively stalling.
This is Defer on the vendor side. The platform takes thirty percent of any bounty paid. If no bounty is paid, the platform’s cut of zero is zero, and the platform has precisely zero commercial reason to push the vendor.
You are not the customer. The vendor is the customer. You are the unpaid QA department.
Stage 9: The Denial (DENY)
The ticket closes.
The closure reason will be one of the following, selected from a dropdown by a triager who has not read the ticket since Stage 3:
- Duplicate. (Of what? No reference provided. The vendor has no public CVE list. The platform shows no overlapping tickets in your view. You ask. No one answers.)
- Informative. (The information is informative, but not, you know, worth money.)
- Not Applicable. (Not applicable to whom? To what? Not specified. Not Applicable.)
- Out of Scope. (The scope, which you read carefully before starting, somehow excludes exactly the vulnerability you found, even though the scope document does not say that and you have it in a tab.)
- Won’t Fix. (The honest one. The rare one. Written by someone who has given up on the pretense.)
Your reputation score drops. Your researcher rank drops. Your signal-to-noise score on the platform drops. The next finding you submit will be triaged slightly later, by a slightly less attentive triager, because the platform’s metrics now say you are a slightly worse researcher.
This is Deny. It is the terminal state. The ticket is closed forever.
The vulnerability remains shipped. The product remains vulnerable. Customers remain exposed. The vendor has a checkbox that says “bug bounty program: active” on its compliance reports.
Everybody wins except the people the product was supposed to protect.
Stage 10: The Realization
You sit with it.
The first time, you rage. You write a five-page rebuttal, cite six CVEs, attach a CVSS v3.1 calculator screenshot, threaten public disclosure, and the system’s response is to ignore the rebuttal for another three weeks and then close the ticket as Not Applicable a second time, a re-closure performed by a different triager who, impressively, has read even less of the submission than the first.
The second time, you are angrier, but faster.
The third time, you recognize the pattern.
By the tenth, you understand it.
The bug bounty industry has a quality control problem. It does not want to solve it. Solving it would cost money. Solving it would require hiring triagers with actual security expertise, paying them enough to care, giving them time to read submissions properly, and evaluating them on accuracy rather than tickets-closed-per-hour.
That is not the business model.
The business model is selling security theater to enterprises. A managed process. A checkbox. A press release about commitment to security. Whether bugs actually get fixed is secondary. Whether researchers get paid fairly is tertiary. Whether the ecosystem incentivizes good-faith participation is not on the list at all.
Your carefully researched finding, the one that took forty hours of strace analysis, kernel debugging, binary patching, and evidence documentation, looks identical, to a triager with six weeks of experience being evaluated on throughput, to the fifty garbage submissions rejected that morning. Until someone actually reads it. And they won’t, because reading takes time, and time costs money, and the metrics say close the ticket.
The bugs don’t get patched.
The bugs don’t get patched because of the process, not in spite of it.
The process is not broken. The process is working exactly as intended. It is optimized to generate the appearance of a security engagement, for the vendor, at the lowest possible cost, with zero obligation to actually fix anything. Real vulnerabilities are a nuisance to that appearance. Real vulnerabilities generate payouts, which come out of the vendor’s budget, which threaten the vendor’s next contract renewal with the platform. Real vulnerabilities are bad for business.
The system is working.
Just not for you. And not for any of the millions of end users whose data and systems remain quietly exposed, for years, because a triager on another continent got paid ten dollars to close a ticket in under a minute by typing “Not Applicable” into a dropdown.
Act IV: The Coping Mechanisms
You don’t quit. Not exactly. You adapt.
Pre-emptive FAQ. Address every possible triager objection before they can voice it. Three sentences at the top of every submission, in bold, impossible to miss (which means, of course, they will miss them):
This is a Linux privilege escalation, not a web vulnerability. There are no URLs.
The
sudoin the PoC is for attaching GDB to a root process. The exploit itself runs unprivileged.Yes, local access is required. That is what “Local Privilege Escalation” means.
Six-step reproduction. Fewer if possible. Never more. Treat every line like it costs a dollar, because the triager’s attention costs less than that, and you are going to spend yours on their behalf whether you like it or not.
Video. Screen recording. Narration. Time-stamped. Terminal on the left, logs on the right, exploit on top. Make it impossible to claim “we couldn’t reproduce” when the reproduction is literally a moving picture.
CVE precedents. At least three, exact vulnerability class, scored HIGH, on the same platform if possible. Link to each one. Paste the CVSS vector. Remove any possibility of arguing this is a novel ruling.
Hostile LLM review. Before submitting, ask your favourite language model to roleplay an incompetent triager and find reasons to reject your report. If it finds a weak point, no matter how irrelevant, no matter how off-topic, a real triager definitely will. Patch the weak point. Repeat until the model gives up.
Leave no idiot un-smartified. This is the operating principle. Every ambiguity closes a ticket. Every unstated assumption closes a ticket. Every sentence that requires the triager to think for two seconds closes a ticket. Spell out the things a security professional should already know. Spell them out twice. Put them in bold.
None of this guarantees acceptance. Nothing does. But it makes the eventual rejection feel slightly less like a personal insult and slightly more like an inevitable feature of a broken system, which is how you need to frame it if you’re going to keep doing this without developing an ulcer.
Act V: The Epilogue
Here is what I want every person who reads this post to take away.
The vulnerabilities are real. The research is real. The evidence is peer-reviewable. The fixes are available. The exploits work.
The triagers cannot read. The platform will not make them. The vendors will not pay for findings they can duck. The system is structured to ensure none of the above ever changes.
And somewhere, right now, a researcher is at three in the morning, on their second beer, with a 1.6 megabyte stripped VPN client in Ghidra and a GDB session in another window, reverse-engineering a proprietary XML profile schema for a piece of enterprise software they cannot legally license, because the only way to prove the command injection they already found is to binary-patch the vendor’s own executable in twenty-four places to bypass the validation logic that stops normal users from reaching the vulnerable code path.
When they finish, when they submit, when they attach the two hundred pages of evidence, when they include the CVE precedents and the CWE mapping and the CVSS justification, the response will be:
“Could you clarify: Target URL? HTTP Method?”
And the researcher will sit back, crack their neck, and reply:
This is a Linux command-line vulnerability. There are no URLs.
And the dance will begin again.
Devalue. Defer. Dismiss. Deny.
Over, and over, and over.
To be continued when the cookie-cutter responses arrive…
Lucid_Duck reverse-engineers things that weren’t meant to be, and writes about it here.