diff --git a/app/Entities/Repos/EntityRepo.php b/app/Entities/Repos/EntityRepo.php index aad9a1205..7ca25b785 100644 --- a/app/Entities/Repos/EntityRepo.php +++ b/app/Entities/Repos/EntityRepo.php @@ -765,6 +765,12 @@ class EntityRepo $scriptElem->parentNode->removeChild($scriptElem); } + // Remove data or JavaScript iFrames + $badIframes = $xPath->query('//*[contains(@src, \'data:\')] | //*[contains(@src, \'javascript:\')]'); + foreach ($badIframes as $badIframe) { + $badIframe->parentNode->removeChild($badIframe); + } + // Remove 'on*' attributes $onAttributes = $xPath->query('//@*[starts-with(name(), \'on\')]'); foreach ($onAttributes as $attr) { diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php index 8191fbfe2..570896ab6 100644 --- a/app/Http/Controllers/UserController.php +++ b/app/Http/Controllers/UserController.php @@ -146,7 +146,12 @@ class UserController extends Controller ]); $user = $this->userRepo->getById($id); - $user->fill($request->all()); + $user->fill($request->except(['email'])); + + // Email updates + if (userCan('users-manage') && $request->filled('email')) { + $user->email = $request->get('email'); + } // Role updates if (userCan('users-manage') && $request->filled('roles')) { diff --git a/public/.htaccess b/public/.htaccess index 8eb2dd0dd..0d55354ec 100644 --- a/public/.htaccess +++ b/public/.htaccess @@ -1,6 +1,6 @@ - Options -MultiViews + Options -MultiViews -Indexes RewriteEngine On diff --git a/public/uploads/.gitignore b/public/uploads/.gitignore index c96a04f00..cb7328e19 100755 --- a/public/uploads/.gitignore +++ b/public/uploads/.gitignore @@ -1,2 +1,3 @@ * -!.gitignore \ No newline at end of file +!.gitignore +!.htaccess \ No newline at end of file diff --git a/public/uploads/.htaccess b/public/uploads/.htaccess new file mode 100755 index 000000000..45552cb63 --- /dev/null +++ b/public/uploads/.htaccess @@ -0,0 +1 @@ +Options -Indexes \ No newline at end of file diff --git a/resources/views/form/text.blade.php b/resources/views/form/text.blade.php index 948a55cbc..909e87286 100644 --- a/resources/views/form/text.blade.php +++ b/resources/views/form/text.blade.php @@ -1,6 +1,7 @@ has($name)) class="text-neg" @endif @if(isset($placeholder)) placeholder="{{$placeholder}}" @endif + @if(isset($disabled) && $disabled) disabled="disabled" @endif @if(isset($tabindex)) tabindex="{{$tabindex}}" @endif @if(isset($model) || old($name)) value="{{ old($name) ? old($name) : $model->$name}}" @endif> @if($errors->has($name)) diff --git a/resources/views/users/form.blade.php b/resources/views/users/form.blade.php index 96beb7b2f..3d073b2c8 100644 --- a/resources/views/users/form.blade.php +++ b/resources/views/users/form.blade.php @@ -19,7 +19,7 @@
@if($authMethod !== 'ldap' || userCan('users-manage')) - @include('form.text', ['name' => 'email']) + @include('form.text', ['name' => 'email', 'disabled' => !userCan('users-manage')]) @endif
diff --git a/tests/Entity/PageContentTest.php b/tests/Entity/PageContentTest.php index c80b5f1d9..b447a7c5d 100644 --- a/tests/Entity/PageContentTest.php +++ b/tests/Entity/PageContentTest.php @@ -80,6 +80,7 @@ class PageContentTest extends TestCase $page->save(); $pageView = $this->get($page->getUrl()); + $pageView->assertStatus(200); $pageView->assertDontSee($script); $pageView->assertSee('abc123abc123'); } @@ -103,12 +104,42 @@ class PageContentTest extends TestCase $page->save(); $pageView = $this->get($page->getUrl()); + $pageView->assertStatus(200); $pageView->assertElementNotContains('.page-content', ''); } } + public function test_iframe_js_and_base64_urls_are_removed() + { + $checks = [ + '', + '', + '', + '', + + ]; + + $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', ''); + $pageView->assertElementNotContains('.page-content', 'src='); + $pageView->assertElementNotContains('.page-content', 'javascript:'); + $pageView->assertElementNotContains('.page-content', 'data:'); + $pageView->assertElementNotContains('.page-content', 'base64'); + } + + } + public function test_page_inline_on_attributes_removed_by_default() { $this->asEditor(); @@ -118,6 +149,7 @@ class PageContentTest extends TestCase $page->save(); $pageView = $this->get($page->getUrl()); + $pageView->assertStatus(200); $pageView->assertDontSee($script); $pageView->assertSee('

Hello

'); } @@ -130,6 +162,7 @@ class PageContentTest extends TestCase '
Lorem ipsum dolor sit amet.

Hello

', '
Lorem ipsum dolor sit amet.

Hello

', '
Lorem ipsum dolor sit amet.

Hello

', + '