mirror of
https://github.com/BookStackApp/BookStack.git
synced 2024-08-27 12:41:58 +00:00
XSS and redirect fixes with test cases
This commit is contained in:
parent
6aa2bf9e27
commit
bbd1384acb
@ -296,6 +296,24 @@ class PageContent
|
|||||||
$scriptElem->parentNode->removeChild($scriptElem);
|
$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
|
// Remove data or JavaScript iFrames
|
||||||
$badIframes = $xPath->query('//*[contains(@src, \'data:\')] | //*[contains(@src, \'javascript:\')] | //*[@srcdoc]');
|
$badIframes = $xPath->query('//*[contains(@src, \'data:\')] | //*[contains(@src, \'javascript:\')] | //*[@srcdoc]');
|
||||||
foreach ($badIframes as $badIframe) {
|
foreach ($badIframes as $badIframe) {
|
||||||
|
@ -159,6 +159,72 @@ class PageContentTest extends TestCase
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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()
|
public function test_page_inline_on_attributes_removed_by_default()
|
||||||
{
|
{
|
||||||
$this->asEditor();
|
$this->asEditor();
|
||||||
|
Loading…
Reference in New Issue
Block a user