fix: only linkify http and https URIs on the error page
escapeButPreserveUris() matched the scheme with "[A-z]+?://", which accepts any scheme. A frame comment containing javascript://x.co/?%0Aalert(1) survives htmlspecialchars() untouched and was then wrapped in an anchor, so clicking it executed script in the origin of the error page. "[A-z]" is also a code point range rather than a letter class, so it additionally matched the six characters between "Z" and "a", making "_://x.co/a" a link too. Match the scheme with "https?" instead, case-insensitively so uppercase "HTTP://" keeps working. Other schemes stay as escaped plain text. The editor integration links are not affected, they are emitted directly by the template and never pass through this method. Fixes #791
This commit is contained in:
1 parent
238f0d6b9a
commit
8652196c72
2 files changed
+48
-1
No files matched your search
@@ -63,6 +63,49 @@ class TemplateHelperTest extends TestCase
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers Whoops\Util\TemplateHelper::escapeButPreserveUris
|
||||
*/
|
||||
public function testEscapeButPreserveUrisIgnoresNonHttpSchemes()
|
||||
{
|
||||
// None of these contain HTML special characters, so escaping leaves them
|
||||
// untouched and the only question is whether they get turned into links.
|
||||
$originals = [
|
||||
// Clicking such a link would run alert(1): the browser decodes %0A to a
|
||||
// newline, which ends the "//x.co/?" JavaScript comment.
|
||||
'javascript://x.co/?%0Aalert(1)',
|
||||
'JAVASCRIPT://x.co/?%0Aalert(1)',
|
||||
'vbscript://x.co/?%0Amsgbox(1)',
|
||||
'data://text.html/?%0Ax',
|
||||
// "_" is between "Z" and "a" in ASCII, so it used to pass as a scheme.
|
||||
'_://x.co/a',
|
||||
'See javascript://x.co/?%0Aalert(document.cookie) for details',
|
||||
];
|
||||
|
||||
foreach ($originals as $original) {
|
||||
$this->assertSame($original, $this->helper->escapeButPreserveUris($original));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers Whoops\Util\TemplateHelper::escapeButPreserveUris
|
||||
*/
|
||||
public function testEscapeButPreserveUrisStillLinksHttpUris()
|
||||
{
|
||||
$originals = [
|
||||
'http://example.com/a',
|
||||
'https://example.com/a',
|
||||
'HTTPS://example.com/a',
|
||||
];
|
||||
|
||||
foreach ($originals as $original) {
|
||||
$this->assertSame(
|
||||
"<a href=\"$original\" target=\"_blank\" rel=\"noreferrer noopener\">$original</a>",
|
||||
$this->helper->escapeButPreserveUris($original)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers Whoops\Util\TemplateHelper::breakOnDelimiter
|
||||
*/
|
||||
|
||||
Reference in new issue
Block a user