Commit a15fda81 authored by Tom Sepez's avatar Tom Sepez Committed by Commit Bot

Add unit tests for X-XSS-Protection header parser.

These add coverage and replace some of the existing layout tests with
a more efficient method of testing.

Tidy a comment in HTTPParsers.h while we're at it.

Change-Id: Idae90404bbd43de2e15a0442c16801079f38c4cc
Reviewed-on: https://chromium-review.googlesource.com/982750
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: default avatarMike West <mkwst@chromium.org>
Cr-Commit-Position: refs/heads/master@{#548345}
parent 95ed2935
CONSOLE ERROR: Error parsing header X-XSS-Protection: red: expected 0 or 1 at character position 0. The default protections will be applied.
CONSOLE ERROR: line 4: The XSS Auditor blocked access to 'http://127.0.0.1:8000/security/xssAuditor/resources/echo-intertag.pl?notifyDone=1&malformed-header=2&q=%3Cscript%3Ealert(String.fromCharCode(0x58,0x53,0x53))%3C/script%3E%3Cp%3EIf%20you%20see%20this%20message%20and%20no%20JavaScript%20alert()%20then%20the%20test%20PASSED.%3C/p%3E' because the source code of a script was found within the request. The auditor was enabled as the server did not send an 'X-XSS-Protection' header.
ALERT: URL mismatch: '[Location object access threw exception]' vs. 'http://127.0.0.1:8000/security/xssAuditor/resources/echo-intertag.pl?notifyDone=1&malformed-header=2&q=%3Cscript%3Ealert(String.fromCharCode(0x58,0x53,0x53))%3C/script%3E%3Cp%3EIf%20you%20see%20this%20message%20and%20no%20JavaScript%20alert()%20then%20the%20test%20PASSED.%3C/p%3E'
This tests that the X-XSS-Protection header is not ignored when the first character is not 0 or 1, and that we issue an error.
--------
Frame: 'frame'
--------
Could not load the requested resource.
Error code: -28 (net::ERR_BLOCKED_BY_XSS_AUDITOR)
<!DOCTYPE html>
<html>
<head>
<script src="http://localhost:8000/security/xssAuditor/resources/utilities.js"></script>
<script>
if (window.testRunner) {
testRunner.dumpAsText();
testRunner.dumpChildFramesAsText();
testRunner.waitUntilDone();
testRunner.setXSSAuditorEnabled(true);
}
</script>
</head>
<body>
<p>This tests that the X-XSS-Protection header is not ignored when the first character is not 0 or 1, and that we issue an error.</p>
<iframe id="frame" name="frame" onload="checkIfFrameLocationMatchesSrcAndCallDone('frame')" src="http://127.0.0.1:8000/security/xssAuditor/resources/echo-intertag.pl?notifyDone=1&malformed-header=2&q=<script>alert(String.fromCharCode(0x58,0x53,0x53))</script><p>If you see this message and no JavaScript alert() then the test PASSED.</p>">
</iframe>
</body>
</html>
CONSOLE ERROR: Error parsing header X-XSS-Protection: 1; mode=purple: invalid mode directive at character position 8. The default protections will be applied.
CONSOLE ERROR: line 4: The XSS Auditor blocked access to 'http://127.0.0.1:8000/security/xssAuditor/resources/echo-intertag.pl?notifyDone=1&malformed-header=3&q=%3Cscript%3Ealert(String.fromCharCode(0x58,0x53,0x53))%3C/script%3E%3Cp%3EIf%20you%20see%20this%20message%20and%20no%20JavaScript%20alert()%20then%20the%20test%20PASSED.%3C/p%3E' because the source code of a script was found within the request. The auditor was enabled as the server did not send an 'X-XSS-Protection' header.
ALERT: URL mismatch: '[Location object access threw exception]' vs. 'http://127.0.0.1:8000/security/xssAuditor/resources/echo-intertag.pl?notifyDone=1&malformed-header=3&q=%3Cscript%3Ealert(String.fromCharCode(0x58,0x53,0x53))%3C/script%3E%3Cp%3EIf%20you%20see%20this%20message%20and%20no%20JavaScript%20alert()%20then%20the%20test%20PASSED.%3C/p%3E'
This tests that a malformed X-XSS-Protection header is not ignored and an error is reported when the mode= token is invalid.
--------
Frame: 'frame'
--------
Could not load the requested resource.
Error code: -28 (net::ERR_BLOCKED_BY_XSS_AUDITOR)
<!DOCTYPE html>
<html>
<head>
<script src="http://localhost:8000/security/xssAuditor/resources/utilities.js"></script>
<script>
if (window.testRunner) {
testRunner.dumpAsText();
testRunner.dumpChildFramesAsText();
testRunner.waitUntilDone();
testRunner.setXSSAuditorEnabled(true);
}
</script>
</head>
<body>
<p>This tests that a malformed X-XSS-Protection header is not ignored and an error is reported when the mode= token is invalid.</p>
<iframe id="frame" name="frame" onload="checkIfFrameLocationMatchesSrcAndCallDone('frame')" src="http://127.0.0.1:8000/security/xssAuditor/resources/echo-intertag.pl?notifyDone=1&malformed-header=3&q=<script>alert(String.fromCharCode(0x58,0x53,0x53))</script><p>If you see this message and no JavaScript alert() then the test PASSED.</p>">
</iframe>
</body>
</html>
CONSOLE ERROR: Error parsing header X-XSS-Protection: 1; mode=block-a-block-block: expected semicolon at character position 14. The default protections will be applied.
CONSOLE ERROR: line 4: The XSS Auditor blocked access to 'http://127.0.0.1:8000/security/xssAuditor/resources/echo-intertag.pl?notifyDone=1&malformed-header=4&q=%3Cscript%3Ealert(String.fromCharCode(0x58,0x53,0x53))%3C/script%3E%3Cp%3EIf%20you%20see%20this%20message%20and%20no%20JavaScript%20alert()%20then%20the%20test%20PASSED.%3C/p%3E' because the source code of a script was found within the request. The auditor was enabled as the server did not send an 'X-XSS-Protection' header.
ALERT: URL mismatch: '[Location object access threw exception]' vs. 'http://127.0.0.1:8000/security/xssAuditor/resources/echo-intertag.pl?notifyDone=1&malformed-header=4&q=%3Cscript%3Ealert(String.fromCharCode(0x58,0x53,0x53))%3C/script%3E%3Cp%3EIf%20you%20see%20this%20message%20and%20no%20JavaScript%20alert()%20then%20the%20test%20PASSED.%3C/p%3E'
This tests that the X-XSS-Protection header is not ignored when there is a trailing garbage after mode=block, and we issue an error
--------
Frame: 'frame'
--------
Could not load the requested resource.
Error code: -28 (net::ERR_BLOCKED_BY_XSS_AUDITOR)
<!DOCTYPE html>
<html>
<head>
<script src="http://localhost:8000/security/xssAuditor/resources/utilities.js"></script>
<script>
if (window.testRunner) {
testRunner.dumpAsText();
testRunner.dumpChildFramesAsText();
testRunner.waitUntilDone();
testRunner.setXSSAuditorEnabled(true);
}
</script>
</head>
<body>
<p>This tests that the X-XSS-Protection header is not ignored when there is a trailing garbage after mode=block, and we issue an error</p>
<iframe id="frame" name="frame" onload="checkIfFrameLocationMatchesSrcAndCallDone('frame')" src="http://127.0.0.1:8000/security/xssAuditor/resources/echo-intertag.pl?notifyDone=1&malformed-header=4&q=<script>alert(String.fromCharCode(0x58,0x53,0x53))</script><p>If you see this message and no JavaScript alert() then the test PASSED.</p>">
</iframe>
</body>
</html>
CONSOLE ERROR: Error parsing header X-XSS-Protection: 1; mode=block; report: expected equals sign at character position 21. The default protections will be applied.
CONSOLE ERROR: line 4: The XSS Auditor blocked access to 'http://127.0.0.1:8000/security/xssAuditor/resources/echo-intertag.pl?notifyDone=1&malformed-header=5&q=%3Cscript%3Ealert(String.fromCharCode(0x58,0x53,0x53))%3C/script%3E%3Cp%3EIf%20you%20see%20this%20message%20and%20no%20JavaScript%20alert()%20then%20the%20test%20PASSED.%3C/p%3E' because the source code of a script was found within the request. The auditor was enabled as the server did not send an 'X-XSS-Protection' header.
ALERT: URL mismatch: '[Location object access threw exception]' vs. 'http://127.0.0.1:8000/security/xssAuditor/resources/echo-intertag.pl?notifyDone=1&malformed-header=5&q=%3Cscript%3Ealert(String.fromCharCode(0x58,0x53,0x53))%3C/script%3E%3Cp%3EIf%20you%20see%20this%20message%20and%20no%20JavaScript%20alert()%20then%20the%20test%20PASSED.%3C/p%3E'
This tests that the X-XSS-Protection header is not ignored when there is an incomplete report url following mode=block, and we issue an error
--------
Frame: 'frame'
--------
Could not load the requested resource.
Error code: -28 (net::ERR_BLOCKED_BY_XSS_AUDITOR)
<!DOCTYPE html>
<html>
<head>
<script src="http://localhost:8000/security/xssAuditor/resources/utilities.js"></script>
<script>
if (window.testRunner) {
testRunner.dumpAsText();
testRunner.dumpChildFramesAsText();
testRunner.waitUntilDone();
testRunner.setXSSAuditorEnabled(true);
}
</script>
</head>
<body>
<p>This tests that the X-XSS-Protection header is not ignored when there is an incomplete report url following mode=block, and we issue an error</p>
<iframe id="frame" name="frame" onload="checkIfFrameLocationMatchesSrcAndCallDone('frame')" src="http://127.0.0.1:8000/security/xssAuditor/resources/echo-intertag.pl?notifyDone=1&malformed-header=5&q=<script>alert(String.fromCharCode(0x58,0x53,0x53))</script><p>If you see this message and no JavaScript alert() then the test PASSED.</p>">
</iframe>
</body>
</html>
CONSOLE ERROR: Error parsing header X-XSS-Protection: 1; report= ;: invalid report directive at character position 11. The default protections will be applied.
CONSOLE ERROR: line 4: The XSS Auditor blocked access to 'http://127.0.0.1:8000/security/xssAuditor/resources/echo-intertag.pl?notifyDone=1&malformed-header=6&q=%3Cscript%3Ealert(String.fromCharCode(0x58,0x53,0x53))%3C/script%3E%3Cp%3EIf%20you%20see%20this%20message%20and%20no%20JavaScript%20alert()%20then%20the%20test%20PASSED.%3C/p%3E' because the source code of a script was found within the request. The auditor was enabled as the server did not send an 'X-XSS-Protection' header.
ALERT: URL mismatch: '[Location object access threw exception]' vs. 'http://127.0.0.1:8000/security/xssAuditor/resources/echo-intertag.pl?notifyDone=1&malformed-header=6&q=%3Cscript%3Ealert(String.fromCharCode(0x58,0x53,0x53))%3C/script%3E%3Cp%3EIf%20you%20see%20this%20message%20and%20no%20JavaScript%20alert()%20then%20the%20test%20PASSED.%3C/p%3E'
This tests that the X-XSS-Protection header is not ignored when there is an incomplete report directive, and we issue an error
--------
Frame: 'frame'
--------
Could not load the requested resource.
Error code: -28 (net::ERR_BLOCKED_BY_XSS_AUDITOR)
<!DOCTYPE html>
<html>
<head>
<script src="http://localhost:8000/security/xssAuditor/resources/utilities.js"></script>
<script>
if (window.testRunner) {
testRunner.dumpAsText();
testRunner.dumpChildFramesAsText();
testRunner.waitUntilDone();
testRunner.setXSSAuditorEnabled(true);
}
</script>
</head>
<body>
<p>This tests that the X-XSS-Protection header is not ignored when there is an incomplete report directive, and we issue an error</p>
<iframe id="frame" name="frame" onload="checkIfFrameLocationMatchesSrcAndCallDone('frame')" src="http://127.0.0.1:8000/security/xssAuditor/resources/echo-intertag.pl?notifyDone=1&malformed-header=6&q=<script>alert(String.fromCharCode(0x58,0x53,0x53))</script><p>If you see this message and no JavaScript alert() then the test PASSED.</p>">
</iframe>
</body>
</html>
CONSOLE ERROR: Error parsing header X-XSS-Protection: 1; red: unrecognized directive at character position 3. The default protections will be applied.
CONSOLE ERROR: line 4: The XSS Auditor blocked access to 'http://127.0.0.1:8000/security/xssAuditor/resources/echo-intertag.pl?notifyDone=1&malformed-header=7&q=%3Cscript%3Ealert(String.fromCharCode(0x58,0x53,0x53))%3C/script%3E%3Cp%3EIf%20you%20see%20this%20message%20and%20no%20JavaScript%20alert()%20then%20the%20test%20PASSED.%3C/p%3E' because the source code of a script was found within the request. The auditor was enabled as the server did not send an 'X-XSS-Protection' header.
ALERT: URL mismatch: '[Location object access threw exception]' vs. 'http://127.0.0.1:8000/security/xssAuditor/resources/echo-intertag.pl?notifyDone=1&malformed-header=7&q=%3Cscript%3Ealert(String.fromCharCode(0x58,0x53,0x53))%3C/script%3E%3Cp%3EIf%20you%20see%20this%20message%20and%20no%20JavaScript%20alert()%20then%20the%20test%20PASSED.%3C/p%3E'
This tests that the X-XSS-Protection header is not ignored when there is an invalid directive, and we issue an error
--------
Frame: 'frame'
--------
Could not load the requested resource.
Error code: -28 (net::ERR_BLOCKED_BY_XSS_AUDITOR)
<!DOCTYPE html>
<html>
<head>
<script src="http://localhost:8000/security/xssAuditor/resources/utilities.js"></script>
<script>
if (window.testRunner) {
testRunner.dumpAsText();
testRunner.dumpChildFramesAsText();
testRunner.waitUntilDone();
testRunner.setXSSAuditorEnabled(true);
}
</script>
</head>
<body>
<p>This tests that the X-XSS-Protection header is not ignored when there is an invalid directive, and we issue an error</p>
<iframe id="frame" name="frame" onload="checkIfFrameLocationMatchesSrcAndCallDone('frame')" src="http://127.0.0.1:8000/security/xssAuditor/resources/echo-intertag.pl?notifyDone=1&malformed-header=7&q=<script>alert(String.fromCharCode(0x58,0x53,0x53))</script><p>If you see this message and no JavaScript alert() then the test PASSED.</p>">
</iframe>
</body>
</html>
CONSOLE ERROR: Error parsing header X-XSS-Protection: 1; mode=block; report=/fail; mode=block;: duplicate mode directive at character position 33. The default protections will be applied.
CONSOLE ERROR: line 4: The XSS Auditor blocked access to 'http://127.0.0.1:8000/security/xssAuditor/resources/echo-intertag.pl?notifyDone=1&malformed-header=8&q=%3Cscript%3Ealert(String.fromCharCode(0x58,0x53,0x53))%3C/script%3E%3Cp%3EIf%20you%20see%20this%20message%20and%20no%20JavaScript%20alert()%20then%20the%20test%20PASSED.%3C/p%3E' because the source code of a script was found within the request. The auditor was enabled as the server did not send an 'X-XSS-Protection' header.
ALERT: URL mismatch: '[Location object access threw exception]' vs. 'http://127.0.0.1:8000/security/xssAuditor/resources/echo-intertag.pl?notifyDone=1&malformed-header=8&q=%3Cscript%3Ealert(String.fromCharCode(0x58,0x53,0x53))%3C/script%3E%3Cp%3EIf%20you%20see%20this%20message%20and%20no%20JavaScript%20alert()%20then%20the%20test%20PASSED.%3C/p%3E'
This tests that the X-XSS-Protection header is not ignored when there is an duplicate mode directive, and we issue an error
--------
Frame: 'frame'
--------
Could not load the requested resource.
Error code: -28 (net::ERR_BLOCKED_BY_XSS_AUDITOR)
<!DOCTYPE html>
<html>
<head>
<script src="http://localhost:8000/security/xssAuditor/resources/utilities.js"></script>
<script>
if (window.testRunner) {
testRunner.dumpAsText();
testRunner.dumpChildFramesAsText();
testRunner.waitUntilDone();
testRunner.setXSSAuditorEnabled(true);
}
</script>
</head>
<body>
<p>This tests that the X-XSS-Protection header is not ignored when there is an duplicate mode directive, and we issue an error</p>
<iframe id="frame" name="frame" onload="checkIfFrameLocationMatchesSrcAndCallDone('frame')" src="http://127.0.0.1:8000/security/xssAuditor/resources/echo-intertag.pl?notifyDone=1&malformed-header=8&q=<script>alert(String.fromCharCode(0x58,0x53,0x53))</script><p>If you see this message and no JavaScript alert() then the test PASSED.</p>">
</iframe>
</body>
</html>
CONSOLE ERROR: Error parsing header X-XSS-Protection: 1; mode=block; report=/fail; report=/fail;: duplicate report directive at character position 35. The default protections will be applied.
CONSOLE ERROR: line 4: The XSS Auditor blocked access to 'http://127.0.0.1:8000/security/xssAuditor/resources/echo-intertag.pl?notifyDone=1&malformed-header=9&q=%3Cscript%3Ealert(String.fromCharCode(0x58,0x53,0x53))%3C/script%3E%3Cp%3EIf%20you%20see%20this%20message%20and%20no%20JavaScript%20alert()%20then%20the%20test%20PASSED.%3C/p%3E' because the source code of a script was found within the request. The auditor was enabled as the server did not send an 'X-XSS-Protection' header.
ALERT: URL mismatch: '[Location object access threw exception]' vs. 'http://127.0.0.1:8000/security/xssAuditor/resources/echo-intertag.pl?notifyDone=1&malformed-header=9&q=%3Cscript%3Ealert(String.fromCharCode(0x58,0x53,0x53))%3C/script%3E%3Cp%3EIf%20you%20see%20this%20message%20and%20no%20JavaScript%20alert()%20then%20the%20test%20PASSED.%3C/p%3E'
This tests that the X-XSS-Protection header is not ignored when there is a duplicate report directive, and we issue an error
--------
Frame: 'frame'
--------
Could not load the requested resource.
Error code: -28 (net::ERR_BLOCKED_BY_XSS_AUDITOR)
<!DOCTYPE html>
<html>
<head>
<script src="http://localhost:8000/security/xssAuditor/resources/utilities.js"></script>
<script>
if (window.testRunner) {
testRunner.dumpAsText();
testRunner.dumpChildFramesAsText();
testRunner.waitUntilDone();
testRunner.setXSSAuditorEnabled(true);
}
</script>
</head>
<body>
<p>This tests that the X-XSS-Protection header is not ignored when there is a duplicate report directive, and we issue an error</p>
<iframe id="frame" name="frame" onload="checkIfFrameLocationMatchesSrcAndCallDone('frame')" src="http://127.0.0.1:8000/security/xssAuditor/resources/echo-intertag.pl?notifyDone=1&malformed-header=9&q=<script>alert(String.fromCharCode(0x58,0x53,0x53))</script><p>If you see this message and no JavaScript alert() then the test PASSED.</p>">
</iframe>
</body>
</html>
...@@ -34,30 +34,6 @@ if ($cgi->param('disable-protection')) { ...@@ -34,30 +34,6 @@ if ($cgi->param('disable-protection')) {
if ($cgi->param('malformed-header') == 1) { if ($cgi->param('malformed-header') == 1) {
print "X-XSS-Protection: 12345678901234567\n"; print "X-XSS-Protection: 12345678901234567\n";
} }
if ($cgi->param('malformed-header') == 2) {
print "X-XSS-Protection: red\n";
}
if ($cgi->param('malformed-header') == 3) {
print "X-XSS-Protection: 1; mode=purple\n";
}
if ($cgi->param('malformed-header') == 4) {
print "X-XSS-Protection: 1; mode=block-a-block-block\n";
}
if ($cgi->param('malformed-header') == 5) {
print "X-XSS-Protection: 1; mode=block; report\n";
}
if ($cgi->param('malformed-header') == 6) {
print "X-XSS-Protection: 1; report= ;\n";
}
if ($cgi->param('malformed-header') == 7) {
print "X-XSS-Protection: 1; red\n";
}
if ($cgi->param('malformed-header') == 8) {
print "X-XSS-Protection: 1; mode=block; report=/fail; mode=block;\n";
}
if ($cgi->param('malformed-header') == 9) {
print "X-XSS-Protection: 1; mode=block; report=/fail; report=/fail;\n";
}
} else { } else {
print "X-XSS-Protection: 1\n"; print "X-XSS-Protection: 1\n";
} }
......
...@@ -53,9 +53,8 @@ enum ContentTypeOptionsDisposition { ...@@ -53,9 +53,8 @@ enum ContentTypeOptionsDisposition {
kContentTypeOptionsNosniff kContentTypeOptionsNosniff
}; };
// Be sure to update the behavior of // Be aware that some behavior may depend on this enum's ordering, with
// XSSAuditor::combineXSSProtectionHeaderAndCSP whenever you change this enum's // higher values taking precedence over lower ones.
// content or ordering.
enum ReflectedXSSDisposition { enum ReflectedXSSDisposition {
kReflectedXSSUnset = 0, kReflectedXSSUnset = 0,
kAllowReflectedXSS, kAllowReflectedXSS,
...@@ -112,11 +111,19 @@ PLATFORM_EXPORT double ParseDate(const String&); ...@@ -112,11 +111,19 @@ PLATFORM_EXPORT double ParseDate(const String&);
// are trimmed. // are trimmed.
PLATFORM_EXPORT AtomicString ExtractMIMETypeFromMediaType(const AtomicString&); PLATFORM_EXPORT AtomicString ExtractMIMETypeFromMediaType(const AtomicString&);
// Given an X-XSS-Protection value like "1; mode=block; report=/foo", combine
// the first positional parameter and the "mode" into the result code, and
// return the "report" as report_url, if present. Return kReflectedXSSInvalid
// on bad syntax, setting |failure_reason| and |failure_position|, otherwise
// set |failure_position| to the start of the "report" URL, if present (since
// it is not validated here, and the caller may need that position information
// to construct an error message).
PLATFORM_EXPORT ReflectedXSSDisposition PLATFORM_EXPORT ReflectedXSSDisposition
ParseXSSProtectionHeader(const String& header, ParseXSSProtectionHeader(const String& header,
String& failure_reason, String& failure_reason,
unsigned& failure_position, unsigned& failure_position,
String& report_url); String& report_url);
PLATFORM_EXPORT CacheControlHeader PLATFORM_EXPORT CacheControlHeader
ParseCacheControlDirectives(const AtomicString& cache_control_header, ParseCacheControlDirectives(const AtomicString& cache_control_header,
const AtomicString& pragma_header); const AtomicString& pragma_header);
......
...@@ -586,4 +586,151 @@ TEST(HTTPParsersTest, ParseContentTypeOptionsTest) { ...@@ -586,4 +586,151 @@ TEST(HTTPParsersTest, ParseContentTypeOptionsTest) {
} }
} }
TEST(HTTPParsersTest, ParseXSSProtectionDirectives) {
// clang-format off
struct {
const char* input;
ReflectedXSSDisposition expected_result;
const char* expected_failure_reason;
unsigned expected_failure_position;
const char* expected_report_url;
unsigned line;
} tests[] = {
#undef SUCC__
#undef FAIL__
#define SUCC__(a, b, d, e) { a, b, nullptr, d, e, __LINE__ }
#define FAIL__(a, c, d) {a, kReflectedXSSInvalid, c, d, nullptr, __LINE__}
// Empty header.
SUCC__("", kReflectedXSSUnset, 0, nullptr),
SUCC__(" ", kReflectedXSSUnset, 0, nullptr),
// First positional parameter tests.
SUCC__("0", kAllowReflectedXSS, 0, nullptr),
SUCC__(" 0 ", kAllowReflectedXSS, 0, nullptr),
SUCC__(" 0 ;", kAllowReflectedXSS, 0, nullptr),
SUCC__("1", kFilterReflectedXSS, 0, nullptr),
SUCC__(" 1 ", kFilterReflectedXSS, 0, nullptr),
SUCC__(" 1 ;", kFilterReflectedXSS, 0, nullptr),
FAIL__(";", "expected 0 or 1", 0),
FAIL__(";;", "expected 0 or 1", 0),
FAIL__(";;;", "expected 0 or 1", 0),
FAIL__(" ; ", "expected 0 or 1", 0),
FAIL__(" ; ; ", "expected 0 or 1", 0),
FAIL__("; ; ;", "expected 0 or 1", 0),
FAIL__("2", "expected 0 or 1", 0),
FAIL__(" 2 ", "expected 0 or 1", 0),
FAIL__("-1", "expected 0 or 1", 0),
FAIL__(" -1 ", "expected 0 or 1", 0),
FAIL__("red", "expected 0 or 1", 0),
FAIL__("12345678901234567", "expected semicolon", 2),
FAIL__("1:", "expected semicolon", 2),
FAIL__("1 2", "expected semicolon", 3),
FAIL__("1; red", "unrecognized directive", 3),
// Don't allow quoted strings here.
FAIL__("\"", "expected 0 or 1", 0),
FAIL__("\"0", "expected 0 or 1", 0),
FAIL__("\"0\"", "expected 0 or 1", 0),
FAIL__("\" 0 \"", "expected 0 or 1", 0),
FAIL__("\" 0\";", "expected 0 or 1", 0),
FAIL__("\" 0;\"", "expected 0 or 1", 0),
FAIL__("\"1", "expected 0 or 1", 0),
FAIL__("\"1\"", "expected 0 or 1", 0),
FAIL__("\" 1 \"", "expected 0 or 1", 0),
FAIL__("\" 1\";", "expected 0 or 1", 0),
FAIL__("\" 1;\"", "expected 0 or 1", 0),
// No other parameters unless enabled.
SUCC__("0; mode=block; report=http://u:p@x.com:n/f.x?q=3&v=%26#tag",
kAllowReflectedXSS, 0, nullptr),
SUCC__("0; all sorts of nonsense; \"here\"",
kAllowReflectedXSS, 0, nullptr),
// Mode parameter tests.
SUCC__("1;mode=block", kBlockReflectedXSS, 0, nullptr),
SUCC__("1; mode=block;", kBlockReflectedXSS, 0, nullptr),
SUCC__("1; mode=block; ", kBlockReflectedXSS, 0, nullptr),
SUCC__("1; mode=block ;", kBlockReflectedXSS, 0, nullptr),
SUCC__("1; mode= block;", kBlockReflectedXSS, 0, nullptr),
SUCC__("1; mode =block;", kBlockReflectedXSS, 0, nullptr),
FAIL__("1; mode", "expected equals sign", 7),
FAIL__("1; mode=", "expected equals sign", 8),
FAIL__("1; mode =", "expected equals sign", 9),
FAIL__("1; mode=purple", "invalid mode directive", 8),
FAIL__("1; mode=block-a-block-block", "expected semicolon", 14),
FAIL__("1; mode=block=a-block-block", "expected semicolon", 14),
FAIL__("1; mode=block; mode=block", "duplicate mode directive", 19),
FAIL__("1; mode=block; report=foo; mode=block;",
"duplicate mode directive", 31),
// TODO(tsepez): allow quoted strings here.
FAIL__("1; mode=\"block\"", "invalid mode directive", 8),
FAIL__("1; mode=\"block\";", "invalid mode directive", 8),
FAIL__("1; mode=\"block;\"", "invalid mode directive", 8),
FAIL__("1; mode=\"red\"", "invalid mode directive", 8),
// Report url parameter tests.
SUCC__("1;report=http://u:p@x.com:n/f.x?q=3&v=%26#tag",
kFilterReflectedXSS, 9, "http://u:p@x.com:n/f.x?q=3&v=%26#tag"),
SUCC__("1; report=http://u:p@x.com:n/f.x?q=3&v=%26#tag",
kFilterReflectedXSS, 10, "http://u:p@x.com:n/f.x?q=3&v=%26#tag"),
SUCC__("1; report=http://u:p@x.com:n/f.x?q=3&v=%26#tag ",
kFilterReflectedXSS, 10, "http://u:p@x.com:n/f.x?q=3&v=%26#tag"),
SUCC__("1; report= http://u:p@x.com:n/f.x?q=3&v=%26#tag",
kFilterReflectedXSS, 11, "http://u:p@x.com:n/f.x?q=3&v=%26#tag"),
SUCC__("1; report =http://u:p@x.com:n/f.x?q=3&v=%26#tag",
kFilterReflectedXSS, 11, "http://u:p@x.com:n/f.x?q=3&v=%26#tag"),
SUCC__("1; report=http://u:p@x.com:n/f.x?q=3&v=%26#tag;",
kFilterReflectedXSS, 10, "http://u:p@x.com:n/f.x?q=3&v=%26#tag"),
SUCC__("1; mode=block; report=http://u:p@x.com:n/f.x?q=3&v=%26#tag",
kBlockReflectedXSS, 22, "http://u:p@x.com:n/f.x?q=3&v=%26#tag"),
SUCC__("1; report=http://u:p@x.com:n/f.x?q=3&v=%26#tag; mode=block",
kBlockReflectedXSS, 10, "http://u:p@x.com:n/f.x?q=3&v=%26#tag"),
FAIL__("1; report", "expected equals sign", 9),
FAIL__("1; report=", "expected equals sign", 10),
FAIL__("1; report= ;", "invalid report directive", 11),
FAIL__("1; report=http://foo.com; mode=block; report=http://foo.com;",
"duplicate report directive", 44),
FAIL__("1; report=http://foo.com;SEQUID=7", "unrecognized directive", 25),
FAIL__("1; mode=block; report=http://foo.com;SEQUID=7",
"unrecognized directive", 37),
// TODO(tsepez): See https://crbug.com/825557
SUCC__("1; report=\"", kFilterReflectedXSS, 10, "\""),
SUCC__("1; report=\"http://foo.com", kFilterReflectedXSS, 10,
"\"http://foo.com"),
SUCC__("1; report=\"http://foo.com\"", kFilterReflectedXSS, 10,
"\"http://foo.com\""),
FAIL__("1; report=\"http://foo.com;SEQUID=7\"", "unrecognized directive",
26),
FAIL__("1; report=\"http://foo.com\";SEQUID=7", "unrecognized directive",
27),
#undef SUCC__
#undef FAIL__
};
// clang-format on
for (const auto& test : tests) {
String report_url;
String failure_reason;
unsigned failure_position = 0;
ReflectedXSSDisposition result = ParseXSSProtectionHeader(
test.input, failure_reason, failure_position, report_url);
EXPECT_EQ(test.expected_result, result)
<< "for testcase at line " << test.line;
if (result == kReflectedXSSInvalid) {
EXPECT_EQ(test.expected_failure_reason, failure_reason)
<< "for testcase at line " << test.line;
} else {
EXPECT_EQ(test.expected_report_url, report_url)
<< "for testcase at line " << test.line;
}
EXPECT_EQ(test.expected_failure_position, failure_position)
<< "for testcase at line " << test.line;
}
}
} // namespace blink } // namespace blink
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment