CVE-2026-62993 Overview
CVE-2026-62993 is a Server-Side Request Forgery (SSRF) vulnerability [CWE-918] in Smarty, a PHP template engine that separates presentation from application logic. The flaw exists in the {fetch} handler within libs/plugins/function.fetch.php and src/FunctionHandler/Fetch.php. When a security policy is active, Security::isTrustedUri() validates only the initial remote URL against trusted_uri. Because file_get_contents() follows HTTP redirects by default, an attacker with an open redirect on a trusted host can redirect the request to attacker-chosen internal endpoints. The issue is fixed in Smarty 4.5.7 and 5.8.2.
Critical Impact
Attackers can bypass the trusted_uri allowlist and reach internal services, cloud metadata endpoints, or other non-public resources via server-side request forgery.
Affected Products
- Smarty template engine versions prior to 4.5.7 (4.x release line)
- Smarty template engine versions prior to 5.8.2 (5.x release line)
- PHP applications using Smarty {fetch} with an active Security policy
Discovery Timeline
- 2026-08-31 - CVE-2026-62993 published to NVD
- 2026-09-02 - Last updated in NVD database
Technical Details for CVE-2026-62993
Vulnerability Analysis
The vulnerability resides in Smarty's {fetch} plugin, which retrieves remote resources for template inclusion. When a Security policy is enabled, Smarty calls Security::isTrustedUri() to validate that the requested URL matches the configured trusted_uri allowlist. This validation runs once against the initial URL supplied by the application.
After passing validation, Smarty invokes file_get_contents() to retrieve the remote resource. PHP's default HTTP stream wrapper follows Location headers on 3xx responses. An attacker who can influence the fetch target and identify an open redirect on a trusted host can chain the request to an unrelated internal endpoint. The redirect target never re-enters isTrustedUri(), allowing the SSRF to bypass the allowlist entirely.
Root Cause
The root cause is a time-of-check to time-of-use (TOCTOU) mismatch between URL validation and URL retrieval. isTrustedUri() inspects only the caller-supplied URL, while the underlying transport (file_get_contents() over HTTP/HTTPS) silently follows redirects. Smarty did not pass a stream context restricting follow_location or max_redirects, leaving the security boundary incomplete.
Attack Vector
Exploitation requires the target application to (1) enable a Smarty Security policy with a trusted_uri allowlist, (2) allow an attacker to influence the file parameter passed to {fetch}, and (3) have at least one trusted host that exposes an open redirect. The attacker requests a URL on the trusted host that redirects to an internal target such as http://169.254.169.254/latest/meta-data/ or http://localhost:8080/admin. Smarty follows the redirect and returns the response content into the template rendering pipeline.
// Security patch in src/FunctionHandler/Fetch.php
// Stops {fetch} from following redirects past trusted_uri (CWE-918)
} else {
if ($protocol && isset($template->getSmarty()->security_policy)) {
// Remote resource (e.g. https://) reached through file_get_contents().
// isTrustedUri() only validates the initial URL, but file_get_contents()
// follows redirects by default, so an open redirect on an otherwise
// trusted host could be used to reach a non-trusted target (SSRF).
// Disable redirect-following while a security policy is in effect.
$context = stream_context_create([
'http' => [
'follow_location' => 0,
'max_redirects' => 1,
],
]);
$content = @file_get_contents($params['file'], false, $context);
} else {
$content = @file_get_contents($params['file']);
}
if ($content === false) {
throw new Exception("{fetch} cannot read resource '" . $params['file'] . "'");
}
}
Source: Smarty commit 31e06fc
Detection Methods for CVE-2026-62993
Indicators of Compromise
- Outbound HTTP requests from PHP worker processes to internal RFC1918 ranges, 127.0.0.0/8, or link-local addresses such as 169.254.169.254.
- Web server access logs showing {fetch}-triggering parameters containing URLs to trusted hosts that return 3xx redirect responses.
- Unexpected retrieval of cloud instance metadata content appearing in rendered template output or application logs.
Detection Strategies
- Inventory PHP applications for Smarty installations below 4.5.7 or 5.8.2 using dependency scanning against composer.lock and vendor directories.
- Review application source for user-controlled input reaching the {fetch} tag or Smarty_Internal_Fetch calls without strict URL parsing.
- Instrument PHP with stream wrappers or auditing extensions to log every file_get_contents() call resolving to non-allowlisted destinations after redirects.
Monitoring Recommendations
- Alert on egress traffic from application servers to cloud metadata IPs (169.254.169.254, fd00:ec2::254) and internal management interfaces.
- Correlate web application firewall (WAF) logs for {fetch} parameter patterns against downstream redirect chains observed at the outbound proxy.
- Monitor PHP error logs for {fetch} cannot read resource exceptions, which may indicate probing activity following the patch.
How to Mitigate CVE-2026-62993
Immediate Actions Required
- Upgrade Smarty to version 4.5.7 (4.x branch) or 5.8.2 (5.x branch) via Composer.
- Audit templates and controllers for any use of {fetch} accepting user-influenced URLs and restrict input where possible.
- Remove or fix open redirects on hosts included in the Smarty trusted_uri allowlist.
Patch Information
The upstream fix is delivered in Smarty v4.5.7 and Smarty v5.8.2. The security advisory is tracked as GHSA-cq55-c7wv-pxmq. The patch creates an HTTP stream context that sets follow_location to 0 and max_redirects to 1 whenever a security_policy is active, forcing file_get_contents() to stop at the validated URL. See the pull request discussion for backport details.
Workarounds
- If patching is delayed, disable the {fetch} function in the active Smarty Security policy by removing it from $php_functions and $allowed_tags.
- Route outbound HTTP from PHP workers through an egress proxy that blocks connections to RFC1918, loopback, and cloud metadata address ranges.
- Replace {fetch} usage with an application-side HTTP client that explicitly disables redirect following and re-validates each hop against the allowlist.
# Upgrade Smarty via Composer to a fixed release
composer require smarty/smarty:^5.8.2
# Or for the 4.x branch
composer require smarty/smarty:^4.5.7
# Verify the installed version
php -r "require 'vendor/autoload.php'; echo Smarty\\Smarty::SMARTY_VERSION;"
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

