What a Part-Time Bug Bounty Actually Looked Like
What I hadn’t done until May 2026 was actively participating to live Bug Bounty programs and find out how much of that survives contact with a real triage queue. Twelve reports since then filed across Bugcrowd, HackerOne and Intigriti, on whatever weekends were free.
Targets stay anonymous, including what sector they’re in.
Bugcrowd: 5 reports
The first one is the one I’d put on a CV, and it’s the one that went worst. A document export feature rendered arbitrary pages server-side. The renderer turned out to be an old headless browser build with a debugging interface listening on loopback, and the export endpoint could reach it. That chain gave me read/write access to files on the renderer host, including the application’s own environment file with production database credentials. Same host as the web application, not an isolated container. So I reported it with all the evidence I had. Somewhere in the same stretch the endpoint got patched quietly, a couple of days after my testing weekend, with nothing posted on the thread. Thirty-four days later, an analyst closed the report: severity rewritten down to low-impact external SSRF, and marked a duplicate of a plain P5 report on the same entry point filed two weeks before. Two problems with that. The low-impact external classification describes blind SSRF, and this chain terminated at a service on loopback, which is a different branch of their own taxonomy. And the parent report sat unremediated for eighteen days, right up until my testing weekend. I requested an impact-variance appeal. Still waiting.
Second: indirect prompt injection into an AI assistant. The product let its assistant read third-party social media content on the user’s behalf. Instructions planted in that content reached the tool-calling layer. The assistant disclosed account data nobody asked for and made a state-changing write nobody authorised, then reported back to the user describing actions it hadn’t taken and omitting the ones it had. If you’re the victim, the interface lies to you about the state of your own account. Collaborative finding, and most of the work was my teammate mrugi1, who is a very good researcher. P2, paid, still unresolved.
Third: markdown image exfiltration from a different AI assistant. I got the system prompt out first, just by asking for more structure and detail until the model walked me through its own instructions and tools. That gave me the attacking map. The assistant then rendered attacker-supplied markdown images with no restriction on where they pointed, so an image URL aimed at my host became a silent request carrying whatever I could get into the model’s context. Out came private account analytics and data belonging to third parties who had never touched the assistant. I filed it under the platform’s own taxonomy for system prompt leakage, which sits at P2 baseline there. Closed Not Applicable, on the reasoning that a prompt leak isn’t a vulnerability and no sensitive information was exposed. Which is odd, given the assistant refuses to show its own functions and render any markdown.
Fourth: an authentication flow bypass across a shared multi-site estate, where feeding external credentials to a secondary login path silently provisioned local accounts that then authenticated normally, sidestepping the header-based gate entirely. Alongside it, an endpoint returning internal staff names, internal email addresses and internal network addressing + some private messages from staff to IT. Reported P3, closed as a false positive. They later patched one of the parameters I’d reported and added a firewall rule for exactly the account pattern I’d described.
Fifth: a stored open redirect that persisted in a server-side cache, on user-generated content, with attacker-controlled link previews. We control the page and the destination, and it stays there for every single person who loads the feed. Closed as duplicate, still unresolved
HackerOne: 4 reports, all Informative
First: full system prompt extraction past an explicit sensitivity filter. Asking plainly gets you a hard block, so the control exists and somebody built it deliberately. Adding a pseudo-technical encoding phrase to the same request bypasses it completely and returns the whole prompt. I wrote the report around that framing on purpose, because “an AI was chatty” is a weak finding and “your security control fails against a trivial reframe” is the main finding. The filter’s existence iconfirms that it shouldn’t be disclosed. Closed Informative anyway.
Second: a content-ingestion endpoint on a public host that fetched arbitrary URLs server-side and returned the full response body to an unauthenticated caller. So not as blind SSRF, but as nothing especially sensitive came back – I can see the argument for Informative on this one.
Third: an embed feature that renders external content in publicly shared documents with no viewer consent. The iframe loads as part of the normal page render. There is an approval button, but it appears after the loading, so it acknowledges rather than gates. My first testing round ran in a browser that had seen the product before, and the behaviour looked like a timing bug, as though a gate existed and the load was winning the race. I retested everything from a clean browser state and found there was no gate to race against. So if I sent the first version, triage would have had a true correction to make and the report would have closed on it. Nevertheless still closed as Informative, with the reasoning that the embed is designed to load external URLs so this is core functionality, the sandbox correctly prevents access to the parent page, and the rest technically requires social engineering. Every one of those sentences is true on its own, which is what makes it hard to argue with. But statement is: “each component behaves as designed” is a bit ankward in that case because of what the composition of the components does to a viewer who doesn’t know it’s happening.
Fourth: a signing key shipped in the client bundle, which on its own is a weak report and I nearly didn’t sent it. What made it interesting was the second thing, a captcha enforced in the browser flow and never validated by server-side. Together that’s unauthenticated SMS dispatch to arbitrary numbers through the platform’s own gateway, with their name on the sender. SMS pumping is a named fraud category which some programs historically have paid a lot for. I kept testing tight: only numbers I control, stopped as soon as the bypass was confirmed rather than generating volume. Closed as Informative, addressing the signing key only. The captcha bypass, which is the actual finding, wasn’t mentioned at all. I checked it back later. The key is still in the bundle, unrotated, which is consistent with their stated position. But this time a rate limit had appeared on the endpoint. Nobody rate-limits an endpoint whose protections are working.
Intigriti: 3 reports
First: an information disclosure through an unusual request method against an API gateway, returning internal infrastructure identifiers that had no business being in a response. Accepted as Medium. The useful lesson is in what carried it. I’d written the report around one angle, and triage accepted it on a different one, taking the concrete internal-topology disclosure as the finding. They read it, found the part that stood up, and graded it honestly.
Second: a pre-authentication open redirect on an SSO login endpoint, worth more in a credential-phishing chain than its rating suggests. Duplicate, points awarded. Fine.
Third: an open redirect on a storefront cart path, verified end to end rather than asserted. Closed not applicable. The program’s low ceiling was fifty euros, so I didn’t argue. Some disputes aren’t worth the time.
The pattern I didn’t expect
Three of these twelve reports were closed as not-a-bug and then quietly remediated: a parameter patched after a false-positive closure, an endpoint patched right after the testing, a rate limit added after an Informative. That gap is the one thing I’d want a person who is reading this to think about. When a fix appears after a dismissal, the classification is wrong and everyone involved can see it. Reopening costs nothing. Leaving it wrong costs you the next report that researcher would have sent.
What I actually learned
The technical side transferred cleanly. The chains have the same shape as CVE work: enumerate, pivot, escalate, prove. The hard part is the gap between a severity number and what a program will pay. With a CVE the bug either works or it doesn’t, and the write-up is just a technical document. I also got proof-of-concept calibration wrong twice, in opposite directions. On the one finding I held back too much and the impact never became visible. On the export chain I pushed harder than I’d planned on a live host. Same outcome either way.
I’ll keep submitting occasionally. The bugs are there and worth finding and provided great experience. Whether the record ends up reflecting that is apparently a separate question.
Still many things to learn 🙂
