Referer spoofing and defeating the XSS filter (Edge/IE)

According to Wikipedia, “Referer spoofing is the sending of incorrect referer information in an HTTP request in order to prevent a website from obtaining accurate data on the identity of the web page previously visited by the user.

In other words, making a server think that requests are coming from anywhere we want.

MSRC Notification

The original PoC sent to MSRC was using iframes, but their rejection made me come back to find something easier. Either way, the referer-spoof works essentially as in the original proof of concept.

Date: Jul 14, 8:47AM (GMT-3)

From: Manuel Caballero
To: secure@microsoft.com
Attachments: IE_EDGE_xss_filter_bypass.zip

Hey fellas! Attached you have a working PoC with an XSS-Filter bypass […]

1) Inject an iFrame on the vulnerable URL.
2) Load the vulnerable inside the iFrame but this time, with the script you want to execute.

Now, this happens because IE/Edge disable the filter when the requests come from the same-domain referrer […]

It’s easy to load inside the iFrame the vulnerable URL because IE/Edge has many problems regarding referrers.

It’s quite easy (check the PoC) to emulate essentially, any referrer we want. […]

 

Date: Jul 14, 5:29PM (GMT-3)
From: secure@microsoft.com
To: Manuel Caballero

Hello, Thank you for contacting the Microsoft Security Response Center (MSRC)[…] but filter bypasses themselves are not considered to be vulnerabilities.

Regards,
[…]

MSRC

Referer

The referer is an HTTP header that allows a site to identify where the request is coming from. For example, if we search for “MS Edge” in Google and click on the first organic link, the browser will navigate to microsoft.com sending google.com as the referer. Microsoft will know that we are coming from Google because the referer is sent by the browser when doing the request.

Referer Click

The referer is not only sent when clicking on a link but also on every resource that is requested. If we load a webpage (say, magicmac.com) that renders two images and an iframe, all those requests will carry the referer in the http header. The requests will look like this:

  1. Main page (magicmac.com) with an empty referer. The browser leaves it blank when we directly type the URL into the address bar.
  2. Two images. Both with magicmac.com as the referer.
  3. One iframe also with magicmac.com as the referer.

Let’s watch that closely while capturing traffic using Fiddler Web Debugger. A simple html with two images side by side and an iframe below them.

Requests

Now check out the Fiddler log below with the request numbers matching the ones of the images/iframe above. In the first row we have the request number, then Host/URLs and in the last one, referers. To make this clearer I deleted a few lines (requests 1, 6 and 7) from the Fiddler log,  as those were unrelated to our task.

Look below how request #2 has an empty referer because its the URL that we typed in the address bar, with no referer at all.  Then come requests #3 and #4  where both have magicmac.com as the referer. Finally request #5 also with magicmac.com

Fiddler Referer

But what happens after that? Why is that all requests starting from #8 have bing.com as the referer? It’s because those images/scripts are being requested by bing.com and not magicmac, even if the top URL is magicmac. Keep in mind that the referer is always the Host/URL that generates the request. Bing.com is inside an iframe and all requests that is doing are coming from bing.com, not magicmac. Who is requesting those scripts and images? Bing.com

If this explanation is unclear I suggest you read this Wikipedia article which is better written and more detailed.

 

Basic uses of the http referer on the web

  • A server wants to prevent other sites requesting images from itself. This is called Hotlinking.
  • A website wants to serve premium content only to a specific HTTP referer. This happens a lot with videos/tutorials served from Vimeo. They are accessible only when the browser referer comes from a particular host. In other words, if you know the “secret” host and how to change your referer, you can get all that content for free.
  • Browsers disable the XSS Filter leaving the site naked against XSS or CSRF attacks. What? Oh yes. IE/Edge allow a site to “auto-xss” itself. In other words, those browsers will literally disable the XSS filter if the referer of the request comes from the same domain. No worries if unclear, we will see this in a bit.

 

Creating vulnerable samples

Let’s create a couple of php scripts: one with a referer check to serve “premium content” and another vulnerable to XSS attacks.

The script below is serves premium content only to requests coming from www.nature.com, otherwise it says you are not authorized.

// http://www.cracking.com.ar/demos/referer/refcheck.php

$ref = $_SERVER['HTTP_REFERER'];
$refData = parse_url($ref);
$host = $refData['host'];

if($host == 'www.nature.com')
{
  echo "This is your premium content because you are coming from: " . $host;
}
else
{
  echo "You are not authorized to view this page";
}

[ Try it Live! ]

The page returned a “not authorized” message because the referer is brokenbrowser, not nature. But no worries, we will bypass this soon. Let’s see now a site that is vulnerable to XSS attacks.

// http://www.cracking.com.ar/demos/referer/xss.php
echo $_REQUEST['xss'];

// XSS me like this:
// http://www.cracking.com.ar/demos/referer/xss.php?xss=<script>alert(1)</script>

[ Try it Live! ]

 

IE XSS Filter in Action
IE XSS Filter in Action

The code injection failed thanks to the XSS filter. No hurries, we will bypass this in a second.

 

Referer spoof – How to do it

The problem that both Edge and IE have is quite simple: when changing the location of the top window using JavaScript, the referer will be the previous URL instead of the host that change it. Check below, easier reading the code than my English explanation:

win = window.open("http://www.nature.com");
win.location.href = "http://www.cracking.com.ar/demos/referer/refcheck.php";

[ Try it Live! ]

 

Fooled! Microsoft Edge (and IE) mistakenly passed nature.com as the referer when it was just the previous page. Remember: the referer should be the URL that initiated the request, not the previous page. In the example above, we opened a window on nature and immediately changed -via scripting- its location. The referer should have been the URL of the script that changed its location which in this case is also cracking.com.ar. Want to try it again? Let’s make whatsmyreferer.com think that we are coming from Paypal.

win = window.open("https://www.paypal.com");
win.location.href = "https://www.whatismyreferer.com";

[ Try it Live! ]

 

Referer Spofed

 

XSS Filter Bypass – How to do it

Bug hunter, I’m pretty confident of your awareness on the mechanics of the XSS filter of IE/Edge, but just in case, remember that it is literally disabled on pages where the referer host equals the host of the rendered page. So this will be pretty simple: we open any URL that belongs to the host of the vulnearable page, and then we change the location XSSing it straight! If we want to attack ebay.com then we will emulate-spoof ebay.com as the referer and then, XSS it. Let’s give it a try. Remember the vulnerable page above?

// http://www.cracking.com.ar/demos/referer/xss.php
echo $_REQUEST['xss'];

We tried to inject a script there but failed because the XSS filter blocked it. But let’s fool the referer and make this work!

win = window.open("http://www.cracking.com.ar");  // Referer Spoofer

// Successful code injection
win.location.href = "http://www.cracking.com.ar/demos/referer/xss.php?xss=<script>alert(1)</script>";

Try it on Edge/IE

 

Fellow bug hunter, I hope you will continue playing with this. The history and location objects have other bugs waiting to be found. Play with them and the vulnerabilities will come to you!

Have fun and ping me if you have questions!