
Multiple CSRF vulnerabilities in the largest Runet portals
Forgive me for the Securitylab-style headline, but the fact remains.
At first I planned to write about CSRF vulnerabilities that I found in one of the largest Runet portals. But it turned out that not only this portal, but most of the largest resources are exposed to these vulnerabilities. I reported the problems to the respective companies a month and a half ago. Now I again had time and I looked at what was already closed. It turned out that in a month and a half only 1 vulnerability was closed.
Because the vulnerabilities are still working, I will write only where I found them and how they can be used. In a week I promise to lay out working examples for dummies - so that schoolchildren and housewives could take advantage. Ready or not, here I come.
Intrigue: I was looking for vulnerabilities in Yandex, Rambler, Mail.ru, Vkontakte, LJ and other popular resources. If you can’t wait to find out where and what vulnerabilities I have found, go directly to the “Vulnerability List” section.
Understanding the vulnerabilities required will require at least basic knowledge of what CSRF is. If they are not there - do not be discouraged, below I tried to explain this in an accessible way (though, in my opinion, it didn’t work out). If you already know what it is, or vice versa, are not going to figure it out, feel free to proceed to the results of my superficial audit.
For starters, it makes sense to read Wikipedia . If you read laziness in English (there is almost nothing on the topic in Russian on Wikipedia, the topic is extremely poorly covered in Habré), but you want to learn something, here’s a shortThe contents of previous episodes describe this vulnerability.
UPD: main development Liveinternet.ru does not believe in the existence of CSRF. I reveal his vulnerabilities before the promised week. Here is a usage example. Be careful if you have an account with LiRu.
UPD 2: The vulnerability has been demonstrated; the example has been removed so far.
UPD 3: The week has passed. Spread working / working examples. Time is short, so I’m not checking yet what works and what doesn’t. I would be grateful if you write about this in the comments. All questions, wishes, suggestions - in the answers to this comment .
Rambler , Mail.Ru , Liveinternet , Yandex
To perform any actions with the Web application, users send HTTP requests. In order to determine on behalf of which user the action is performed, sessions are usually used, data about which is stored in Cookies. The server receives the request, looks at the Cookie, makes sure that the session associated with the cookie data exists and performs the action on behalf of the user associated with this session. In order for the user to remain logged in to their favorite resource, browsers automatically send cookies to the server that installed them. Thus, if a request is sent from the user's browser, then Cookies will be sent along with it. And the server will think that it is dealing with a logged in user of the resource and will perform actions on his behalf. And you can force the browser to send a request from a third-party page.
A bit confusing, of course, it turned out, so a simple example. From the whole explanation it is possible to read only him.
To delete your profile from the popular social network, Vasya needs to click on the “Delete profile” link, which leads to the page http://vulnerable.site/delete_profile.php?sure=yes. Petya places a picture on his page that should be uploaded to this address (it’s clear that there is no picture at this address, but the browser does not know this in advance). When Vasya visits Petya’s page, Vasya’s browser tries to download this picture. He does not find pictures and calms down. But the popular social network received a command to delete the profile on behalf of Vasya. And Vasya’s profile was safely deleted. Perhaps you still do not understand - exchange Vasya and Petya for Alice and Bob and read again. From these Vasya and Petya there is always sheer confusion.
So, for use, you will have to lure the user to a page that you personally created (or to a page with XSS on which your code is posted through XSS - but there is no difference for this article). There should be something on this page that will send the request. The easiest way is to post a picture:
You can hack a popular blog and post a hidden iframe there - the result will be amazing.
For some reason, many developers are sure that it is impossible to exploit the CSRF vulnerability requiring sending a POST request. Usually they motivate this by the fact that through JS it is not possible to send a POST request to another domain. This is true (at least under normal conditions). But for some reason, they always forget about theroot of world evil iframe tag. Firstly, it may be hidden (display: none) and still boot. Secondly, you can download it from anywhere (including from your server). And thirdly, it may contain a form with method = “POST” and action = “http://vulnerable.site/delete_profile.php”, and submit on this form can be called. To demonstrate the vulnerabilities listed below, I used just such a method.
Here I have to upset you. The only way to protect yourself is not to use the Internet. Or at least that part of it in which you need to log in somewhere (social networks, twitter, e-mail, forums, etc.). No, you can of course never leave open sessions and always press the exit button immediately after using the resource - but this still will not save you, because while you are logged in - you are vulnerable. Ordinary users can only rely on the professionalism of the developers and the fact that they took care of their users. And there is little hope.
UPD: For FF there is addon - RequestPolicy , thanks Vanav
It is to take care of your users - using the CSRF server does not disable and SSH does not give access. Just some actions on behalf of the user are performed. Well, the user himself could execute them. Therefore, some developers do not consider this a vulnerability. And I consider this attitude to be blatant unprofessionalism and spit on their own users. Get out of the profession. Moreover, the vulnerability is far from new.
I’ll probably not dwell on the protection methods in detail - I’ll just list the methods and give small comments - because if you are a developer, then you yourselfcan already understand this.
I must say right away that I took the methods from the English Wikipedia and, in my personal opinion, many of them are no protection.
Basically, finding CSRF is a very simple task. We just create an account on the resource of interest to us, turn on the Firebug / Chrome Developer Tools and do everything that an ordinary user does - set up a mailbox, read, write, delete letters, write to blogs, etc. At the same time, do not forget to look at the requests sent. If the request does not contain incomprehensibly how the generated data (various one-time tokens) is a potential vulnerability. We repeat this request from the local page and look at the result. If an action has occurred, a vulnerability has been discovered. We write a page with a form, upload it to our server and load this page in a hidden iframe from some other page of ours - just to demonstrate the work (or for industrial use). You can still show some of your friends and check them.
It was not possible to track some requests either through Firebug or through Chrome Developer Tools - first an AJAX request is sent, and after receiving a response to it using JS, the next page opens. In this case, the request we are interested in is visible only for a few seconds. But no one can hide from Wireshark.
UPD: Smart people in the comments suggest that there is a Do Not Clean button in FireBug and Preserve Log upon Navigation in Chrome Developer Tools.
When searching for vulnerabilities, one should not forget about additional services (like Yandex calendars) and mobile versions.
I did not set myself the task of finding all the CSRF visibility on a particular portal. No more than 2 hours were allocated for each resource. I checked only Russian portals - Google.ru, Facebook.com and the like remained aloof. In some portals for the allotted time, I did not find anything, but I added it to the list in order to leave a general review about their protection method. Some portals from the list, I do not consider the largest in Runet, but thinks the rating that I used.
There is no protection against CSRF at all. You can do anything you like - send private messages, post to blogs, write comments, reconfigure your account, in general, anything the resource allows. Therefore, I did not compile a list of vulnerabilities. This resource was the last I reached, and I do not consider it one of the largest. After him, my hands dropped - everything became clear already.
CSRF protection according to method No. 1 - a one-time token. It would seem that there can be no CSRF. But, firstly, this protection is not everywhere. And, secondly, the token is not checked - you can send any token (and even an empty one) and anyway you need to perform the action. As an additional protection in one of the forms I saw a hidden field “referer” with the address of the current page. I even cried a little.
It seems that the developers of Rambler were one day told that there is such a CSRF vulnerability and that to protect against it, you need to send a unique token with each request. But they forgot to say that it also needs to be checked.
What can be done
In general, a huge scope for spam and fraud with mail. I didn’t even think about potential use cases - it’s easier to say what cannot be done without the user's knowledge.
This is not the whole list, because there is no protection (or rather it is, but it does not work, which is equivalent).
In the mail protection from CSRF according to method No. 2 - password entry. Those. This is initially not CSRF protection, but where password entry is required, CSRF does not work either. Other services have normal protection.
So, what are the obsessions found in the most popular postal service of the CIS
Protection against CSRF is. But since Yandex is not only search or mail, but protection is different everywhere. And somewhere, something is missing. Yandex within 3 days answered my letter and promised to verify the information. And they are the only ones who fixed at least one vulnerability.
What can (be) done
Not the most serious vulnerabilities. Most likely the reason for their appearance is that Yandex is a large number of services, each with its own development team and everywhere the protection is organized in different ways. And somewhere just overlooked.
Of course, I could not ignore these resources. But I did not find vulnerabilities, although this does not mean that they are not there. In any case, it’s worth telling how they have protection against CSRF.
Tokens for any user actions. It seems to be added automatically, so they are not forgotten. Exactly the same protection in the mobile version. One service, one development team, there are no such problems as, for example, Yandex. Only one thing confuses me - the token for a specific action is always the same for a particular user. Those. this is a certain mixture of protection methods No. 1 and No. 2 - tokens are not disposable, but known only to the user. You can consider them a password to perform an action - each action has its own password. I don’t like something in such an organization, but I still don’t understand what exactly.
Protection according to method No. 1 - one-time tokens. In the mobile version, protection is a little easier, but still there. Here is someone to look at as an example. It is true to note that the service is not very Russian. So he is out of competition.
I really wanted to check them out. But for this you need to be able to use them. And I have a nervous tick from their design. So it did not work out. I’ll try to fix this one night with the images disabled.
In general, the picture is completely joyless. If such monsters make such mistakes in their projects, then all other developers should check their resources again. Yandex takes the first place in the speed of closing vulnerabilities at a speed of 1 vulnerability in a month and a half. The remaining resources occupy an honorable second place.
At first I planned to write about CSRF vulnerabilities that I found in one of the largest Runet portals. But it turned out that not only this portal, but most of the largest resources are exposed to these vulnerabilities. I reported the problems to the respective companies a month and a half ago. Now I again had time and I looked at what was already closed. It turned out that in a month and a half only 1 vulnerability was closed.
Because the vulnerabilities are still working, I will write only where I found them and how they can be used. In a week I promise to lay out working examples for dummies - so that schoolchildren and housewives could take advantage. Ready or not, here I come.
Intrigue: I was looking for vulnerabilities in Yandex, Rambler, Mail.ru, Vkontakte, LJ and other popular resources. If you can’t wait to find out where and what vulnerabilities I have found, go directly to the “Vulnerability List” section.
Understanding the vulnerabilities required will require at least basic knowledge of what CSRF is. If they are not there - do not be discouraged, below I tried to explain this in an accessible way (though, in my opinion, it didn’t work out). If you already know what it is, or vice versa, are not going to figure it out, feel free to proceed to the results of my superficial audit.
For starters, it makes sense to read Wikipedia . If you read laziness in English (there is almost nothing on the topic in Russian on Wikipedia, the topic is extremely poorly covered in Habré), but you want to learn something, here’s a short
UPD 2: The vulnerability has been demonstrated; the example has been removed so far.
UPD 3: The week has passed. Spread working / working examples. Time is short, so I’m not checking yet what works and what doesn’t. I would be grateful if you write about this in the comments. All questions, wishes, suggestions - in the answers to this comment .
Rambler , Mail.Ru , Liveinternet , Yandex
What is CSRF?
To perform any actions with the Web application, users send HTTP requests. In order to determine on behalf of which user the action is performed, sessions are usually used, data about which is stored in Cookies. The server receives the request, looks at the Cookie, makes sure that the session associated with the cookie data exists and performs the action on behalf of the user associated with this session. In order for the user to remain logged in to their favorite resource, browsers automatically send cookies to the server that installed them. Thus, if a request is sent from the user's browser, then Cookies will be sent along with it. And the server will think that it is dealing with a logged in user of the resource and will perform actions on his behalf. And you can force the browser to send a request from a third-party page.
How to use?
A bit confusing, of course, it turned out, so a simple example. From the whole explanation it is possible to read only him.
To delete your profile from the popular social network, Vasya needs to click on the “Delete profile” link, which leads to the page http://vulnerable.site/delete_profile.php?sure=yes. Petya places a picture on his page that should be uploaded to this address (it’s clear that there is no picture at this address, but the browser does not know this in advance). When Vasya visits Petya’s page, Vasya’s browser tries to download this picture. He does not find pictures and calms down. But the popular social network received a command to delete the profile on behalf of Vasya. And Vasya’s profile was safely deleted. Perhaps you still do not understand - exchange Vasya and Petya for Alice and Bob and read again. From these Vasya and Petya there is always sheer confusion.
So, for use, you will have to lure the user to a page that you personally created (or to a page with XSS on which your code is posted through XSS - but there is no difference for this article). There should be something on this page that will send the request. The easiest way is to post a picture:

