Unsubscribe Anyone From Chess.com

07 January 2022 #software #security

I recently got some junk email from Chess.com. I don’t really use the website much anymore since I’ve switched to lichess. I clicked the handy “unsubscribe” link, which took me to a page that allowed me to select which emails I didn’t want (or unsubscribe from all of them).

But something looked funny about the URL…

Why is my plaintext email being used as a parameter on this page? (I switched my email with example here for privacy). Right away this was a red flag for me. Hoping that it might be using the fact that I was logged in already, I opened an incognito window and navigated to the same URL. Sure enough, it looked exactly the same, so I hit “Unsubscribe from all” and then “Save”.

I switched back to the logged-in regular window and navigated to my account settings at https://www.chess.com/settings/notifications. Lo and behold, the changes were saved.

Anyone can navigate to the /unsubscribe endpoint with any email as the parameter. This means all a malicious actor needs is your login email and they can unsubscribe you from any or all Chess.com emails. To add insult to injury, if you select the “Unsubscribe from all” option, the user is irreversibly unsubscribed from emails and has to contact support to fix this. These users can’t even reset their own passwords!

How to Handle Email Unsubscription

Obviously Chess.com didn’t implement things the right way here. There’s a couple ways we can properly handle scenarios where the user wants to unsubscribe from emails:

Via Email

When you see the helpful “Unsubscribe” button in your email client, this is because most senders choose to include a List-Unsubscribe field in the email header to provide a way for recipients to easily unsubscribe from unwanted emails. According to the relevant RFC section 3.2, the “preferred” way is to include an unsubscribe email, such as mailto:unsubscribe@chess.com. With this, the server can see who has sent the email to the “unsubscribe” address, and can update that user’s settings. There are several widely used methods for authenticating and verifying that an email sender is who they say they are, which most mail servers support out of the box.

Via a Web Page

Of course, sometimes we might want to give the user more options on what they’re unsubscribing from, as Chess.com is doing. In this case setting a web page in the List-Unsubscribe field can make sense. Requiring the user to sign in to edit their email preferences may be inconvenient (though more secure!), but as we’ve seen just using their email as a URL parameter is a big no-no.

Instead, we could generate some sort of unique token for each user and use this in the unsubscribe link. In Rails land we would typically use something like a Signed Global ID limited to the email unsubscribe route and with a reasonable expiration time. Plenty of other websites use this technique with no problem, so there’s no reason Chess.com couldn’t do this too.

Update December 2023: Chess.com now requires you to sign in before accessing your account’s email notification settings, and being unsubscribed from all emails does not include password reset emails anymore.