Bugcrowd is currently fundamentally broken

In July I wrote about Bugcrowd’s Request a Response expiring without a response. Two of my requests had expired unanswered, on two different programs, after 21 and 18 days of waiting. Bugcrowd removed the expiry in August, and I started writing a follow-up about that one change. Since then more has gone wrong than the expiry, so this post is about all of it.

When something goes wrong with a submission on Bugcrowd there are three places a researcher can turn: the triage team that made the decision, Request a Response, and Support. All three are broken at the same time. That matters because each of them exists, in part, to catch failures in the others, and right now each one’s answer to a problem is to send you to one of the other two. I’ll go through them in the order you meet them.

Triage

Bugcrowd has been open about the pressure on triage. On 10 March it wrote that its queues had “increased by more than 334%” over the preceding three weeks, mostly from low-quality AI-generated submissions (policy changes to address “AI slop” submissions), and it has been adding rate limits, identity verification and submission throttling since. I think that’s a reasonable reaction to a real problem, and the triagers are dealing with a flood I don’t see.

What I do see is the other side of it. Earlier this year three of my submissions on one program were closed inside a fourteen minute window, each with the same message saying the report contained no proof of concept. Each had a proof-of-concept archive attached and listed on the same page as the closure, containing a compose file and one script.

On 29 August I submitted a report on another program. It had a proof-of-concept archive attached with the stack scripts, a deterministic fixture, the raw API responses for both test users, a WebSocket capture and screenshots, plus a technical appendix with file and line references. On 21 September, 23 days later, it was closed. The message said the issue couldn’t be reproduced based on the information provided, that the report lacked a clear proof of concept and sufficient technical detail, and that the content “appears to be low-quality or potentially automated (AI-generated)”. It doesn’t say which step was run or what happened instead. I do use AI heavily in my research. I’d be surprised if I were the only one. That fact alone does not make a report high or low quality. What I got is a paragraph that could be used on most submissions, but which doesn’t actually apply in my case.

I can’t tell from the outside whether anyone opened the archive, and I only see my own submissions, so I can’t say anything about how often this happens to other people. Both closures have the same shape though: a fast verdict, a generic reason, and no detail a researcher could act on. What happens after the closure is nothing. No reply to comments, no answer to the obvious question of which step failed. The closure is the last thing triage says, and a triage team under this much pressure will make some wrong calls, which is fine as long as the mechanism for correcting them works.

Request a Response

Request a Response is the mechanism for exactly this situation. Bugcrowd’s documentation says it’s for asking a follow-up question, requesting a re-evaluation of a decision, or providing additional information.

In my experience it currently produces one of two things: nothing, or a sentence saying the original assessment stands. The second is technically a response. I said in July that I’d accept a response I didn’t like as long as somebody had considered the disagreement, but “my original assessment stands” restates the verdict the request was about and considers nothing.

A researcher can have two open requests at a time, and that limit is per account, not per submission. Each submission can have two requests over its lifetime, and only one of them can be open at a time. Until August an open request expired after ten business days without a response (November changelog). That was bad, I wrote a whole post about it, but the expiry did two things: it gave you the slot back, and it left a record. The expiration was written to the submission’s activity log, so there was an entry saying a request was made and nobody answered it. Since August there’s no expiry event to write, so the log shows the request being opened and then nothing. The changelog entry (archived) says:

Open RaRs no longer expire after a fixed period. Your request now stays open until it is resolved, so it will no longer be closed automatically before you receive an answer.

The entry is precise about the wrong thing. It guarantees that the request stays open, it doesn’t guarantee that anyone replies to it, and “resolved” is doing a lot of work in that sentence. The documentation is clearer about what it means: a request “requires at least one response to be answered”, and “your request stays open until it is answered”. So by Bugcrowd’s own description the only way out of a request is a response, and a request nobody answers is open for good.

There’s also no way to withdraw a request, no cancel, no close, no way to say I’d rather try something else. So the slot comes back when the recipient answers, and only then. Two slots per account, no expiry, no cancel: the party that isn’t answering decides whether I can ask anyone else anything.

