asEditor(); $page = $this->entities->page(); $script = 'abc123abc123'; $page->html = "escape {$script}"; $page->save(); $pageView = $this->get($page->getUrl()); $pageView->assertStatus(200); $pageView->assertDontSee($script, false); $pageView->assertSee('abc123abc123'); } public function test_more_complex_content_script_escaping_scenarios() { config()->set('app.content_filtering', 'j'); $checks = [ "

Some script

", "

Some script

", "

Some script

", "

Some script

", "

Some script

", "

Some script

", ]; $this->asEditor(); $page = $this->entities->page(); foreach ($checks as $check) { $page->html = $check; $page->save(); $pageView = $this->get($page->getUrl()); $pageView->assertStatus(200); $this->withHtml($pageView)->assertElementNotContains('.page-content', ''); } } public function test_js_and_base64_src_urls_are_removed() { config()->set('app.content_filtering', 'j'); $checks = [ '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ]; $this->asEditor(); $page = $this->entities->page(); foreach ($checks as $check) { $page->html = $check; $page->save(); $pageView = $this->get($page->getUrl()); $pageView->assertStatus(200); $html = $this->withHtml($pageView); $html->assertElementNotContains('.page-content', 'assertElementNotContains('.page-content', 'data='); $html->assertElementNotContains('.page-content', ''); $html->assertElementNotContains('.page-content', 'src='); $html->assertElementNotContains('.page-content', 'javascript:'); $html->assertElementNotContains('.page-content', 'data:'); $html->assertElementNotContains('.page-content', 'base64'); } } public function test_javascript_uri_links_are_removed() { config()->set('app.content_filtering', 'j'); $checks = [ 'withHtml($pageView)->assertElementNotContains('.page-content', 'href=javascript:'); } } public function test_form_filtering_is_controlled_by_config() { config()->set('app.content_filtering', ''); $page = $this->entities->page(); $page->html = '
'; $page->save(); $this->asEditor()->get($page->getUrl())->assertSee('dont-see-this', false); config()->set('app.content_filtering', 'f'); $this->get($page->getUrl())->assertDontSee('dont-see-this', false); } public function test_form_actions_with_javascript_are_removed() { config()->set('app.content_filtering', 'j'); $checks = [ '', 'Click me', 'Click me', '', '', ]; $this->asEditor(); $page = $this->entities->page(); foreach ($checks as $check) { $page->html = $check; $page->save(); $pageView = $this->get($page->getUrl()); $pageView->assertStatus(200); $pageView->assertDontSee('id="xss"', false); $pageView->assertDontSee('action=javascript:', false); $pageView->assertDontSee('action=JaVaScRiPt:', false); $pageView->assertDontSee('formaction=javascript:', false); $pageView->assertDontSee('formaction=JaVaScRiPt:', false); } } public function test_form_elements_are_removed() { config()->set('app.content_filtering', 'f'); $checks = [ '

thisisacattofind

thisdogshouldnotbefound
', '

thisisacattofind

', '

thisisacattofind

', '

thisisacattofind

', '

thisisacattofind

thisdogshouldnotbefound
', '

thisisacattofind

', '

thisisacattofind

', <<<'TESTCASE'

thisisacattofind

thisdogshouldnotbefound

TESTCASE ]; $this->asEditor(); $page = $this->entities->page(); foreach ($checks as $check) { $page->html = $check; $page->save(); $pageView = $this->get($page->getUrl()); $pageView->assertStatus(200); $pageView->assertSee('thisisacattofind'); $pageView->assertDontSee('thisdogshouldnotbefound'); } } public function test_form_attributes_are_removed() { config()->set('app.content_filtering', 'f'); $withinSvgSample = <<<'TESTCASE'

thisisacattofind

thisisacattofind

TESTCASE; $checks = [ 'formaction' => '

thisisacattofind

', 'form' => '

thisisacattofind

', 'formmethod' => '

thisisacattofind

', 'formtarget' => '

thisisacattofind

', 'FORMTARGET' => '

thisisacattofind

', ]; $this->asEditor(); $page = $this->entities->page(); foreach ($checks as $attribute => $check) { $page->html = $check; $page->save(); $pageView = $this->get($page->getUrl()); $pageView->assertStatus(200); $pageView->assertSee('thisisacattofind'); $this->withHtml($pageView)->assertElementNotExists(".page-content [{$attribute}]"); } $page->html = $withinSvgSample; $page->save(); $pageView = $this->get($page->getUrl()); $pageView->assertStatus(200); $html = $this->withHtml($pageView); foreach ($checks as $attribute => $check) { $pageView->assertSee('thisisacattofind'); $html->assertElementNotExists(".page-content [{$attribute}]"); } } public function test_metadata_redirects_are_removed() { config()->set('app.content_filtering', 'h'); $checks = [ '', '', '', ]; $this->asEditor(); $page = $this->entities->page(); foreach ($checks as $check) { $page->html = $check; $page->save(); $pageView = $this->get($page->getUrl()); $pageView->assertStatus(200); $this->withHtml($pageView)->assertElementNotContains('.page-content', ''); $this->withHtml($pageView)->assertElementNotContains('.page-content', ''); $this->withHtml($pageView)->assertElementNotContains('.page-content', 'content='); $this->withHtml($pageView)->assertElementNotContains('.page-content', 'external_url'); } } public function test_page_inline_on_attributes_removed_by_default() { config()->set('app.content_filtering', 'j'); $this->asEditor(); $page = $this->entities->page(); $script = '

Hello

'; $page->html = "escape {$script}"; $page->save(); $pageView = $this->get($page->getUrl()); $pageView->assertStatus(200); $pageView->assertDontSee($script, false); $pageView->assertSee('

Hello

', false); } public function test_more_complex_inline_on_attributes_escaping_scenarios() { config()->set('app.content_filtering', 'j'); $checks = [ '

Hello

', '

Hello

', '
Lorem ipsum dolor sit amet.

Hello

', '
Lorem ipsum dolor sit amet.

Hello

', '
Lorem ipsum dolor sit amet.

Hello

', '
Lorem ipsum dolor sit amet.

Hello

', '
xss link\', ]; $this->asEditor(); $page = $this->entities->page(); foreach ($checks as $check) { $page->html = $check; $page->save(); $pageView = $this->get($page->getUrl()); $pageView->assertStatus(200); $this->withHtml($pageView)->assertElementNotContains('.page-content', 'onclick'); } } public function test_page_content_scripts_show_with_filters_disabled() { $this->asEditor(); $page = $this->entities->page(); config()->set('app.content_filtering', ''); $script = 'abc123abc123'; $page->html = "no escape {$script}"; $page->save(); $pageView = $this->get($page->getUrl()); $pageView->assertSee($script, false); $pageView->assertDontSee('abc123abc123'); } public function test_svg_script_usage_is_removed() { config()->set('app.content_filtering', 'j'); $checks = [ '', '', '', '', '', 'XSS', 'XSS', '', ]; $this->asEditor(); $page = $this->entities->page(); foreach ($checks as $check) { $page->html = $check; $page->save(); $pageView = $this->get($page->getUrl()); $pageView->assertStatus(200); $html = $this->withHtml($pageView); $html->assertElementNotContains('.page-content', 'alert'); $html->assertElementNotContains('.page-content', 'xlink:href'); $html->assertElementNotContains('.page-content', 'application/xml'); $html->assertElementNotContains('.page-content', 'javascript'); } } public function test_page_inline_on_attributes_show_with_filters_disabled() { $this->asEditor(); $page = $this->entities->page(); config()->set('app.content_filtering', ''); $script = '

Hello

'; $page->html = "escape {$script}"; $page->save(); $pageView = $this->get($page->getUrl()); $pageView->assertSee($script, false); $pageView->assertDontSee('

Hello

', false); } public function test_non_content_filtering_is_controlled_by_config() { config()->set('app.content_filtering', ''); $page = $this->entities->page(); $html = <<<'HTML' HTML; $page->html = $html; $page->save(); $resp = $this->asEditor()->get($page->getUrl()); $resp->assertSee('superbeans', false); config()->set('app.content_filtering', 'h'); $resp = $this->asEditor()->get($page->getUrl()); $resp->assertDontSee('superbeans', false); } public function test_non_content_filtering() { config()->set('app.content_filtering', 'h'); $page = $this->entities->page(); $html = <<<'HTML'

inbetweenpsection

superbeans! HTML; $page->html = $html; $page->save(); $resp = $this->asEditor()->get($page->getUrl()); $resp->assertDontSee('superbeans', false); $resp->assertSee('inbetweenpsection', false); } public function test_allow_list_filtering_is_controlled_by_config() { config()->set('app.content_filtering', ''); $page = $this->entities->page(); $page->html = '
Hello!
'; $page->save(); $resp = $this->asEditor()->get($page->getUrl()); $resp->assertSee('style="position: absolute; left: 0;color:#00FFEE;"', false); config()->set('app.content_filtering', 'a'); $resp = $this->get($page->getUrl()); $resp->assertDontSee('style="position: absolute; left: 0;color:#00FFEE;"', false); $resp->assertSee('style="color:#00FFEE;"', false); } public function test_allow_list_style_filtering() { $testCasesExpectedByInput = [ '
Hello!
' => '
Hello!
', '
Hello!
' => '
Hello!
', '
Hello!
' => '
Hello!
', ]; config()->set('app.content_filtering', 'a'); $page = $this->entities->page(); $this->asEditor(); foreach ($testCasesExpectedByInput as $input => $expected) { $page->html = $input; $page->save(); $resp = $this->get($page->getUrl()); $resp->assertSee($expected, false); } } }