From 2d64890f3f67e08f98bc0628d769017deea20e6e Mon Sep 17 00:00:00 2001 From: Kunal Mehta Date: Tue, 16 May 2017 15:40:08 -0700 Subject: [PATCH] TemplateParser: Improve cache integrity check failure scenario Previously, if the cache integrity check failed then it would emit a warning but then continue to use the code. The integrity check could genuinely fail if the secret key was changed, if the cache was truncated, or other edge case scenarios. Now TemplateParser will recompile if the cache fails the integrity check, and then update the cache with the newly compiled version. Bug: T163154 Change-Id: I9a6c8d528f84cfbabf402cfaf6468c162fab1f15 --- includes/TemplateParser.php | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/includes/TemplateParser.php b/includes/TemplateParser.php index 924c347aa5..2759ff9baa 100644 --- a/includes/TemplateParser.php +++ b/includes/TemplateParser.php @@ -102,20 +102,22 @@ class TemplateParser { $key = $cache->makeKey( 'template', $templateName, $fastHash ); $code = $this->forceRecompile ? null : $cache->get( $key ); - if ( !$code ) { - $code = $this->compileForEval( $fileContents, $filename ); - - // Prefix the cached code with a keyed hash (64 hex chars) as an integrity check - $cache->set( $key, hash_hmac( 'sha256', $code, $secretKey ) . $code ); - } else { + if ( $code ) { // 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 the integrity check fails, don't use the cached code + // We'll update the invalid cache below + $code = null; } } + if ( !$code ) { + $code = $this->compileForEval( $fileContents, $filename ); + + // Prefix the cached code with a keyed hash (64 hex chars) as an integrity check + $cache->set( $key, hash_hmac( 'sha256', $code, $secretKey ) . $code ); + } // If there is no secret key available, don't use cache } else { $code = $this->compileForEval( $fileContents, $filename ); -- 2.20.1