One slot is a request I opened to Bugcrowd on 25 August, asking why the attached proof of concept didn’t count. The other is a request I opened to a customer on 11 September, on a different program, where a submission had been left in a contradictory state and I asked for a clarification. At the time of writing, on 22 September, neither request has been answered. That’s both slots, one held by Bugcrowd and one by a customer. The report closed on 21 September can’t get a request at all, and neither can anything else I submit, until one of the two open ones is answered. I’m in Request a Response limbo, and nothing I can do from my side gets me out of it.

That last part is new. A bad decision used to be contained to the submission it happened on. Because the slots are account-wide, an unanswered dispute on one program now removes my ability to challenge a decision on a different program, made by different people, about a different finding.

Support

Support is the third mechanism. How long it takes varies, I’ve had a first reply in four days on one ticket and waited two weeks on others. Either way the reply closes the ticket.

I’ve opened three tickets about the three closures and how they were handled. The first was about the closures themselves. It was closed by telling me the status of those submissions was final, and that if I still disagreed I should submit a new report to the program. So I did. I refiled one and put the argument about the supposedly missing proof of concept in the opening paragraph, specifically to stop the same thing happening again. It was closed with the same message, the argument wasn’t addressed. On 25 August I opened a Request a Response on that closure instead of going back to Support.

The second ticket, on 11 September, wasn’t about whether the findings were valid. It was a complaint about the handling: three reports closed inside fourteen minutes for a reason anyone could check was wrong, the re-submission closed the same way, the argument I’d put at the top of that re-submission to prevent exactly that ignored, and a Request a Response that had been sitting unanswered since 25 August. I filed it with the request type, the engagement name and the submission IDs. It was answered as though I had asked which feature to use. I was told that I hadn’t used Request a Response on the three original submissions, that I should do that before support could assist, and that:

The Request a Response feature can only be used a maximum of two times per submission.

Using the RaR for a second time is considered as an Appeal, so be sure to include new or additional information in your comment.

The answers to the two tickets contradict each other. The first ticket was closed saying the status of those three submissions was final and a new report was the remedy, the second was closed saying I hadn’t used Request a Response on those three submissions and that was the remedy. Both can’t be true. The second answer also says nothing about the re-submission, or the request that has been open on it since 25 August, which the ticket was partly about.

The second answer doesn’t work on its own terms either. The ticket was a complaint about conduct, and the answer treats it as a dispute about verdicts. What it asks for is two requests on each of the three originals, all of which have the same underlying issue, which is six requests through two account slots, and the second request on a submission can’t be opened until the first has closed. Under the old rules each request took two weeks to expire, so that’s at least eight weeks before I’d be allowed to contact Support about a triage that took fourteen minutes. Under the new rules it’s never, because the second request on a submission can’t be opened until the first one is answered, and the first one is the request that doesn’t get answered. That’s before counting that both of my account slots are already held by open requests. The second request is also supposed to add new information, and if the first one already contained everything relevant there’s nothing to add, so the appeal is either a repeat that gets the same sentence back or made up. And part of the complaint was that the triager doesn’t answer requests, so telling me to appeal with two consecutive requests is nonsensical. Support’s answer to a triager who doesn’t respond is to send me back to the triager.

There’s a third ticket, opened on 17 September, where I tried a creative approach to get Support to engage. It opened with one sentence in bold: this is not about the outcome of the triage, this is about conduct. It asked for five things: that the handling be reviewed, whether the attached archives were opened before the submissions were closed, a reply to the request that has been open since 25 August, a reassessment by other triagers, and that this triager not be assigned my submissions in future. It was closed on 22 September, and the answer is about the outcome of the triage. The ASE team was unable to identify a demonstrable security impact, theoretical scenarios don’t qualify, and none of the five things is mentioned. It also gives a new reason, the closures said no proof of concept and this says no demonstrable impact. And it ends with this:

If you still disagree and have additional POC to provide, please submit a new report to the program, as the status of this submission is final.

