November 5, 2026
How a Broken Email Confirmation Flow Took Over Any Shopify Store
Real chain this time, not one report but three linked ones, all from the same researcher, Ron Chan, who goes by ngalog on HackerOne. This…

By L4ZZ3RJ0D
5 min read
Real chain this time, not one report but three linked ones, all from the same researcher, Ron Chan, who goes by ngalog on HackerOne. This is genuinely one of the highest-paid, most-upvoted report chains in HackerOne's entire history, $16,000 on the first one with over 1,800 upvotes, another $15,000 on the follow-up, and a further $7,500 on a third report that closed the one gap the first two left open. Original reports are public, here's the first one and the one that builds on it: Email Confirmation Bypass in myshop.myshopify.com and Able to Takeover Merchants Accounts Even They Have Already Setup SSO. Worth reading his own words directly, what follows here is a reconstruction of the thinking, not a replacement for it.
The whole chain hinges on one specific moment every account system has to handle correctly: what happens the instant a user changes their email address, and how the system decides that the new address actually belongs to them before trusting it. Nearly every platform does this the same way, you submit a new email, the system sends a confirmation link to that new address, and nothing about the account actually changes until someone clicks that link proving they control the inbox it landed in. Simple in concept. The entire bug lived in exactly where that verification step actually anchors its trust.
Chan's starting move was deceptively simple: create a brand-new, throwaway Shopify trial account using his own email address, something any attacker can do with zero privilege at all, this is the part worth sitting with, the entire attack begins from a position any random visitor can reach. From inside that fresh account, he went to the account settings page and submitted a request to change the account's email to an address he didn't actually own, one already registered to a real, existing Shopify merchant account elsewhere on the platform.
Most systems would stop right there, either refusing to let you claim an email already tied to another account, or sending the confirmation link to that other account's owner instead of to you. What actually happened was neither of those safe outcomes. The confirmation link meant to verify ownership of that target email ended up delivered back to Chan himself, reachable from the session he already controlled, rather than ending up exclusively in the actual victim's inbox the way the entire design of email verification depends on.
That single mechanical failure, a confirmation token generated for one email ending up reachable by whoever initiated the request rather than strictly gated to the new address's actual owner, is the entire root cause underneath every dollar of that six-figure combined payout. Once Chan could click through that link himself, the platform treated the email as confirmed and legitimately owned, at which point the account-merge logic that email verification unlocks took over, and that merge logic trusted the confirmation step completely rather than re-checking anything about who actually controlled the target account to begin with. Email verified meant game over, control of the real merchant account that owned that address became reachable from the throwaway trial account the whole chain started from.
What makes this worth studying beyond the first report is that Chan didn't stop once Shopify shipped a fix. He went back and specifically tested the patched flow against a case the first report hadn't covered, merchant accounts that had SSO configured through Shopify's own single sign-on system rather than a plain password. The natural assumption, and apparently the engineering team's own assumption when scoping the first fix, was that SSO accounts were inherently safer here, since merging into one supposedly still required entering that merchant's actual password at some point in the flow.
Chan's second report picked that exact assumption apart. Walking through the merge process manually, he noticed that at one particular step, the one meant to ask for the target account's password, the URL sitting in the browser's address bar followed a specific, guessable pattern, something like accounts.shopify.com/login? followed by a query string carrying the session context for that merge. His actual move was almost absurdly simple once you see it stated plainly: leave every part of that query string completely untouched, and just change the path portion of the URL itself from /login to /accounts_merge/new-password.
That one substitution dropped him straight into a password-creation screen for the account being merged into, completely bypassing the password check the design assumed was mandatory. The multi-step merge process was apparently tracking which step you were on purely by which URL you'd navigated to, rather than by verifying server-side that each step had actually been reached in the correct order with the correct authorization behind it. The query string carried session identifiers that stayed valid across that entire merge flow regardless of path, so swapping the path alone was enough to skip straight past the one check meant to stop exactly this.
This is really the generalizable lesson underneath both reports, and the one worth actually carrying into your own hunting rather than just admiring from a distance. Any multi-step process, a signup wizard, a checkout flow, an account-recovery sequence, an SSO merge, is only as secure as whichever side is actually enforcing that the steps happened in the right order. If that enforcement lives in the UI, hiding a button here, redirecting you there, and the server underneath just trusts whatever path or parameter you hand it next as long as the session token checks out, then the real state machine isn't a state machine at all, it's a suggestion. The single move worth trying on every multi-step flow you ever test is exactly what Chan did here on two separate occasions: once you're sitting on a legitimate step of a flow, try substituting the URL for a different step entirely while keeping every other parameter, cookie, and token exactly as issued, and watch whether the server actually re-checks that you were supposed to be allowed there, or just lets you walk straight through.
The impact scaled as far as it did because of how cleanly the two bugs chained. The first one handed over verified control of arbitrary email addresses, the actual keys to proving ownership of any account on the platform. The second one closed the one remaining gap that email control alone didn't cover, accounts protected by SSO where a password still theoretically stood in the way. Individually, either bug reads as a serious but bounded authentication flaw. Chained together, they added up to full, unauthenticated takeover of any Shopify merchant account on the entire platform, SSO-protected or not, starting from nothing but a free trial signup. That's the part worth remembering about chaining in general: the business impact of two bugs together is very rarely the sum of their individual severities, it's usually a full category higher, because the second bug exists specifically to close whatever excuse the first one left standing.
Happy hunting, see you in the next scope :)