Skip to content

Commit

Permalink
XSS and redirect fixes with test cases
Browse files Browse the repository at this point in the history
  • Loading branch information
PercussiveElbow committed Oct 27, 2020
1 parent 6aa2bf9 commit bbd1384
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 0 deletions.
18 changes: 18 additions & 0 deletions app/Entities/Managers/PageContent.php
Expand Up @@ -296,6 +296,24 @@ protected function escapeScripts(string $html) : string
$scriptElem->parentNode->removeChild($scriptElem);
}

// Remove clickable links to JavaScript URI
$badLinks = $xPath->query('//*[contains(@href, \'javascript:\')]');
foreach ($badLinks as $badLink) {
$badLink->parentNode->removeChild($badLink);
}

// Remove forms with calls to JavaScript URI
$badForms = $xPath->query('//*[contains(@action, \'javascript:\')] | //*[contains(@formaction, \'javascript:\')]');
foreach ($badForms as $badForm) {
$badForm->parentNode->removeChild($badForm);
}

// Remove meta tag to prevent external redirects
$metaTags = $xPath->query('//meta[contains(@content, \'url\')]');
foreach ($metaTags as $metaTag) {
$metaTag->parentNode->removeChild($metaTag);
}

// Remove data or JavaScript iFrames
$badIframes = $xPath->query('//*[contains(@src, \'data:\')] | //*[contains(@src, \'javascript:\')] | //*[@srcdoc]');
foreach ($badIframes as $badIframe) {
Expand Down
66 changes: 66 additions & 0 deletions tests/Entity/PageContentTest.php
Expand Up @@ -159,6 +159,72 @@ public function test_iframe_js_and_base64_urls_are_removed()

}

public function test_javascript_uri_links_are_removed()
{
$checks = [
'<a id="xss" href="javascript:alert(document.cookie)>Click me</a>',
'<a id="xss" href="javascript: alert(document.cookie)>Click me</a>'
];

$this->asEditor();
$page = Page::first();

foreach ($checks as $check) {
$page->html = $check;
$page->save();

$pageView = $this->get($page->getUrl());
$pageView->assertStatus(200);
$pageView->assertElementNotContains('.page-content', '<a id="xss">');
$pageView->assertElementNotContains('.page-content', 'href=javascript:');
}
}
public function test_form_actions_with_javascript_are_removed()
{
$checks = [
'<form><input id="xss" type=submit formaction=javascript:alert(document.domain) value=Submit><input></form>',
'<form ><button id="xss" formaction=javascript:alert(document.domain)>Click me</button></form>',
'<form id="xss" action=javascript:alert(document.domain)><input type=submit value=Submit></form>'
];

$this->asEditor();
$page = Page::first();

foreach ($checks as $check) {
$page->html = $check;
$page->save();

$pageView = $this->get($page->getUrl());
$pageView->assertStatus(200);
$pageView->assertElementNotContains('.page-content', '<button id="xss"');
$pageView->assertElementNotContains('.page-content', '<input id="xss"');
$pageView->assertElementNotContains('.page-content', '<form id="xss"');
$pageView->assertElementNotContains('.page-content', 'action=javascript:');
$pageView->assertElementNotContains('.page-content', 'formaction=javascript:');
}
}

public function test_metadata_redirects_are_removed()
{
$checks = [
'<meta http-equiv="refresh" content="0; url=//external_url">',
];

$this->asEditor();
$page = Page::first();

foreach ($checks as $check) {
$page->html = $check;
$page->save();

$pageView = $this->get($page->getUrl());
$pageView->assertStatus(200);
$pageView->assertElementNotContains('.page-content', '<meta>');
$pageView->assertElementNotContains('.page-content', '</meta>');
$pageView->assertElementNotContains('.page-content', 'content=');
$pageView->assertElementNotContains('.page-content', 'external_url');
}
}
public function test_page_inline_on_attributes_removed_by_default()
{
$this->asEditor();
Expand Down

0 comments on commit bbd1384

Please sign in to comment.