That is, word for word, the sentence that closed my first ticket five weeks earlier, the instruction the second ticket said was wrong, and the thing I had already done. It’s also the second sentence I’ve now had back verbatim from two different tickets. The replies are macros, and the macro chosen has nothing to do with what the ticket said. The Support boilerplate I’ve had back twice says that Bugcrowd Support Services does not review submissions, that’s handled by the ASE Triage Team. The third reply, to a complaint about conduct, is a submission review from the ASE Triage Team.

I’ve been told twice that a second request counts as an Appeal, six weeks apart, on two different engagements, in two different tickets, and the two replies were the same block of text apart from one clause, so it’s canned text. Both came with requirements: the request had to contain numbered reproduction steps and non-theoretical impact, or it would be closed as invalid.

None of this is anywhere a researcher can read. On 22 September I searched all 328 pages of Bugcrowd’s researcher and customer documentation, and “appeal” appeared exactly once, in a sentence about programs being appealing to researchers. The nearest thing is a line under Tips on the Request a Response page, “Avoid opening multiple requests on the same issue unless you have new information to share”, which is advice, with no appeal in it, no requirement and no consequence. You only learn the rule from Support, after the fact, and it shifts the blame: the problem is no longer that a triager closed three reports for a reason anyone could check was wrong, the problem is that you didn’t follow a protocol (you had no way of knowing about).

Whoever wrote the rule, the effect of it is to move the problem onto the researcher, buy time, and make protesting pretty much impossible. Appealing a decision shouldn’t require jumping through this many hoops, let alone hoops that aren’t written down anywhere.

Why I’m calling it broken rather than slow

Slow I could live with. A queue three times its normal size is slow, Bugcrowd has said so itself, and a triage decision that takes three weeks is still a decision. A platform can also survive a share of wrong decisions, every triage team makes some, as long as the mechanism for correcting them works. And it can survive a correction mechanism that’s slow or clumsy, as long as the decisions feeding it are mostly right.

HackerOne is a useful comparison. It’s under the same pressure, in May it wrote that report volume across the industry had more than doubled since February (Navigating the AI Wave), and my response times there have gone up too. It’s not smooth either, things take longer than they used to and there are hiccups. But across several unrelated cases, every answer I’ve eventually got there has been a real one, and I’ve never hit anything like the Request a Response deferral or the appeal rule, nothing that sends you in circles. Slower, and still functional.

What I’m describing on Bugcrowd is both failures at once. And the wrong decisions here aren’t close calls. “No proof of concept” with a proof-of-concept archive listed on the same page isn’t a judgment call. That’s the kind of mistake a correction mechanism exists for, and the correction mechanism doesn’t produce corrections. Triage closes without detail and goes quiet. The remedy for that is a request that the same quiet party has to answer before I can ask again. The remedy for an unanswered request is Support, and Support’s remedy is the request. Each of the three would be tolerable if the other two worked: triage mistakes are fine if a request gets them a second look, unanswered requests are fine if Support steps in and gets them resolved, and Support pointing at the request is fine if requests get answered instead of staying tied up. Right now none of those hold, and the three failures cover for each other.

In software terms it’s a liveness problem: no single state is wrong, the system just has states you can’t leave. A valid submission gets rejected, the researcher follows every step they were told to follow, and no action available to them produces a substantive review. The one thing a bug bounty platform has to do is tell valid findings from invalid ones, and in that state it can’t, because the part that corrects the first decision doesn’t run.

The August change made this worse. Under the old rules an unanswered request eventually expired and released you. That was a bad exit, I said so at the time, but it was an exit. Now silence produces more silence, and it also consumes the account-wide quota for every other submission you have. Removing the timer didn’t fix the unanswered request, it removed the only automatic way out of it.

Permit A38

In Asterix Conquers Rome, Asterix and Obelix have to get Permit A38 from the Place That Sends You Mad. They’re sent from counter to counter through an escalating maze of forms and requirements, nobody ever says no, and the procedure itself is what prevents them from getting the thing the procedure exists to provide.

