From: kaldari Date: Tue, 3 Mar 2015 22:19:35 +0000 (-0800) Subject: If no secret key is available, don't try to use cache X-Git-Tag: 1.31.0-rc.0~12152^2 X-Git-Url: http://git.cyclocoop.org/ecrire?a=commitdiff_plain;h=50c50bea2e;p=lhc%2Fweb%2Fwiklou.git If no secret key is available, don't try to use cache In the unlikely event that no secret key is available, we shouldn't rely on the cache at all in TemplateParser. Adding new compileForEval() function and and moving eval() outside of if statement to prevent code duplication. Also, if the template fails integrity check, generate a notice instead of throwing an exception in case we change the secret key. Change-Id: Id44fdcc9533fc8a9c77e84fcebaa064f602477c6 --- diff --git a/includes/TemplateParser.php b/includes/TemplateParser.php index a178fed4c3..0dbf2c73ea 100644 --- a/includes/TemplateParser.php +++ b/includes/TemplateParser.php @@ -97,57 +97,74 @@ class TemplateParser { // Fetch a secret key for building a keyed hash of the PHP code $config = ConfigFactory::getDefaultInstance()->makeConfig( 'main' ); - $secretKey = $config->get( 'SecretKey' ) ? : 'key'; - - // See if the compiled PHP code is stored in cache. - // CACHE_ACCEL throws an exception if no suitable object cache is present, so fall - // back to CACHE_ANYTHING. - try { - $cache = wfGetCache( CACHE_ACCEL ); - } catch ( Exception $e ) { - $cache = wfGetCache( CACHE_ANYTHING ); - } - $key = wfMemcKey( 'template', $templateName, $fastHash ); - $code = $this->forceRecompile ? null : $cache->get( $key ); - - if ( !$code ) { - // Compile the template into PHP code - $code = self::compile( $fileContents ); - - if ( !$code ) { - throw new Exception( "Could not compile template: {$filename}" ); + $secretKey = $config->get( 'SecretKey' ); + + if ( $secretKey ) { + // See if the compiled PHP code is stored in cache. + // CACHE_ACCEL throws an exception if no suitable object cache is present, so fall + // back to CACHE_ANYTHING. + try { + $cache = wfGetCache( CACHE_ACCEL ); + } catch ( Exception $e ) { + $cache = wfGetCache( CACHE_ANYTHING ); } + $key = wfMemcKey( 'template', $templateName, $fastHash ); + $code = $this->forceRecompile ? null : $cache->get( $key ); - // Strip the "compileForEval( $fileContents, $filename ); - // Prefix the code with a keyed hash (64 hex chars) as an integrity check - $code = hash_hmac( 'sha256', $code, $secretKey ) . $code; + // Prefix the code with a keyed hash (64 hex chars) as an integrity check + $code = hash_hmac( 'sha256', $code, $secretKey ) . $code; - // Cache the compiled PHP code - $cache->set( $key, $code ); - } else { - // Verify the integrity of the cached PHP code - $keyedHash = substr( $code, 0, 64 ); - $code = substr( $code, 64 ); - if ( $keyedHash === hash_hmac( 'sha256', $code, $secretKey ) ) { - $renderer = eval( $code ); + // Cache the compiled PHP code + $cache->set( $key, $code ); } else { - throw new Exception( "Template failed integrity check: {$filename}" ); + // Verify the integrity of the cached PHP code + $keyedHash = substr( $code, 0, 64 ); + $code = substr( $code, 64 ); + if ( $keyedHash !== hash_hmac( 'sha256', $code, $secretKey ) ) { + // Generate a notice if integrity check fails + trigger_error( "Template failed integrity check: {$filename}" ); + } } + // If there is no secret key available, don't use cache + } else { + $code = $this->compileForEval( $fileContents, $filename ); } + $renderer = eval( $code ); return $this->renderers[$templateName] = $renderer; } + /** + * Wrapper for compile() function that verifies successful compilation and strips + * out the '