History of one XSS in Telegram

Before diving into the details of the specific vulnerability I found, let’s take a quick look at the general attack strategy I used. This attack method is well known in the cybersecurity community and consists of injecting a javascript pseudo-protocol into HTML links. Briefly, it looks like this:

<a href="https://habr.com/ru/articles/744316/javascript:alert()">Click Me!</a>

Of course, if we send such a link via Telegram, we will not see the expected result:

In this regard, I decided to take a closer look at the source code of the Telegram web client and found the following code snippet:

export function ensureProtocol(url?: string) {
  if (!url) {
    return undefined;
  }
  return url.includes('://') ? url : `http://${url}`;
}

This code checks for the presence of a protocol in links coming in messages, and if there is no protocol, it automatically adds ‘http’ to the beginning of the link.

This approach to validation is incorrect and definitely not in line with the RFC standard. An example of bypassing this check is trivial:

slonser.ru/#://

When sending a message with such a link, you may notice that the web client has not added http:// to the beginning of the link. Therefore, when clicking on it, the user will be redirected to http://web.telegram.org/slonser.ru/#://.

However, if we tried to paste a link in the following format:

javascript:alert()/#://

We would find that our link was not parsed correctly. What is the reason? Perhaps Telegram has a blacklist for some links? Or perhaps they still check the javascript protocol separately on the server side? The answer, of course, is no! The point is that the characters “:” and “()” are not valid for domain names, and therefore the regular expression on the server does not recognize this as a link.

For a moment, I thought, deciding that the attempt failed, and perhaps Stored XSS in Telegram will remain an unattainable dream. However, I was able to come up with an elegant solution pretty quickly:

javascript:alert@github.com/#://

What happens in this example? This link uses HTTP Basic Authentication and the Telegram backend interprets this as a link to github.com with authentication data: username equal to “javascript” and password equal to “alert” (and in a sense this is correct). As a nice side effect, we get a preview of our link that looks like a valid GitHub link:

This greatly increases the potential threat from an XSS attack, as users may be convinced that they are looking at a normal link to GitHub. Now it remains to solve the issue with characters that are not allowed in the username:password section when parsing. The solution is to use character encoding with the urlencode function. Here is the final version:

javascript:alert%28%27Slonser%20was%20here%21%27%29%3B%2F%2F@github.com#;alert(10);://eow5kas78d0wlv0.m.pipedream.net%27

After clicking on this link, we will see the expected result:

Part 2

Let’s consider what this vulnerability allows to do, for example, if we send a link to a large chat, we can, on behalf of the victim:

  1. Read all messages of the user, as well as send messages on his behalf.

  2. Completely take over the user account, for example by sending a request to set a new password.

  3. Read messages with codes for entering Telegram that come to the application.

  4. Get Remote Code Execution (RCE) at Version Telegram powered by Electron! Yes, you heard right, by clicking on a specially crafted link, the victim can unwittingly give the attacker access to their computer.

Part 3. Communication with Telegram Security

The chronology of events developed as follows:

  • June 17 – sent a report about the found vulnerability to Telegram, but did not receive a response.

  • June 21 – discovered that the vulnerability was fixed, but there was no response from the Telegram team.

  • Jun 24 – Submitted an inquiry regarding the status of my Vulnerability Report. Again there was no answer.

  • June 26 – thanks to connections through acquaintances, I was able to directly contact the Telegram security team. Received a response:

    Hello,

    Thank you for your email. We will send you an update soon.

    All the best,Telegram Support

  • June 27 – received the message: Thank you for your report. We would like to award you a bounty of XXXX euro for your findings.

I deliberately hid the amount of the reward in order to test the detective skills of the readers of this article. As a hint, Reddit’s bug bounty program, which has similar conditions (with a maximum in-app payout of $10k as Telegram), provided $5k for a similar problem.

So how much did they pay me?

Answer

Do I think this amount is fair? – No.

Is Telegram allowed to do this? – Yes, definitely. They do not have a clear gradation of vulnerabilities and corresponding payouts on their bugbounty platform.

What are my impressions? – Negative. It seems that Telegram is not particularly interested in ensuring its security. I’m not sure it’s worth it to search for vulnerabilities for the sake of such an experience.

Part Final. conclusions

My conclusions are the following:

  1. Even in such an advanced application as Telegram, you can find basic and, it would seem, entry-level errors. Therefore, always dare to analyze even the most complex applications, as you will probably be able to discover something interesting.

  2. Unfortunately, Telegram’s bugbounty program leaves much to be desired. There is no clear gradation of vulnerabilities, support does not always respond to requests, and the fairness of payments is questionable.

Hope this article was helpful for you. I look forward to your comments!

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *