X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2FContentSecurityPolicy.php;h=be598eae8314cf47d0762d9a86402dbdc9baa8ed;hb=8768c686e68e89d86adc31ed03da1ec81aae1965;hp=91117f4e361f5c8407db9426d2646cebaafd837c;hpb=33ac4182cae78d525d5fabd317d5889f52c46135;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/ContentSecurityPolicy.php b/includes/ContentSecurityPolicy.php index 91117f4e36..be598eae83 100644 --- a/includes/ContentSecurityPolicy.php +++ b/includes/ContentSecurityPolicy.php @@ -27,8 +27,6 @@ class ContentSecurityPolicy { const REPORT_ONLY_MODE = 1; const FULL_MODE = 2; - /** Used for meta tag. Does not include report urls or nonce sources */ - const FULL_MODE_RESTRICTED = 3; /** @var string The nonce to use for inline scripts (from OutputPage) */ private $nonce; @@ -65,20 +63,6 @@ class ContentSecurityPolicy { } } - /** - * Return the meta header to use for after load restricted mode - * - * This should restrict browsers that don't support nonce-sources. - * Idea stolen from - * https://blogs.dropbox.com/tech/2015/09/unsafe-inline-and-nonce-deployment/ - * - * @param array $csp CSP configuration - * @return string Content for meta tag - */ - public function getMetaHeader( $csp ) { - return $this->makeCSPDirectives( $csp, self::FULL_MODE_RESTRICTED ); - } - /** * Send CSP headers based on wiki config * @@ -100,39 +84,13 @@ class ContentSecurityPolicy { $csp->sendCSPHeader( $cspConfig, self::FULL_MODE ); $csp->sendCSPHeader( $cspConfigReportOnly, self::REPORT_ONLY_MODE ); - // Include header which increases security level after initial load. - // This helps mitigate attacks on browsers not supporting CSP2. It also - // helps mitigate attacks due to the shared nonce that non-logged in users - // get due to varnish cache. - // Unclear if this is the best place to insert the meta tag, or if - // it should be in a RL module. I figure its best to do this as early - // as possible. - // FIXME: Needs testing to see if this actually works properly - $metaHeader = $csp->getMetaHeader( $cspConfig ); - if ( $metaHeader ) { - $context->getOutput()->addScript( - ResourceLoader::makeInlineScript( - $csp->makeMetaInsertScript( - $metaHeader - ), - $out->getCSPNonce() - ) - ); - } - } - - /** - * Makes javascript to insert a meta CSP header after page load - * - * @see https://blogs.dropbox.com/tech/2015/09/unsafe-inline-and-nonce-deployment/ - * @param string $metaContents content of meta tag - * @return string JS for including in page - */ - private function makeMetaInsertScript( $metaContents ) { - return "$('\\x3Cmeta http-equiv=\"Content-Security-Policy\"\\x3E')" . - '.attr("content",' . - Xml::encodeJsVar( $metaContents ) . - ').prependTo($("head"))'; + // This used to insert a tag here, per advice at + // https://blogs.dropbox.com/tech/2015/09/unsafe-inline-and-nonce-deployment/ + // The goal was to prevent nonce from working after the page hit onready, + // This would help in old browsers that didn't support nonces, and + // also assist for varnish-cached pages which repeat nonces. + // However, this is incompatible with how resource loader storage works + // via mw.domEval() so it was removed. } /** @@ -140,12 +98,14 @@ class ContentSecurityPolicy { * * @param int $reportOnly Either self::REPORT_ONLY_MODE or self::FULL_MODE * @return string Name of http header - * @throws UnexpectedValueException if you feed it self::FULL_MODE_RESTRICTED. + * @throws UnexpectedValueException */ private function getHeaderName( $reportOnly ) { if ( $reportOnly === self::REPORT_ONLY_MODE ) { return 'Content-Security-Policy-Report-Only'; - } elseif ( $reportOnly === self::FULL_MODE ) { + } + + if ( $reportOnly === self::FULL_MODE ) { return 'Content-Security-Policy'; } throw new UnexpectedValueException( $reportOnly ); @@ -154,8 +114,9 @@ class ContentSecurityPolicy { /** * Determine what CSP policies to set for this page * - * @param array|bool $config Policy configuration (Either $wgCSPHeader or $wgCSPReportOnlyHeader) - * @param int $mode self::REPORT_ONLY_MODE, self::FULL_MODE or Self::FULL_MODE_RESTRICTED + * @param array|bool $policyConfig Policy configuration + * (Either $wgCSPHeader or $wgCSPReportOnlyHeader) + * @param int $mode self::REPORT_ONLY_MODE, self::FULL_MODE * @return string Policy directives, or empty string for no policy. */ private function makeCSPDirectives( $policyConfig, $mode ) { @@ -182,13 +143,10 @@ class ContentSecurityPolicy { $cssSrc = false; $imgSrc = false; $scriptSrc = [ "'unsafe-eval'", "'self'" ]; - if ( - $mode !== self::FULL_MODE_RESTRICTED && - ( !isset( $policyConfig['useNonces'] ) || $policyConfig['useNonces'] ) - ) { - $nonceSrc = "'nonce-" . $this->nonce . "'"; - $scriptSrc[] = $nonceSrc; + if ( !isset( $policyConfig['useNonces'] ) || $policyConfig['useNonces'] ) { + $scriptSrc[] = "'nonce-" . $this->nonce . "'"; } + $scriptSrc = array_merge( $scriptSrc, $additionalSelfUrlsScript ); if ( isset( $policyConfig['script-src'] ) && is_array( $policyConfig['script-src'] ) @@ -198,9 +156,8 @@ class ContentSecurityPolicy { } } // Note: default on if unspecified. - if ( ( !isset( $policyConfig['unsafeFallback'] ) - || $policyConfig['unsafeFallback'] ) - && $mode !== self::FULL_MODE_RESTRICTED + if ( !isset( $policyConfig['unsafeFallback'] ) + || $policyConfig['unsafeFallback'] ) { // unsafe-inline should be ignored on browsers // that support 'nonce-foo' sources. @@ -247,10 +204,7 @@ class ContentSecurityPolicy { $cssSrc = array_merge( $defaultSrc, [ "'unsafe-inline'" ] ); } - if ( $mode === self::FULL_MODE_RESTRICTED ) { - // report-uri disallowed in tags. - $reportUri = false; - } elseif ( isset( $policyConfig['report-uri'] ) && $policyConfig['report-uri'] !== true ) { + if ( isset( $policyConfig['report-uri'] ) && $policyConfig['report-uri'] !== true ) { if ( $policyConfig['report-uri'] === false ) { $reportUri = false; } else { @@ -311,14 +265,11 @@ class ContentSecurityPolicy { /** * Get the default report uri. * - * @param int $mode self::*_MODE constant. Do not use with self::FULL_MODE_RESTRICTED + * @param int $mode self::*_MODE constant. * @return string The URI to send reports to. * @throws UnexpectedValueException if given invalid mode. */ private function getReportUri( $mode ) { - if ( $mode === self::FULL_MODE_RESTRICTED ) { - throw new UnexpectedValueException( $mode ); - } $apiArguments = [ 'action' => 'cspreport', 'format' => 'json'