Yaamlabs
Bug bounty

Bug bounty roundup: nine disclosed reports worth reading

Nine publicly disclosed HackerOne reports from the past two weeks, from Shopify to WordPress, with what each bug was and the check that would have stopped it.

By Yaali. November 6, 2026, 7 min read, Bug bounty, Vulnerabilities.

Cover illustration of a magnifying glass over a stack of report pages with a bug-in-shield icon, with the Yaamlabs logo and the text: Nine disclosed bugs, and what fixes them, $4,126 paid across the two reports that list a bounty

This roundup collects nine bug bounty reports that became public on HackerOne between 26 October and 5 November 2026. Researchers found the bugs and the programs fixed them, and the reports were then disclosed. We credit each researcher by handle and link the original write-up. We summarise the bugs so developers can recognise the pattern in their own code. We do not reproduce exploits.

Most of the nine come down to one mistake: a check that exists in one code path and is missing from its sibling. A staff-only page is blocked at one URL and open at another. A permission is enforced on read and forgotten on write. Only two of the nine list a bounty, a combined $4,126, because most programs choose not to publish amounts.

Table of nine disclosed reports with program, bug, severity and bounty: Shopify $3,100, Vercel $1,026, and seven reports with no listed bounty

Missing authentication on Shopify staff routes

A Next.js app behind Shopify's Checkout Blocks exposed employee-only pages under /internal. The protection was a rule that redirected requests matching that path to the staff login. Next.js also serves each page as a JSON data file under /_next/data/<buildId>/, which does not match the rule, so the same handlers answered with no login. The build ID is printed on the public login page. The researcher saw merchant metadata, with a total of 201,520 records, and used only their own test shop.

The lesson: authorise inside the handler or in framework middleware that sees every route form, not with a URL pattern in front of it. Program: Shopify. Severity: medium. Bounty: $3,100. Reporter: cafecito. Report: https://hackerone.com/reports/3954327

Revoked token works again at Vercel

Vercel's deployment toolbar lets collaborators comment on a preview. After a collaborator was removed, their token correctly returned 403. When another active collaborator then used the toolbar, the removed user's old token worked again against the sync endpoint and returned private comment threads. The behaviour points to an authorization cache that a later normal action refreshed from stale state.

The lesson: revocation has to delete the credential or its server-side session, and a flag that another code path can overwrite is not enough. Test it by revoking a user, then exercising every other user's features. Program: Vercel. Severity: medium (CVSS 4.8). Bounty: $1,026. Reporter: qub. Report: https://hackerone.com/reports/3852102

Cross-account webhook edits in Basecamp

Basecamp's webhook update handler decided who could change a webhook by looking at the project's visibility, not at whether the caller belonged to the account that owns it. A user with their own account could put someone else's account ID in the path and change or delete a webhook belonging to a project set to All-access. The read handler for the same webhook refused the request, which is how the researcher knew the write handler was the odd one out. Webhook IDs also came from one counter shared by all accounts, which made them easy to guess.

The lesson: every handler that takes an object ID needs its own ownership check, and tests should cover each verb (GET, PUT, DELETE) separately. Program: Basecamp. Severity: high (CVSS 8.3). Bounty: not disclosed. Reporter: deivizzzz. Report: https://hackerone.com/reports/3979217

An OAuth server that trusted any redirect

37signals runs its own OAuth 2 authorization server for the Basecamp API. The report says any signed-in user could register an OAuth client with a redirect address of their choosing, with no ownership check, and that the legacy implicit grant was still switched on. In that grant the access token travels in the URL fragment to the registered address. A victim who approved such a client would hand a working token to the registrant. The reporter rated it CVSS 9.1; the program record shows 8.0.

The lesson: require exact-match, pre-registered redirect URIs, require PKCE (Proof Key for Code Exchange, a one-time secret that ties the code to the client that asked for it), and disable the implicit grant, which current OAuth guidance has deprecated. Program: Basecamp. Severity: high. Bounty: not disclosed. Reporter: rootaccessxvv. Report: https://hackerone.com/reports/3955956

A payment webhook that fails open on WordCamp

