The last time Hackerfall tried to access this page, it returned a not found error. A cached version of the page is below, or click here to continue anyway

Taking over Heroku accounts

This is the first time Im proud of a vulnerability I find.

Prior to publishing this blog post, the team at Heroku fixed the vulnerability on 5/26, and it is no longer exploitable.


Heroku has a feature called Buttons, which let you one-click provision, configure and deploy third party components, libraries and pattern apps. You can notice the button on Github like here: In this case, when you click on , you are redirected to

Anyone can create a Button:

I created a Button that only includes the required file app.json. Because app.json is the file from where Heroku gets the information about the Button.

I tried injecting HTML attributes and tags in app.json to achieve XSS, but the special characters are being escaped in the client side (if you can do it, report it!). However, I noticed that I can set the URL of the "logo" to any value. This URL is used as the src of an <img> created when is loaded.

When using <img>s the Referer header is sent with the URL that requested the image as the value, which allows the image to capture this URL in the server-side. I was only able to capture the Referer from a different domain using Firefox, Safari, Internet Explorer and Edge, but not using Chrome.

More ways to leak HTTP requests:


What I had until now was that when I load, <img src=";s=200" class=""> is created and the browser makes a request to with the header Referer: But I didnt have any critical parameter+value in the URL.

I played with OAuth and the applications owned by Heroku, with the intention to point the redirect_uri to where I could leak the Referer without success.

I dont remember when, but I noticed that a parameter code is added to[path_requested] after authentication. The value of this parameter is sent to an endpoint which doesnt have CSRF protection and returns a JSON response including an "access_token" with global scope. This global scope allows you to do anything with the account using the API! However I couldnt change the password or the email of the account, until [to be continued ]


Only worked if the user was already authenticated.

  1. Send user to

  2. User is redirected to

  3. User is redirected to

  4. And finally, the user is redirected to

  5. Once the page loads, a request is made to the Github API to get the file app.json

  6. The <img src=""> is created and the image is loaded, sending the code in the Referer

  7. My file poc.php captures the Referer, extracts the code and makes a POST request to

    with the value of the parameter password set to the value of code

  8. poc.php takes the "access_token" from the last response and makes a GET request to

    with the header Authorization: set to Bearer [the_access_token]

  9. poc.php takes the "email" from the last response and sends an email to the address

Art Attack

After reporting the vulnerability to Heroku, Patrik from Bugcrowd asked me to do whatever I could with his Heroku account. So, I started to look at what I could do and noticed that I couldnt change the email or password of his account.

I kept looking for ways to really take over his account, until I decided to try to use his access_token (that I had taken using the attack) as his password, and it worked! So, I changed his email.


To Heroku for allow me to write about this vulnerability. To Patrik for push me to do something really bad with the bug.

If something is not correct or well explained, let me know. Maybe is because of my ignorance, my poor English or because I missed something.

Continue reading on