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