Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-62996

CVE-2026-62996: Smarty Template Engine File Disclosure

CVE-2026-62996 is an information disclosure flaw in Smarty PHP template engine that allows attackers to read arbitrary local files through php://filter wrappers. This article covers technical details, affected versions, and mitigation.

Published:

CVE-2026-62996 Overview

CVE-2026-62996 is a path traversal vulnerability [CWE-22] in the Smarty template engine for PHP. Smarty separates HTML/CSS presentation from application logic and is widely used in PHP applications. Versions from 5.0.0 up to but not including 5.8.4 fail to adequately restrict which PHP stream wrappers and filter chains can be referenced from a template. An attacker able to author or influence a template's stream: resource reference can supply a php://filter-wrapped resource name to read arbitrary local files accessible to the PHP process. The issue is fixed in Smarty version 5.8.4.

Critical Impact

Attackers with the ability to control template resource references can disclose sensitive local file contents outside the intended template and configuration scope.

Affected Products

  • Smarty PHP template engine version 5.0.0 through 5.8.3
  • PHP applications embedding Smarty and permitting user influence over template resource names
  • Deployments using the stream: resource type without a restrictive security_policy

Discovery Timeline

  • 2026-08-07 - CVE-2026-62996 published to NVD
  • 2026-08-07 - Smarty releases version 5.8.4 addressing the issue
  • 2026-08-07 - Last updated in NVD database

Technical Details for CVE-2026-62996

Vulnerability Analysis

The vulnerability resides in Smarty's StreamPlugin resource handler, which processes templates referenced with a stream: prefix. When a template references a resource such as stream:php://filter/..., Smarty resolves the path and passes it directly to fopen(). The nested wrapper scheme (for example php) is never checked against the configured security policy. This allows chained PHP stream filters, including convert.base64-encode, to read arbitrary local files and return their contents to the calling template context. The result is unauthorized disclosure of file contents readable by the PHP process, such as configuration files, credentials, or source code.

Root Cause

In BasePlugin::load(), the built-in stream sysplugin is matched before stream_get_wrappers() and isTrustedStream() are evaluated. Because the outer wrapper is stream, the inner wrapper carried in the resolved filepath is never validated. Setting Security::$streams = null therefore does not block nested wrappers such as php://filter.

Attack Vector

Exploitation requires an attacker to author or influence a template's resource name. The attacker crafts a resource reference such as stream:php://filter/convert.base64-encode/resource=/etc/passwd. Smarty rewrites the reference into a filepath and opens it with fopen(), streaming the filtered file contents back into the template output.

php
// Patch excerpt from src/Resource/StreamPlugin.php
// Source: https://github.com/smarty-php/smarty/commit/3c9f77a2e06ce319ae0092496af32cc8f3adc52e
$filepath = str_replace(':', '://', $source->getFullResourceName());

// Validate the underlying stream wrapper against the security policy.
// When the built-in "stream" resource type is used (e.g.
// stream:php://filter/...), BasePlugin::load() matches the "stream"
// sysplugin before the stream_get_wrappers()/isTrustedStream() check,
// so the nested wrapper ("php" here) is never validated. Parse the
// wrapper scheme from the resolved path and check it explicitly so that
// e.g. Security::$streams = null blocks it before fopen() (CWE-22/-441).
$smarty = $source->getSmarty();
if (is_object($smarty->security_policy) && ($_pos = strpos($filepath, '://')) !== false) {
    $smarty->security_policy->isTrustedStream(strtolower(substr($filepath, 0, $_pos)));
}

$t = '';
$fp = fopen($filepath, 'r+');
if ($fp) {
    while (!feof($fp) && ($current_line = fgets($fp)) !== false) {
        // ...
    }
}

The patch parses the wrapper scheme from the resolved path and explicitly calls isTrustedStream() on it before fopen() executes.

Detection Methods for CVE-2026-62996

Indicators of Compromise

  • Template resource strings containing stream:php://filter, stream:php://, or other nested wrapper schemes.
  • Web server or application logs showing template parameters that include convert.base64-encode/resource= or similar filter chains.
  • Unexpected file reads of sensitive files such as /etc/passwd, .env, or config.php originating from the PHP process during template rendering.

Detection Strategies

  • Inventory PHP applications and identify Smarty deployments with versions between 5.0.0 and 5.8.3 using composer.lock or vendor/smarty/smarty/CHANGELOG.md.
  • Perform static analysis to locate call sites where user-controllable input reaches Smarty template resource names, template inheritance, or {include} directives.
  • Search request logs and WAF telemetry for URL-encoded or plain occurrences of php://filter in parameters associated with template selection.

Monitoring Recommendations

  • Alert on PHP-FPM or Apache worker processes opening files outside the expected template directory tree.
  • Log Smarty exceptions and warnings, especially those emitted from Resource/StreamPlugin.php and the security policy layer.
  • Correlate template rendering events with subsequent outbound transfers of large or base64-encoded response bodies.

How to Mitigate CVE-2026-62996

Immediate Actions Required

  • Upgrade Smarty to version 5.8.4 or later across all affected applications.
  • Audit application code for locations where template resource names, template files, or {include} targets can be influenced by untrusted input.
  • Configure a Smarty Security_Policy and set $streams = null to disallow stream wrappers where they are not required.

Patch Information

The fix is available in Smarty GitHub Release v5.8.4 and merged via Pull Request #1195. Full technical context is documented in GitHub Security Advisory GHSA-rjhh-76wf-8xmw and the remediation commit.

Workarounds

  • Enforce a Smarty security policy that blocks the stream: resource type and any nested wrappers not required by the application.
  • Filter or reject user-supplied strings containing ://, php:, or filter/ before passing them to any Smarty API that resolves template resources.
  • Restrict the PHP process's filesystem access using open_basedir and least-privilege file permissions to limit the blast radius of arbitrary file reads.
bash
# Upgrade Smarty via Composer
composer require smarty/smarty:^5.8.4
composer update smarty/smarty

# PHP configuration hardening (php.ini)
allow_url_fopen = Off
allow_url_include = Off
open_basedir = /var/www/app:/tmp

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.