Bug 67091 - XSS auditor bypass with http-equiv="refresh"
Summary: XSS auditor bypass with http-equiv="refresh"
Alias: None
Product: WebKit
Classification: Unclassified
Component: WebKit Misc. (show other bugs)
Version: 528+ (Nightly build)
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Nobody
Depends on:
Blocks: 66579
  Show dependency treegraph
Reported: 2011-08-27 13:30 PDT by Adam Barth
Modified: 2011-08-29 12:16 PDT (History)
3 users (show)

See Also:


Note You need to log in before you can comment on or make changes to this bug.
Description Adam Barth 2011-08-27 13:30:16 PDT

Reported by j.terh...@gmail.com, Today (4 hours ago)
A basic reflected XSS, using the <meta http-equiv="refresh" /> vector, is allowed by the XSS filter.

Chrome Version: 13.0.782.215 m + stable
Operating System: Windows NT 5.1 build 2600 (Windows XP Home Edition Service Pack 3) i586

Place the attached php file in a web accessible directory of a php enabled apache server at http://<host>/xss.php and call:

The alert is shown and no blocking message is posted to the console. However the call:

_is_ blocked and the usual blocking message ("Refused to execute a JavaScript script. Source code of script found within request.") is posted to the console. See screenshots refresh.jpg and basic.jpg.

If line 4 of the php script is changed to:
echo "<meta http-equiv='refresh' content='0; url=javascript:{$_GET['refresh']}' />";

the filter will also miss the reflected XSS if called as follows: 

Also if line 4 is changed to:
echo "<meta http-equiv='refresh' {$_GET['refresh']} />";

and called using:

the XSS is also allowed. _However_ if line 4 is changed to:
echo "<meta {$_GET['refresh']} />";

and the call:

is made, the filter WILL detect the XSS (see screenshot refresh2.jpg)

PHP Version: 5.3.5
Apache: Apache/2.2.17 (Win32) compiled with MSVC6

        if( isset($_GET['refresh']) ) {
                //echo "<meta http-equiv='refresh' content='0; url={$_GET['refresh']}' />";
                echo "<meta http-equiv='refresh' {$_GET['refresh']} />";
                //echo "<meta http-equiv='refresh' content='0; url=javascript:{$_GET['refresh']}' />";
        if( isset($_GET['body']) ) {
                echo $_GET['body'];
Comment 1 Thomas Sepez 2011-08-29 10:40:47 PDT
<meta> refresh to "javascript:" seems dubious.  Can we measure how often this occurs in the wild?  Might be best to just block it using a mechanism other than XSSAuditor.
Comment 2 Adam Barth 2011-08-29 12:15:20 PDT
Does meta-refresh to a JavaScript URL work in other browsers?  It seems there couple be a compat issue with just removing it.
Comment 3 Adam Barth 2011-08-29 12:16:57 PDT
Actually, this is working as intended.  The bypass is only occurring when the injection is in the context of the refresh itself, which isn't something we're trying to stop.