* * For the full copyright and license information, please view * the LICENSE file that was distributed with this source code. */ namespace CodeIgniter\HTTP; use Config\ContentSecurityPolicy as ContentSecurityPolicyConfig; /** * Provides tools for working with the Content-Security-Policy header * to help defeat XSS attacks. * * @see http://www.w3.org/TR/CSP/ * @see http://www.html5rocks.com/en/tutorials/security/content-security-policy/ * @see http://content-security-policy.com/ * @see https://www.owasp.org/index.php/Content_Security_Policy */ class ContentSecurityPolicy { /** * Used for security enforcement * * @var array|string */ protected $baseURI = []; /** * Used for security enforcement * * @var array|string */ protected $childSrc = []; /** * Used for security enforcement * * @var array */ protected $connectSrc = []; /** * Used for security enforcement * * @var array|string */ protected $defaultSrc = []; /** * Used for security enforcement * * @var array|string */ protected $fontSrc = []; /** * Used for security enforcement * * @var array|string */ protected $formAction = []; /** * Used for security enforcement * * @var array|string */ protected $frameAncestors = []; /** * Used for security enforcement * * @var array|string */ protected $frameSrc = []; /** * Used for security enforcement * * @var array|string */ protected $imageSrc = []; /** * Used for security enforcement * * @var array|string */ protected $mediaSrc = []; /** * Used for security enforcement * * @var array|string */ protected $objectSrc = []; /** * Used for security enforcement * * @var array|string */ protected $pluginTypes = []; /** * Used for security enforcement * * @var string */ protected $reportURI; /** * Used for security enforcement * * @var array|string */ protected $sandbox = []; /** * Used for security enforcement * * @var array|string */ protected $scriptSrc = []; /** * Used for security enforcement * * @var array|string */ protected $styleSrc = []; /** * Used for security enforcement * * @var array|string */ protected $manifestSrc = []; /** * Used for security enforcement * * @var bool */ protected $upgradeInsecureRequests = false; /** * Used for security enforcement * * @var bool */ protected $reportOnly = false; /** * Used for security enforcement * * @var array */ protected $validSources = [ 'self', 'none', 'unsafe-inline', 'unsafe-eval', ]; /** * Used for security enforcement * * @var array */ protected $nonces = []; /** * An array of header info since we have * to build ourself before passing to Response. * * @var array */ protected $tempHeaders = []; /** * An array of header info to build * that should only be reported. * * @var array */ protected $reportOnlyHeaders = []; /** * Constructor. * * Stores our default values from the Config file. */ public function __construct(ContentSecurityPolicyConfig $config) { foreach (get_object_vars($config) as $setting => $value) { if (property_exists($this, $setting)) { $this->{$setting} = $value; } } } /** * Compiles and sets the appropriate headers in the request. * * Should be called just prior to sending the response to the user agent. */ public function finalize(ResponseInterface &$response) { $this->generateNonces($response); $this->buildHeaders($response); } /** * If TRUE, nothing will be restricted. Instead all violations will * be reported to the reportURI for monitoring. This is useful when * you are just starting to implement the policy, and will help * determine what errors need to be addressed before you turn on * all filtering. * * @return $this */ public function reportOnly(bool $value = true) { $this->reportOnly = $value; return $this; } /** * Adds a new base_uri value. Can be either a URI class or a simple string. * * base_uri restricts the URLs that can appear in a page’s element. * * @see http://www.w3.org/TR/CSP/#directive-base-uri * * @param array|string $uri * * @return $this */ public function addBaseURI($uri, ?bool $explicitReporting = null) { $this->addOption($uri, 'baseURI', $explicitReporting ?? $this->reportOnly); return $this; } /** * Adds a new valid endpoint for a form's action. Can be either * a URI class or a simple string. * * child-src lists the URLs for workers and embedded frame contents. * For example: child-src https://youtube.com would enable embedding * videos from YouTube but not from other origins. * * @see http://www.w3.org/TR/CSP/#directive-child-src * * @param array|string $uri * * @return $this */ public function addChildSrc($uri, ?bool $explicitReporting = null) { $this->addOption($uri, 'childSrc', $explicitReporting ?? $this->reportOnly); return $this; } /** * Adds a new valid endpoint for a form's action. Can be either * a URI class or a simple string. * * connect-src limits the origins to which you can connect * (via XHR, WebSockets, and EventSource). * * @see http://www.w3.org/TR/CSP/#directive-connect-src * * @param array|string $uri * * @return $this */ public function addConnectSrc($uri, ?bool $explicitReporting = null) { $this->addOption($uri, 'connectSrc', $explicitReporting ?? $this->reportOnly); return $this; } /** * Adds a new valid endpoint for a form's action. Can be either * a URI class or a simple string. * * default_src is the URI that is used for many of the settings when * no other source has been set. * * @see http://www.w3.org/TR/CSP/#directive-default-src * * @param array|string $uri * * @return $this */ public function setDefaultSrc($uri, ?bool $explicitReporting = null) { $this->defaultSrc = [(string) $uri => $explicitReporting ?? $this->reportOnly]; return $this; } /** * Adds a new valid endpoint for a form's action. Can be either * a URI class or a simple string. * * font-src specifies the origins that can serve web fonts. * * @see http://www.w3.org/TR/CSP/#directive-font-src * * @param array|string $uri * * @return $this */ public function addFontSrc($uri, ?bool $explicitReporting = null) { $this->addOption($uri, 'fontSrc', $explicitReporting ?? $this->reportOnly); return $this; } /** * Adds a new valid endpoint for a form's action. Can be either * a URI class or a simple string. * * @see http://www.w3.org/TR/CSP/#directive-form-action * * @param array|string $uri * * @return $this */ public function addFormAction($uri, ?bool $explicitReporting = null) { $this->addOption($uri, 'formAction', $explicitReporting ?? $this->reportOnly); return $this; } /** * Adds a new resource that should allow embedding the resource using * ,