Stealing passwords from infosec Mastodon – without bypassing CSP

by Prapattimynk, Tuesday, 8 August 2023 (7 months ago)
Stealing passwords from infosec Mastodon – without bypassing CSP


Recording that shows click a fake Mastodon toolbar to demonstrate a HTML injection vulnerability that enables you to steal credentials

The story of how I could steal credentials on Infosec Mastodon with a HTML injection vulnerability, without needing to bypass CSP.

Everybody on our Twitter feed seemed to be jumping ship to the infosec.exchange Mastodon server, so I decided to see what the fuss was all about. After figuring out why exactly you had to have loads of @ symbols in your username, I began to have a look at how secure it was. If you’ve followed me on Twitter you’ll know I like to post vectors and test the limits of the app I’m using, and today was no exception. 

First, I began testing to see if HTML or Markdown was supported. I did a couple of “tweets” to see if you could have code blocks (how cool would that be?) but nothing seemed to work. That is, until @ret2bed pointed out that you could change your preferences to enable HTML! That’s right people, a social network that enables you to post HTML – what could possibly go wrong?

I enabled this handy preference and redid my tests. Markdown seemed pretty limited. I was mainly hoping for code blocks but they didn’t materialise. I switched to testing HTML and tested for basic stuff like bold tags, which seemed to work on the web but not on mobile. Whilst I was testing, @securitymb gave me a link to their HTML filter source code and he showed me a very interesting vector where they were decoding entities.

This gave me the feeling that this platform’s HTML filter wasn’t the best. I studied the source code and found that it supported a few different attributes. What looked promising was the “title” attribute, maybe I could embed tags in there and break out of it? I did a private “tweet” to see if it worked:

Input:

title="">test

Output:

title="">test

The content of the attribute was retained as is. This was great. It gave me a payload to use if I figured a way to break out of the attribute! Using the abbr tag I looked for single and double quotes, both of which were supported – although it seemed single quotes were converted to double quotes, I also tried quoteless attributes but they seemed to be removed. After many different private “tweets”, I couldn’t find a way to break out of the attribute.

I noticed a couple of people had a verified Verified icon icon in their name and after asking some questions to the very helpful community, I discovered that if you use the text :verified: it would be replaced with an icon.

Input:

:verified:

Output:

draggable="false" class="emojione custom-emoji" alt=":verified:">

The icon was an img tag and it had quotes, maybe I could use that? I placed the :verified: string inside a anchor text node that was inside the title attribute:

Input:

title=":verified: