Add support for 'child-src' directive

This is required when working with stuff such as PDF.js in the files_pdfviewer application. Opt-in only.

Master change only because the stable CSP policies has a failback that allows nearly anything 🙈
This commit is contained in:
Lukas Reschke 2015-02-26 12:54:15 +01:00
parent 42f6448da2
commit b29940d956
2 changed files with 34 additions and 2 deletions

View file

@ -65,6 +65,8 @@ class ContentSecurityPolicy {
private $allowedFontDomains = [
'\'self\'',
];
/** @var array Domains from which web-workers and nested browsing content can load elements */
private $allowedChildSrcDomains = [];
/**
* Whether inline JavaScript snippets are allowed or forbidden
@ -180,6 +182,16 @@ class ContentSecurityPolicy {
return $this;
}
/**
* Domains from which web-workers and nested browsing content can load elements
* @param string $domain Domain to whitelist. Any passed value needs to be properly sanitized.
* @return $this
*/
public function addAllowedChildSrcDomain($domain) {
$this->allowedChildSrcDomains[] = $domain;
return $this;
}
/**
* Get the generated Content-Security-Policy as a string
* @return string
@ -236,6 +248,11 @@ class ContentSecurityPolicy {
$policy .= ';';
}
if(!empty($this->allowedChildSrcDomains)) {
$policy .= 'child-src ' . implode(' ', $this->allowedChildSrcDomains);
$policy .= ';';
}
return rtrim($policy, ';');
}
}

View file

@ -181,7 +181,6 @@ class ContentSecurityPolicyTest extends \Test\TestCase {
$this->assertSame($expectedPolicy, $this->contentSecurityPolicy->buildPolicy());
}
public function testGetAllowedFrameDomain() {
$expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self';font-src 'self';connect-src 'self';media-src 'self';frame-src www.owncloud.com";
@ -197,8 +196,23 @@ class ContentSecurityPolicyTest extends \Test\TestCase {
$this->assertSame($expectedPolicy, $this->contentSecurityPolicy->buildPolicy());
}
public function testGetAllowedChildSrcDomain() {
$expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self';font-src 'self';connect-src 'self';media-src 'self';child-src child.owncloud.com";
$this->contentSecurityPolicy->addAllowedChildSrcDomain('child.owncloud.com');
$this->assertSame($expectedPolicy, $this->contentSecurityPolicy->buildPolicy());
}
public function testGetPolicyChildSrcValidMultiple() {
$expectedPolicy = "default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self';font-src 'self';connect-src 'self';media-src 'self';child-src child.owncloud.com child.owncloud.org";
$this->contentSecurityPolicy->addAllowedChildSrcDomain('child.owncloud.com');
$this->contentSecurityPolicy->addAllowedChildSrcDomain('child.owncloud.org');
$this->assertSame($expectedPolicy, $this->contentSecurityPolicy->buildPolicy());
}
public function testConfigureStacked() {
$expectedPolicy = "default-src 'none';script-src 'self' script.owncloud.org;style-src 'self' style.owncloud.org;img-src 'self' img.owncloud.org;font-src 'self' font.owncloud.org;connect-src 'self' connect.owncloud.org;media-src 'self' media.owncloud.org;object-src objects.owncloud.org;frame-src frame.owncloud.org";
$expectedPolicy = "default-src 'none';script-src 'self' script.owncloud.org;style-src 'self' style.owncloud.org;img-src 'self' img.owncloud.org;font-src 'self' font.owncloud.org;connect-src 'self' connect.owncloud.org;media-src 'self' media.owncloud.org;object-src objects.owncloud.org;frame-src frame.owncloud.org;child-src child.owncloud.org";
$this->contentSecurityPolicy->allowInlineStyle(false)
->allowEvalScript(false)
@ -209,6 +223,7 @@ class ContentSecurityPolicyTest extends \Test\TestCase {
->addAllowedConnectDomain('connect.owncloud.org')
->addAllowedMediaDomain('media.owncloud.org')
->addAllowedObjectDomain('objects.owncloud.org')
->addAllowedChildSrcDomain('child.owncloud.org')
->addAllowedFrameDomain('frame.owncloud.org');
$this->assertSame($expectedPolicy, $this->contentSecurityPolicy->buildPolicy());
}