Discord DoS with a single message

Crafted message causes causes denial of service on a Discord channel


TLDR: I discovered that sending the message http://%zz@example.com from the mobile app would result in a permanent denial of service of a Discord channel on the web and desktop clients.


It began when my mentor, @fransla, sent me this blog post about a WhatsApp vulnerability and encouraged me to look for similar bugs in other Electron-based chat clients. I started with Discord.

First I checked to see if the link’s preview text was being generated by my client or the server, in the hopes that I could edit the preview that was being displayed to other users. That wasn’t successful, so I moved on to play with the @ symbol in my URLs.

URLs can provide a username and password for authentication in the following format user:pass@website.com. Discord’s mobile app completely stripped the authentication part of the URL, while the desktop and web clients left it in the link. This inconsistent handling of authentication URLs immediately raised red flags, as it indicated that special code was used when an @ was present. With further testing, I discovered that the Discord server was not validating percent encoding correctly, and was accepting percent symbols even if they didn’t have two hexadecimal characters after them.

BackendMobileDesktopWeb
Displays the user:passN/ANNN
Link contains the user:passYNYY
Accepts percent encoded symbols (%78)YYYY
Accepts unicode percent encoding (%u0078)YYNN
Different handling between the server and each of the clients

The desktop and web clients break when they receive invalid percent encoding in the authentication part of a URL. This happens because the JavaScript URL parser creates an uncaught error when it attempts to decodeURIComponent the authentication prefix.

The message http://%zz@example.com can be successfully sent from a mobile app, or by intercepting and editing the POST request to the server. The mobile app isn’t affected and displays a link to http://example.com. The desktop client will not receive any future messages, and reloading the desktop and web clients will result in a never-ending loading screen — no messages in that channel can ever be viewed again (except on a mobile device).

discord_1.png
This is what a user will see after reloading the web client
discord_2.png
Desktop client: a never-ending loading screen greets the user

Discord’s time-to-patch was impressively short, with the patch being made live on the same afternoon that I received a human reply, less than two days after my initial report. The patch was released on Feb 13 2020 and no clients are currently vulnerable. Discord security described it as “just a client parser bug” so no bounty was awarded.


Thanks again to @fransla for pushing me on when I would have given up :)


Last updated: 13 Feb 2020