You can hack a popular blog and post a hidden iframe there - the result will be amazing.
And in my application, all actions are performed through POST requests
For some reason, many developers are sure that it is impossible to exploit the CSRF vulnerability requiring sending a POST request. Usually they motivate this by the fact that through JS it is not possible to send a POST request to another domain. This is true (at least under normal conditions). But for some reason, they always forget about the
I am a user - how do I protect myself?
Here I have to upset you. The only way to protect yourself is not to use the Internet. Or at least that part of it in which you need to log in somewhere (social networks, twitter, e-mail, forums, etc.). No, you can of course never leave open sessions and always press the exit button immediately after using the resource - but this still will not save you, because while you are logged in - you are vulnerable. Ordinary users can only rely on the professionalism of the developers and the fact that they took care of their users. And there is little hope.
UPD: For FF there is addon - RequestPolicy , thanks Vanav
I am a developer - how do I take care of my users?
It is to take care of your users - using the CSRF server does not disable and SSH does not give access. Just some actions on behalf of the user are performed. Well, the user himself could execute them. Therefore, some developers do not consider this a vulnerability. And I consider this attitude to be blatant unprofessionalism and spit on their own users. Get out of the profession. Moreover, the vulnerability is far from new.
I’ll probably not dwell on the protection methods in detail - I’ll just list the methods and give small comments - because if you are a developer, then you yourself
I must say right away that I took the methods from the English Wikipedia and, in my personal opinion, many of them are no protection.
- A one-time token for each action is the most reliable way, I personally choose it
- In each request, requiring a username and password is also reliable, but if you do not use HTTPS, you can steal the password from any request using a sniffer
- Limiting the lifetime of a session - does not protect against anything, it simply reduces the time during which a vulnerability can be exploited
- Checking the Referer header is not bad, but this header is not always set, the first method is still preferable
- Make sure that clientaccesspolicy.xml and crossdomain.xml (for Silverlight and Flash, respectively) do not allow requests from unverified sources - this is how to first remove the lock from the door and allow anyone to walk, and then hang it back for protection
- Check for X-Requested-With - will help for AJAX requests and even then not always
Practice
Basically, finding CSRF is a very simple task. We just create an account on the resource of interest to us, turn on the Firebug / Chrome Developer Tools and do everything that an ordinary user does - set up a mailbox, read, write, delete letters, write to blogs, etc. At the same time, do not forget to look at the requests sent. If the request does not contain incomprehensibly how the generated data (various one-time tokens) is a potential vulnerability. We repeat this request from the local page and look at the result. If an action has occurred, a vulnerability has been discovered. We write a page with a form, upload it to our server and load this page in a hidden iframe from some other page of ours - just to demonstrate the work (or for industrial use). You can still show some of your friends and check them.
It was not possible to track some requests either through Firebug or through Chrome Developer Tools - first an AJAX request is sent, and after receiving a response to it using JS, the next page opens. In this case, the request we are interested in is visible only for a few seconds. But no one can hide from Wireshark.
UPD: Smart people in the comments suggest that there is a Do Not Clean button in FireBug and Preserve Log upon Navigation in Chrome Developer Tools.
When searching for vulnerabilities, one should not forget about additional services (like Yandex calendars) and mobile versions.
List of vulnerabilities
I did not set myself the task of finding all the CSRF visibility on a particular portal. No more than 2 hours were allocated for each resource. I checked only Russian portals - Google.ru, Facebook.com and the like remained aloof. In some portals for the allotted time, I did not find anything, but I added it to the list in order to leave a general review about their protection method. Some portals from the list, I do not consider the largest in Runet, but thinks the rating that I used.
Liveinternet.ru
There is no protection against CSRF at all. You can do anything you like - send private messages, post to blogs, write comments, reconfigure your account, in general, anything the resource allows. Therefore, I did not compile a list of vulnerabilities. This resource was the last I reached, and I do not consider it one of the largest. After him, my hands dropped - everything became clear already.
Rambler.ru
CSRF protection according to method No. 1 - a one-time token. It would seem that there can be no CSRF. But, firstly, this protection is not everywhere. And, secondly, the token is not checked - you can send any token (and even an empty one) and anyway you need to perform the action. As an additional protection in one of the forms I saw a hidden field “referer” with the address of the current page. I even cried a little.
It seems that the developers of Rambler were one day told that there is such a CSRF vulnerability and that to protect against it, you need to send a unique token with each request. But they forgot to say that it also needs to be checked.
What can be done
- In Rambler. Friends (who uses them at all?), You can create a group of friends with an arbitrary name, add or remove an arbitrary friend, change the notification settings for friend actions / adding to friends
- In the account settings, you can add or remove a user from the black list, change the signature, change the location, change the list of your interests, enable / disable the display of your friends list and your name
- In the mail you can send an arbitrary letter on behalf of the user, enable unconditional forwarding to any e-mail (without saving), change the mail settings (it is especially valuable to enable the display of images from third-party servers), delete all letters from the folder (in fact, they will be moved to the trash ) and empty the basket
- Also in the mail you can delete the letter, mark the letter as read and forward the letter to an arbitrary mailbox. True, for this you need to know the id of the letter and the name of the folder in which it is stored. 2 folders are known - “Inbox” and “Sent”. letter id - letter number in the current folder, so no one canceled bruteforce
In general, a huge scope for spam and fraud with mail. I didn’t even think about potential use cases - it’s easier to say what cannot be done without the user's knowledge.
This is not the whole list, because there is no protection (or rather it is, but it does not work, which is equivalent).
Mail.ru
In the mail protection from CSRF according to method No. 2 - password entry. Those. This is initially not CSRF protection, but where password entry is required, CSRF does not work either. Other services have normal protection.
So, what are the obsessions found in the most popular postal service of the CIS
- Sending letters on behalf of the user with any text and subject to any mailbox. A letter with a unique code can be sent to the attacker's mailbox and then he will recognize the email address of the visitor. This email through AJAX will get to the page on which the user is already located - this is useful for exploiting vulnerabilities No. 2, No. 7
- Sending a copy of the letter to any address (the letter is not saved in the sent ones, the user cannot find out about this in any way). To exploit this vulnerability, it was necessary to know the message id - 20 digits, of which the first 10 are timestamp, and the second 10 are the message number among the servers processed by this second (this is just my personal assumption of course). According to my observations, this number does not exceed 1000. You can ask the server to send 1000 letters at once and then it will send those of them that the user really has in the mailbox, although the interface pro.mail.ru (namely, this vulnerability is located there) says that it is impossible to forward more than 3 letters at the same time. You can use brute force - send letters received in 10 seconds, requesting forwarding each time in 1000 pieces. In order to forward messages in a day, you need 2.5 GB of outgoing traffic, but this is not necessary to steal a letter with a password - a password recovery on a third-party resource is started on the user's mailbox (it can already be known from No. 1) and the time of arrival of the letter is already approximately known. Can be used with vulnerability 3
- Delete a message - again by id. Again brute force. We start password recovery, steal an email with a password and delete it
- Connecting and disconnecting SMS notifications - everything is simple here. Some mailbox settings can be changed without entering a password. You can turn off notifications, or you can turn them on to your phone, tied in paragraph 7
- Disable saving sent emails and enable Web mail agent on mail pages - these checkboxes are on the same page in the settings and just like the previous vulnerability did not require a password to change state. Disable saving sent is understandable why. And it makes sense to enable the Web mail agent if it also has CSRF
- Turn off notifications about the approach of the mailbox size limit - the essence is the same as in the previous 2. We turn off notifications and fill up the box with large letters
- Bind / delete a phone number - with this, everything is a little more interesting. For all actions, a user email is required (or rather username and domain), which can be obtained from point 1. It is also required to specify a phone number, so deleting a user’s own phone number will not work (at least if you do not know it in advance - for example, it is displayed to authorized contacts in the mail agent - and how to log in is another question). To bind your phone number you need to send a request. After that, an SMS with a code will come to the phone. At this stage, you will need software that will get the code from SMS and report it on an AJAX request. JS on the page, having received this code, will create another iframe that will confirm the binding of the phone number. You can delete this phone number in the same way. There really is one feature - if the phone number is the only one, then it will be deleted only after 15 days, and not immediately. You can delete it right away only by knowing the code from SMS (it is the same as for binding)
Yandex
Protection against CSRF is. But since Yandex is not only search or mail, but protection is different everywhere. And somewhere, something is missing. Yandex within 3 days answered my letter and promised to verify the information. And they are the only ones who fixed at least one vulnerability.
What can (be) done
- It was possible to reconfigure the search - to enable the saving of search queries and results in the “Finds” service, to change the filtering level of the search (for example, to prohibit a colleague from searching for pornography - just like that, out of harm). This invisibility is currently closed.
- You can change the location of the user - and he will be shown search results, ads and traffic jams in Kherson instead of St. Petersburg. And you can change the location of all visitors to some not very popular and drive advertisements from Direct at prices much lower than Moscow
- You can create a ToDo-list with an arbitrary name in the user's calendar and add arbitrary cases to it. To add cases, you need to know the list id, but you can first create a list at home, then at the user, and then at home again and iterate over the id between your two lists (and, given the number of lists created, most likely you won’t even have to sort out) . Vulnerability in the mobile version of Yandex.Calendar
- You can remove the phone from Yandex.Passport. You need to know its id, but knowing the approximate date of addition, you can pick it up and brute force
- In Yandex.Market, you can add an arbitrary product to the comparison list. Or remove it from there.
- In Yandex.Market, you can subscribe a user to a notification about a price reduction for a specific product below a certain level. Or unsubscribe a user from notifications. For example, an unscrupulous online store bought a batch of gray iPhones and is planning an action to sell them. Before the action, he arranges some kind of PR-campaign and signs all visitors on a notice about the price reduction below 8000 rubles. And then iPhone is exported to Yandex.Market at a price of 7999 rubles, and all users receive spam from Yandex with an offer to buy this iPhone
- Global logout. You can end all user sessions on all computers. It can be used as a pet dirty trick. Competitors can place an iframe on their sites that will end all Yandex sessions, users will be annoyed. In general, the only site on which there is no such problem is Vkontakte. There you can’t even get out of the account with the wrong token. I'm not sure if this can be considered a vulnerability at all, but it seems that Vkontakte considers
Not the most serious vulnerabilities. Most likely the reason for their appearance is that Yandex is a large number of services, each with its own development team and everywhere the protection is organized in different ways. And somewhere just overlooked.
But what about Vkontakte and LJ?
Of course, I could not ignore these resources. But I did not find vulnerabilities, although this does not mean that they are not there. In any case, it’s worth telling how they have protection against CSRF.
In contact with
Tokens for any user actions. It seems to be added automatically, so they are not forgotten. Exactly the same protection in the mobile version. One service, one development team, there are no such problems as, for example, Yandex. Only one thing confuses me - the token for a specific action is always the same for a particular user. Those. this is a certain mixture of protection methods No. 1 and No. 2 - tokens are not disposable, but known only to the user. You can consider them a password to perform an action - each action has its own password. I don’t like something in such an organization, but I still don’t understand what exactly.
LJ
Protection according to method No. 1 - one-time tokens. In the mobile version, protection is a little easier, but still there. Here is someone to look at as an example. It is true to note that the service is not very Russian. So he is out of competition.
Classmates
I really wanted to check them out. But for this you need to be able to use them. And I have a nervous tick from their design. So it did not work out. I’ll try to fix this one night with the images disabled.
Conclusion
In general, the picture is completely joyless. If such monsters make such mistakes in their projects, then all other developers should check their resources again. Yandex takes the first place in the speed of closing vulnerabilities at a speed of 1 vulnerability in a month and a half. The remaining resources occupy an honorable second place.