The CampTix Instamojo addon on WordCamp.org marked ticket orders as pending or paid without proving that a payment belonged to the order. An invalid signature on the payment notification still moved the order forward, and a valid notification for any cheap payment on the same merchant account could complete a different order, because the order token sat in the query string outside the signed body. The researcher pointed out that the sibling Razorpay, Stripe and other payment methods in the same plugin store the payment ID and amount and compare them.

The lesson: a webhook handler should reject any request whose signature fails, and should check the payment ID and amount against what the order expects before changing its state. Program: WordPress. Severity: high (CVSS 8.7). Bounty: not disclosed. Reporter: 0xbs0d27. Report: https://hackerone.com/reports/3941626

Private posts readable through Secure Custom Fields

The Secure Custom Fields plugin resolves stored post IDs through a helper that asks WordPress for posts in any status and never checks whether the visitor may read them. An anonymous request could therefore receive the body, author and plaintext post_password of draft, private and password-protected posts that WordPress core would answer with 404 or 401. A hardening change in version 6.9.3 covered the plugin's AJAX paths but not this one.

The lesson: when you patch one entry point to a function, search for every other caller of it. Program: WordPress. Severity: high. Bounty: not disclosed. Reporter: 0x200notfound. Report: https://hackerone.com/reports/4152553

An inverted check exposed organizer data

The WordCamp Reports plugin exports a private CSV of Meetup organizer details, including contact information and notes. The gate that should block users without the right capability joined its two conditions with AND instead of OR, so the export was refused only for someone who both had an invalid nonce and held the capability. Everyone else got through, including signed-out visitors. Sibling reports in the same plugin had the check written correctly.

The lesson: put authorization checks in one shared helper, and write a test where an anonymous user requests every export. Program: WordPress. Severity: high (CVSS 8.7). Bounty: not disclosed. Reporter: 0xbs0d27. Report: https://hackerone.com/reports/3871816

Editors inviting Administrators on wordpress.org

On Rosetta locale sites, Editors may invite existing network users but are blocked from assigning the Administrator role through WordPress's editable_roles filter. A wordpress.org plugin stored the invite with the requested role before consulting that filter, and the later step that applies the invite did not re-check it. An Editor who sent role=administrator by hand, a value the form does not offer, could create an invite that made the account a site Administrator.

The lesson: validate the role on the server at the moment you store it and again when you apply it, and never trust the choices a form displays. Program: WordPress. Severity: high (CVSS 8.7). Bounty: not disclosed. Reporter: 0xbs0d27. Report: https://hackerone.com/reports/3942522

Version control metadata left in Weblate downloads

After a June 2026 fix (CVE-2026-61792) hardened Weblate's translation ZIP downloads, the code that strips version control folders listed only .git and .hg. Subversion and Bazaar folders, .svn and .bzr, were not removed even though Weblate supports Subversion and its own copy code excludes both. A repository migrated from SVN could therefore ship its wc.db working-copy database, and any cached credentials, inside a downloaded archive. The reporter labelled it incomplete hardening rather than proven credential theft.

The lesson: follow-up fixes should reuse the existing list of excluded paths instead of writing a second one. Program: Weblate. Severity: medium. Bounty: not disclosed. Reporter: sumit-sabhaya. Report: https://hackerone.com/reports/4037976

What to check in your own code

Write one test per verb and per route form for anything that returns or changes another user's object, run as a user from a different account. Search for every caller of a function you just patched. Compare a new handler against its closest sibling and look for the check that one has and the other lacks. Run a revoke-then-use test for every token type you issue.

If you want an outside team to run those checks against your application, our web application penetration testing covers authorization testing across roles and accounts, and red team code review reads the source for missing checks like these. Open the chat and Yaali, our AI agent, will pass your question to an engineer.


Sources: Individual reports on HackerOne: https://hackerone.com/reports/3954327, https://hackerone.com/reports/3852102, https://hackerone.com/reports/3979217, https://hackerone.com/reports/3955956, https://hackerone.com/reports/3941626, https://hackerone.com/reports/4152553, https://hackerone.com/reports/3871816, https://hackerone.com/reports/3942522, https://hackerone.com/reports/4037976. Archives used for ranking and detail: https://github.com/ajaysenr/HackerOne-Disclosed-Reports and https://github.com/Gh0stSpy/HackerOne-Disclosed-Reports-Database

Read next

Back to the blog, or tell us about your system in the chat. Yaali, our AI agent, answers first and brings in an engineer.