From 1ad6fe1cbd65a22008184e8578d6b349d30a00ed Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Sat, 17 Mar 2018 15:51:40 +0000 Subject: [PATCH] Added togglable script escaping to page content Configurable via 'ALLOW_CONTENT_SCRIPTS' env variable. Fixes #575 --- app/Repos/EntityRepo.php | 22 ++++++++++++++++++++++ config/app.php | 2 ++ tests/Entity/PageContentTest.php | 27 +++++++++++++++++++++++++++ 3 files changed, 51 insertions(+) diff --git a/app/Repos/EntityRepo.php b/app/Repos/EntityRepo.php index 64f7a0810..ece9aa305 100644 --- a/app/Repos/EntityRepo.php +++ b/app/Repos/EntityRepo.php @@ -713,6 +713,10 @@ class EntityRepo public function renderPage(Page $page, $ignorePermissions = false) { $content = $page->html; + if (!config('app.allow_content_scripts')) { + $content = $this->escapeScripts($content); + } + $matches = []; preg_match_all("/{{@\s?([0-9].*?)}}/", $content, $matches); if (count($matches[0]) === 0) { @@ -760,6 +764,24 @@ class EntityRepo return $content; } + /** + * Escape script tags within HTML content. + * @param string $html + * @return mixed + */ + protected function escapeScripts(string $html) + { + $scriptSearchRegex = '/.*?<\/script>/ms'; + $matches = []; + preg_match_all($scriptSearchRegex, $html, $matches); + if (count($matches) === 0) return $html; + + foreach ($matches[0] as $match) { + $html = str_replace($match, htmlentities($match), $html); + } + return $html; + } + /** * Get the plain text version of a page's content. * @param Page $page diff --git a/config/app.php b/config/app.php index fb958f89c..ce2225221 100755 --- a/config/app.php +++ b/config/app.php @@ -8,6 +8,8 @@ return [ 'books' => env('APP_VIEWS_BOOKS', 'list') ], + 'allow_content_scripts' => env('ALLOW_CONTENT_SCRIPTS', false), + /* |-------------------------------------------------------------------------- | Application Debug Mode diff --git a/tests/Entity/PageContentTest.php b/tests/Entity/PageContentTest.php index 370514788..8b0e180da 100644 --- a/tests/Entity/PageContentTest.php +++ b/tests/Entity/PageContentTest.php @@ -112,4 +112,31 @@ class PageContentTest extends TestCase $pageView->assertSee('def456'); } + public function test_page_content_scripts_escaped_by_default() + { + $this->asEditor(); + $page = Page::first(); + $script = ''; + $page->html = "escape {$script}"; + $page->save(); + + $pageView = $this->get($page->getUrl()); + $pageView->assertDontSee($script); + $pageView->assertSee(htmlentities($script)); + } + + public function test_page_content_scripts_show_when_configured() + { + $this->asEditor(); + $page = Page::first(); + config()->push('app.allow_content_scripts', 'true'); + $script = ''; + $page->html = "no escape {$script}"; + $page->save(); + + $pageView = $this->get($page->getUrl()); + $pageView->assertSee($script); + $pageView->assertDontSee(htmlentities($script)); + } + }