Here is the circuit I’ve been sent around, in order:

  1. Three submissions are closed for containing no proof of concept. Each has a proof-of-concept archive attached, listed on the same page as the closure.
  2. I open a support ticket. It’s closed: the status is final, and if I disagree I should submit a new report to the program.
  3. I submit a new report, with the argument about the missing proof of concept in the first paragraph. It’s closed with the same message, the argument isn’t addressed.
  4. I use Request a Response, which is the mechanism for exactly this. It has been open and unanswered since 25 August. I can’t cancel it or replace it.
  5. I open a second support ticket, a complaint about how those closures were handled. It’s closed: I haven’t used Request a Response on the three original submissions, I should do that before support can assist further, and a second use counts as an Appeal.
  6. I can’t. Both of my account slots are held by open requests, one of them the request on the re-submission that the answer doesn’t mention.
  7. A report on a different program, with a runnable proof of concept attached, is closed as low-quality with no proof of concept. I can’t open a request on it, both account slots are held by requests nobody has answered.
  8. I open a third support ticket, stating in bold that it’s about conduct, not the outcome of the triage. It’s closed: the outcome of the triage is final, and if I disagree I should submit a new report to the program, which is where step 2 sent me.

Every one of those replies is procedurally plausible when read on its own, and moves me to another counter. The last counter is the one I’m already standing at, holding a ticket nobody has called.

I don’t think the August change was designed to create this deadlock, it looks more like the timer was removed without anyone thinking through what happens to a request that never gets an answer. What I do think is deliberate is what happens after the deadlock exists. Whatever Request a Response was designed for is beside the point, I have no internal documents and no way of knowing what the people who created it intended. What I can see is how it’s being used now, and in this case it’s being used as Bugcrowd’s Passierschein A38: a procedural mechanism that turns a question Bugcrowd would otherwise have to answer into another procedural obligation for the researcher. Each time I ask why the handling was wrong, the answer is about a step I supposedly haven’t taken yet. Submit a new report, done. Use Request a Response, done. Use it a second time as an Appeal, which I can’t, because the first one is still open and Bugcrowd has removed the mechanism that used to make an unanswered request end. The existence of the mechanism becomes evidence that a remedy exists even though the mechanism isn’t producing one.

What would fix it

I still think the rule is the one I wrote in July: a request for a response should produce a response. Keeping requests open until they’re answered only makes sense if they’re answered within a reasonable time, so something has to happen when they aren’t, preferably something other than “well, that’s too bad, better luck next time”.

The old deadline could escalate instead of expiring. After a defined period with no reply the request moves to another queue or another team, and the researcher gets neither a fake resolution nor a silent dead end.

Failing that, some smaller changes would at least remove the trap:

  • Let researchers withdraw an open request, so an unanswered one is a delay rather than a permanent block.
  • Release the account slot after a fixed period without a response, without closing the request. The old ten business days would do. The request stays open and unresolved, the researcher gets the slot back. The limit is there to stop researchers opening requests faster than anyone can answer them, and a request nobody has answered in two weeks isn’t that.
  • If two requests on a submission are an appeal, document it, and route the second one to somebody other than the person who made the original decision. Otherwise it’s the same question to the same queue.
  • A closure should say what was tried. Bugcrowd’s own guidance for Not Reproducible already says to “provide detail so the researcher can improve”.
  • Don’t prescribe a procedural step that the platform itself makes unavailable.

How to implement it is Bugcrowd’s choice, what matters is that silence can’t be the terminal state of a mechanism whose whole purpose is to get a response.

Where it stands

I ended the July post by saying that a researcher doesn’t need to come out of a dispute with the decision they wanted, but should come out of it knowing that someone considered the disagreement and answered it. That’s still what I’m asking for.

The request I opened on 25 August is still open. The second one is too. I can’t cancel either of them, replace them or escalate past them, the report closed on 21 September can’t be questioned at all until one of them is answered, and all three support tickets are closed. Bugcrowd implemented none of the four changes I proposed in July and removed the deadline instead, which changed the failure mode without fixing it. So the requests can’t expire anymore, and I’m still waiting for the response.

Similar Posts