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

CVE-2026-82531: Smarty Template Engine RCE Vulnerability

CVE-2026-82531 is a code injection flaw in Smarty template engine allowing attackers to execute arbitrary PHP code through forged SmartyNocache markers. This post covers technical details, affected versions, impact, and mitigation.

Published:

CVE-2026-82531 Overview

CVE-2026-82531 is a code injection vulnerability [CWE-94] in the Smarty PHP template engine affecting versions before 4.5.8 and 5.x before 5.8.5. The flaw resides in Smarty's cache regeneration logic for templates using extends: or multi-component inheritance. During inheritance compilation, the top-level nocache_hash is never restored and remains null, which breaks the regex used to isolate non-cacheable sections. Attackers who control assigned template data can inject a forged SmartyNocache marker that is written verbatim into the regenerated PHP cache file. When the application next includes that cache file, arbitrary PHP executes, yielding remote code execution on the server.

Critical Impact

Attacker-controlled template data can achieve unauthenticated remote PHP code execution through cache poisoning of inherited Smarty templates.

Affected Products

  • Smarty PHP template engine versions prior to 4.5.8
  • Smarty PHP template engine 5.x versions prior to 5.8.5
  • Any PHP application rendering extends: or multi-component inheritance templates with attacker-influenced assigned data

Discovery Timeline

  • 2026-10-06 - CVE-2026-82531 published to NVD
  • 2026-10-06 - Last updated in NVD database
  • 2026-10-06 - Fixes released as Smarty v4.5.8 and v5.8.5

Technical Details for CVE-2026-82531

Vulnerability Analysis

Smarty caches compiled templates as PHP files and uses a per-template nocache_hash to delimit sections that must execute at render time rather than being frozen into the cache. The cache writer builds a regex of known hashes and splits captured output into cacheable text and nocache blocks, neutralizing PHP tags in the cacheable portions. In templates compiled through the extends: inheritance path, the top-level unifunc never restores its nocache_hash, leaving the property null when writeCachedContent() executes.

The regex ends up containing an empty alternative such as (realhash|), which matches zero-width positions throughout the attacker-controlled output. Everything between those matches is treated as legitimate nocache content and copied verbatim, bypassing the PHP-tag sanitization that would otherwise strip <?php constructs. On the next include of the cache file, PHP interprets and executes the injected payload.

Root Cause

The root cause is a missing state restoration during inheritance compilation combined with insufficient defensive validation in Smarty_Internal_Runtime_UpdateCache and Template\Cached. Using the null nocache_hash as an array offset produces an empty regex alternative, which the cache splitter treats as a valid match and skips the PHP-tag neutralization pass.

Attack Vector

Exploitation requires an application that renders a Smarty template using inheritance ({extends} or multi-component), caching enabled, and at least one assigned variable whose value is attacker-influenced and emitted into the output. The attacker supplies a payload containing a forged SmartyNocache marker surrounding PHP code. Smarty writes the payload into the cache file, and the next request that includes the cache triggers code execution in the web server's PHP context.

php
// Vendor fix in libs/sysplugins/smarty_internal_runtime_updatecache.php
$php_pattern = '/(<%|%>|<\?php|<\?|\?>|<script\s+language\s*=\s*["\']?\s*php\s*["\']?\s*>)/';
$content = ob_get_clean();
$hash_array = $cached->hashes;
// Only fold in the top-level nocache hash when it is actually set. A template
// compiled through the inheritance/component path produces a top-level unifunc
// that never restores its nocache_hash, leaving it null here. An empty hash
// would produce an empty alternative "(realhash|)" in the pattern below,
// letting attacker-controlled output forge a nocache marker whose raw content
// is copied verbatim into the cache file (CWE-94 code injection).
if ((string) $_template->compiled->nocache_hash !== '') {
    $hash_array[ $_template->compiled->nocache_hash ] = true;
}
// Defensive: never allow an empty hash (hence an empty regex alternative).
$hash_array = array_filter(array_keys($hash_array), function ($hash) {
    return (string) $hash !== '';
});
$_template->cached->has_nocache_code = false;
if ($hash_array === array()) {
    // No known nocache hashes: treat the whole buffer as ordinary output.
    $cache_split = array($content);
    $cache_parts = array();
}
// Source: https://github.com/smarty-php/smarty/commit/1cba51cb813563eb61d963c83d28cd59f26b858d

Detection Methods for CVE-2026-82531

Indicators of Compromise

  • Smarty cache files under the configured cache_dir containing <?php sequences outside expected template compilation output.
  • Unexpected modification times on cache artifacts for templates that use {extends} or component inheritance.
  • Web application logs showing requests whose parameters embed the literal string SmartyNocache or related marker tokens.
  • PHP-FPM or Apache child processes spawning shells or outbound network connections from the cache_dir include path.

Detection Strategies

  • Inventory deployed Smarty versions and flag any installation below 4.5.8 (4.x branch) or 5.8.5 (5.x branch).
  • Statically scan generated cache files for PHP tags adjacent to user-controlled strings or malformed nocache delimiters.
  • Instrument the application to log the resolved nocache_hash during cache writes and alert when the value is null for inherited templates.

Monitoring Recommendations

  • Monitor the Smarty cache directory for file writes followed immediately by includes of the same file.
  • Alert on PHP interpreter processes executing system binaries such as sh, bash, curl, or wget when the parent context is a web request.
  • Correlate egress connections from web tier hosts with recent template rendering activity to surface post-exploitation callbacks.

How to Mitigate CVE-2026-82531

Immediate Actions Required

  • Upgrade Smarty to 4.5.8 or 5.8.5 or later on all production and non-production hosts.
  • Invalidate and delete existing compiled template and cache directories to purge any previously poisoned artifacts.
  • Audit application code paths that pass user-controlled data into Smarty assign() calls where inherited templates render that data.

Patch Information

The maintainers published fixes in commits 1cba51c and c0fdd48, released as Smarty v4.5.8 and Smarty v5.8.5. The patch skips folding a null top-level nocache_hash into the regex, filters empty hash entries, and treats the output buffer as ordinary content when no legitimate nocache hashes exist. See the GitHub Security Advisory GHSA-3w63-v7pm-cq9x and the VulnCheck Advisory for Smarty for additional detail.

Workarounds

  • Disable template caching ($smarty->caching = Smarty::CACHING_OFF) until patched versions are deployed where feasible.
  • Avoid passing untrusted or user-influenced strings directly to templates that use {extends} or multi-component inheritance.
  • Restrict filesystem permissions on the Smarty cache_dir so that only the application user can write, and monitor read/execute operations.
bash
# Upgrade via Composer and purge compiled artifacts
composer require smarty/smarty:^5.8.5
# or for the 4.x branch
composer require smarty/smarty:^4.5.8

# Clear compiled and cached templates after upgrade
rm -rf templates_c/* cache/*

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

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.