X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2FTemplateParser.php;h=2759ff9baa8d9b91240e061dd9939916324f3c85;hb=42ba9ea516beb06969bd3e579aa506821629ecb8;hp=470a75c4b9820878bf81b31b05de325960c2b1a6;hpb=e968a1f431ad058dcb14adb2757bde5664b99a79;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/TemplateParser.php b/includes/TemplateParser.php index 470a75c4b9..2759ff9baa 100644 --- a/includes/TemplateParser.php +++ b/includes/TemplateParser.php @@ -54,18 +54,11 @@ class TemplateParser { * @throws UnexpectedValueException If $templateName attempts upwards directory traversal */ protected function getTemplateFilename( $templateName ) { - // Prevent upwards directory traversal using same methods as Title::secureAndSplit + // Prevent path traversal. Based on Language::isValidCode(). + // This is for paranoia. The $templateName should never come from + // untrusted input. if ( - strpos( $templateName, '.' ) !== false && - ( - $templateName === '.' || $templateName === '..' || - strpos( $templateName, './' ) === 0 || - strpos( $templateName, '../' ) === 0 || - strpos( $templateName, '/./' ) !== false || - strpos( $templateName, '/../' ) !== false || - substr( $templateName, -2 ) === '/.' || - substr( $templateName, -3 ) === '/..' - ) + strcspn( $templateName, ":/\\\000&<>'\"%" ) !== strlen( $templateName ) ) { throw new UnexpectedValueException( "Malformed \$templateName: $templateName" ); } @@ -109,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 );