High severityGHSA Advisory· Published May 11, 2026· Updated May 11, 2026
Yii 2: Local file inclusion via view parameter name collision
CVE-2026-39850
Description
The core view rendering method View::renderPhpFile() calls extract($_params_, EXTR_OVERWRITE) before the require statement that includes the view file. A caller-controlled parameter named _file_ in the $params array overwrites the internal local variable that specifies which file is included — enabling a Local File Inclusion primitive.
Impact
- Local File Inclusion (arbitrary file read via non-PHP files)
- Potential RCE if attacker can write PHP files via a separate primitive
- Information disclosure
Patches
2.0.55
Workarounds
No.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
yiisoft/yii2Packagist | < 2.0.55 | 2.0.55 |
Affected products
1Patches
1109878b491dbFix: CVE-2026-39850, Isolate internal variables in `View::renderPhpFile()` and `ErrorHandler::renderFile()` to prevent parameter collisions from overriding included file paths
5 files changed · +54 −4
framework/base/View.php+5 −2 modified@@ -341,11 +341,14 @@ public function afterRender($viewFile, $params, &$output) public function renderPhpFile($_file_, $_params_ = []) { $_obInitialLevel_ = ob_get_level(); + $_renderer_ = function () { + extract(func_get_arg(1), EXTR_OVERWRITE); + require func_get_arg(0); + }; ob_start(); ob_implicit_flush(false); - extract($_params_, EXTR_OVERWRITE); try { - require $_file_; + call_user_func_array($_renderer_, [$_file_, $_params_]); return ob_get_clean(); } catch (\Exception $e) { while (ob_get_level() > $_obInitialLevel_) {
framework/CHANGELOG.md+1 −0 modified@@ -4,6 +4,7 @@ Yii Framework 2 Change Log 2.0.55 under development ------------------------ +- Bug: CVE-2026-39850, Isolate internal variables in `View::renderPhpFile()` and `ErrorHandler::renderFile()` to prevent parameter collisions from overriding included file paths (samdark) - Bug #20705: Replace `$this` with `self` in generics in Psalm annotations (mspirkov) - Bug #20715: Adjust `JSON` helper error message assertions for `PHP 8.6` compatibility in `JsonTest` class (terabytesoftw) - Enh #20714: Allow overriding the `yii\grid\GridView`'s default `filterSelector`, allow using `Closure`s for `filterSelector` (chriscpty)
framework/web/ErrorHandler.php+5 −2 modified@@ -259,10 +259,13 @@ public function renderFile($_file_, $_params_) { $_params_['handler'] = $this; if ($this->exception instanceof ErrorException || !Yii::$app->has('view')) { + $_renderer_ = function () { + extract(func_get_arg(1), EXTR_OVERWRITE); + require Yii::getAlias(func_get_arg(0)); + }; ob_start(); ob_implicit_flush(false); - extract($_params_, EXTR_OVERWRITE); - require Yii::getAlias($_file_); + call_user_func_array($_renderer_, [$_file_, $_params_]); return ob_get_clean(); }
tests/framework/base/ViewTest.php+13 −0 modified@@ -108,6 +108,19 @@ public function testRelativePathInView(): void $this->assertSame($subViewContent, $view->render('@testviews/base')); } + public function testRenderFileDoesNotAllowInternalFileOverride(): void + { + $view = new View(); + + $viewFile = $this->testViewPath . DIRECTORY_SEPARATOR . 'safe.php'; + file_put_contents($viewFile, '<?php echo "safe view";'); + + $secretFile = $this->testViewPath . DIRECTORY_SEPARATOR . 'secret.txt'; + file_put_contents($secretFile, 'secret data'); + + $this->assertSame('safe view', $view->renderFile($viewFile, ['_file_' => $secretFile])); + } + public function testAfterRender(): void { $view = new View();
tests/framework/web/ErrorHandlerTest.php+30 −0 modified@@ -10,6 +10,7 @@ use Exception; use yii\BaseYii; +use yii\base\ErrorException; use yii\web\Application; use Yii; use yii\web\NotFoundHttpException; @@ -178,6 +179,28 @@ public function testHtmlEncodeWithUnicodeSequence(): void $this->assertSame($expected, $handler->htmlEncode($text)); } + + public function testRenderFileDoesNotAllowInternalFileOverride(): void + { + $viewFile = tempnam(sys_get_temp_dir(), 'yii2-error-view-'); + $secretFile = tempnam(sys_get_temp_dir(), 'yii2-error-secret-'); + + file_put_contents($viewFile, '<?php echo "safe error view";'); + file_put_contents($secretFile, 'secret data'); + + try { + /** @var ErrorHandler $handler */ + $handler = Yii::$app->getErrorHandler(); + + $this->assertSame( + 'safe error view', + $handler->renderFileForException($viewFile, ['_file_' => $secretFile], new ErrorException('test')) + ); + } finally { + @unlink($viewFile); + @unlink($secretFile); + } + } } class ErrorHandler extends \yii\web\ErrorHandler @@ -189,4 +212,11 @@ protected function shouldRenderSimpleHtml() { return false; } + + public function renderFileForException($file, array $params, \Throwable $exception): string + { + $this->exception = $exception; + + return $this->renderFile($file, $params); + } }
Vulnerability mechanics
AI mechanics synthesis has not run for this CVE yet.
References
4News mentions
0No linked articles in our index yet.