Shopify · Report #300305
Ability to bypass partner email confirmation to take over any store given an employee email
Summary
@cache-money reported it was possible to bypass the email verification process in our Partners Dashboard. Doing so would have allowed a Partner to request access to a store under an email address the Partner did not own. If the store had a staff account associated with that email address, the staff account would have been automatically converted to a "collaborator" account and added to the Partner's dashboard without any merchant interaction.
We tracked down the bug to a race condition in the logic for changing and verifying email addresses. We fixed it by locking the database record during those actions and requiring store administrators to approve all collaborator requests.
After reading Shopify's summary from #270981 a few of times I was able to replicate the intended behavior. Seeing how it worked, I realized the core behavior to investigate was the automatic conversion aspect of it. In order for the conversion to work, you needed to confirm a store employee's email on a partner account. From there you could add the store on the partner account as a "managed store", which will then perform the automatic conversion and give you collaborator access. The bug existed in the email confirmation, which allowed me to confirm arbitrary emails under my partner account via race condition.
The bug was filed on Christmas Eve, and within 12 hours the Shopify team rolled out a fix to address the immediate issue. It was a pleasure to work with a team that takes security as seriously as they do.
How it was found
I told Pete I would take a look at Spotify, hi Pete.
Summary It's possible to take over any store account through partners given an employee email address. This is possible because I found a way to confirm arbitrary emails. I don't know the Shopify ecosystem well enough to know the other ramifications of such a bug.
On #270981 you wrote:
The intention was that, when a partner already had a valid user account on the store, their collaborator account request could be accepted automatically, with the user account converted into a collaborator account.
I tested that functionality and confirmed how it works. I realized that if you can somehow create a partner account with a business email that matched that of an employee, you would be able to take over their employee account, then convert it to a collaborator. The problem is that business accounts need emails to be validated, but this can be bypassed with a race condition.
The bug works by hitting the email validation endpoint for an email you own, at the same time as changing your email to a victim's. It might take a few tries, but eventually your email will be changed and be validated due to not (properly) using a DB transaction.
Steps to reproduce
- Create a store account and invite an employee.
- Accept the employee invite (maybe not necessary I didn't test).
- Login to or create a partner account as the attacker.
- Go to your partner settings page
https://partners.shopify.com/[ID]/settingsand change your email to something you own. - Check your email and grab the confirmation link, but don't visit it yet.
- Go back to your partner account and change your email to that of the store employee from step 2, but intercept the request to not let it through yet.
- Now the tricky part. The "change email" takes anywhere from 1,100 - 2,500 ms to load so you need to take that into account. But let the request go through, wait for some milliseconds, then in another tab visit that email confirmation link from step 5.
- If done correctly you will now have confirmed an email you do not own.
- Visit
https://partners.shopify.com/[ID]/managed_stores, add the store, and you now have access.
As proof, look at the email for partner account 698396. It will be confirmed [email protected], which I obviously would never be able to validate otherwise.
Thanks, -- Tanner
Impact
Ability to take over stores, and possibly perform any other action that relies on a validated email as a security measure.