7

Consider the following PHP script (it could be any other language; I chose PHP for simplicity):

<?php
echo $_SERVER['HTTP_REFERER'];
?>

Is it vulnerable to XSS?

Of course I can send a request to the script using curl and set referer to something like <script>alert(document.cookie)</script>. However, at least some browsers seem to encode referer, so if I for example redirect users to that script from the following URL:

http://example.com/<script>alert(document.cookie)</script>

the browser encodes referer and in result the PHP script outputs this:

http://example.com/%3Cscript%3Ealert(document.cookie)%3C/script%3E

Are there any browsers that doesn't encode referer? If not, can it be exploited in any other way?

1 Answers1

4

RFC

RFC 1945 - which first mentions the referer header - specifies that referers need to be URL encoded:

Referer = "Referer" ":" ( absoluteURI | relativeURI )

absoluteURI = scheme ":" ( uchar | reserved )
[...]
uchar = unreserved | escape
unreserved = ALPHA | DIGIT | safe | extra | national
escape = "%" HEX HEX
reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+"
extra = "!" | "
" | "'" | "(" | ")" | ","
safe = "$" | "-" | "_" | "."
unsafe = CTL | SP | <"> | "#" | "%" | "<" | ">"

The more up-to-date RFCs like 7231 are a bit more difficult to read as they cross-reference a lot, but it doesn't seem like they changed this rule.

So <, >, and " need to be URL encoded, according to the relevant RFCs. This was always the case, so even very old browsers should URL encode.

Note that ' does not need to be encoded - and is not encoded by modern browsers - and may thus be used for XSS attacks (eg <a href='[REFERER]'>go back</a>).

In Practice

Even though the RFCs specify that <, >, and " need to be URL encoded, it is still a good idea to encode the referer yourself just in case.

Browsers should follow RFCs - and major browser such as Chrome and Firefox do in this case - but it's a good idea to still follow best practices - ie encoding - on your side just in case some browsers don't, or in case the RFC changes in the future (although it's unlikely).

tim
  • 29,018
  • 7
  • 95
  • 119
  • 1
    @Gothdo Thanks, fixed the typo. And it's true, mostly double quotes are used. But there are cases where single quotes are used (mostly when a string is build via `"`, to avoid escaping quotes). There are also other more contrived examples where echoing would be unsafe, eg when quotes are completely omitted for attributes, or when the referer is echoed outside of quotes in a JavaScript context (but both of those are even more unlikely). – tim Jun 06 '16 at 21:46