CVE-2026-62996: Smarty Security stream restriction bypass through stream: resource

Published Aug 7, 2026
·
Updated

smarty/smarty version 5.8.0 can read local files through PHP stream wrappers even when Smarty Security is enabled and all streams are disabled with Security::$streams = null.

The bypass uses Smarty's built-in stream: resource type. A template such as:

smarty {include file="stream:php://filter/read=convert.base64-encode/resource=/tmp/secret.tpl"}

is handled as Smarty resource type stream, so the security check that would normally reject the underlying php wrapper is not applied. StreamPlugin then opens the nested php://filter/... URI directly.

For comparison, the direct resource:

smarty {include file="php://filter/read=convert.base64-encode/resource=/tmp/secret.tpl"}

is blocked with stream 'php' not allowed by security setting.

Affected package:

- Ecosystem: Packagist / Composer - Package: smarty/smarty - Confirmed affected version: 5.8.0 - Confirmed source reference from Composer lock: 78d259d3b971c59a0cd719c270cc5cbb740c36a7 - Current stable version on Packagist at review time: v5.8.0 - Packagist usage at review time: 41,113,855 total downloads and 840,604 monthly downloads

Relevant code paths:

- Smarty\Resource\BasePlugin::load(...) - Smarty\Resource\StreamPlugin::getContent(...) - Smarty\Security::isTrustedStream(...)

BasePlugin::load() maps the built-in resource name stream directly to StreamPlugin before the code path that checks PHP stream wrappers with streamgetwrappers() and Security::isTrustedStream($type). StreamPlugin::getContent() later calls fopen($filepath, 'r+') on the nested URI when the resource name contains ://.

Preconditions:

An application must render templates that are not fully trusted while relying on Smarty Security to restrict local files and PHP stream wrappers. The PoC sets:

php $smarty->enableSecurity(); $smarty->securitypolicy->streams = null;

Local reproduction:

The PoC creates a disposable template directory and a separate outside directory. It enables Smarty Security, disables all streams, and then compares three includes:

1. ../outside/secret.tpl to confirm the ordinary trusted-directory boundary is enforced. 2. php://filter/... to confirm direct PHP streams are blocked by Security::$streams = null. 3. stream:php://filter/... to show the built-in stream: resource bypasses the same restriction and reads the outside file.

Run:

shell php -d displayerrors=1 poc.php

Observed sanitized output:

text package=smarty/smarty installedversion=v5.8.0 templatedir=<tmp>/templates outsidetemplate=<tmp>/outside/secret.tpl plaindotdotinclude=BLOCKED:Smarty\Exception:Smarty Security: not trusted file path '<tmp>/outside/secret.tpl' directphpfilterinclude=BLOCKED:Smarty\Exception:stream 'php' not allowed by security setting streamphpfilterinclude=OK:U01BUlRZX1NUUkVBTV9XUkFQUEVSX1NFQ1VSSVRZX0VTQ0FQRQ== expectedbase64=U01BUlRZX1NUUkVBTV9XUkFQUEVSX1NFQ1VSSVRZX0VTQ0FQRQ==

The plaindotdotinclude line shows the directory boundary is enforced for ordinary traversal. The directphpfilterinclude line shows the same policy rejects php://filter when used directly. The streamphpfilterinclude line shows that wrapping the same URI in Smarty's stream: resource bypasses that restriction and reads the outside file.

Impact:

A template author can bypass Smarty Security stream restrictions and read local files that are readable by the PHP process. With php://filter, file contents can be base64 encoded and rendered back through the template. This bypasses both the intended Security::$streams = null restriction and the normal trusted-template-directory check that blocks ../ traversal.

Duplicate checks:

- OSV query for Packagist/smarty/smarty version 5.8.0 returned no vulnerabilities. - GitHub advisory query for ecosystem=composer and affects=smarty/smarty returned historical Smarty advisories, including sandbox escapes, PHP code injection, XSS, and older path traversal issues. The listed path traversal advisories affect older versions and do not describe this current stream:php://filter resource-wrapper bypass in 5.8.0. - GitHub issue search in smarty-php/smarty for stream:php://filter returned zero results. - Public searches for Smarty StreamPlugin php://filter and smarty/smarty isTrustedStream stream: did not identify a clear public duplicate during triage.

Suggested remediation:

When resolving the built-in stream: resource, parse and validate the nested URI scheme before opening it. For example, stream:php://filter/... should call Security::isTrustedStream('php'), and Security::$streams = null should block the resource before StreamPlugin::getContent() reaches fopen().

It would also be safer for StreamPlugin to reject nested stream wrappers by default unless the underlying wrapper is explicitly allowed by the active security policy.

Other sources

Smarty is a template engine for PHP, facilitating the separation of presentation (HTML/CSS) from application logic. From 5.0.0 until 5.8.4, Smarty's stream: resource-name handling does not adequately restrict which PHP stream wrappers and filter chains can be referenced from a template, allowing a php://filter-wrapped resource name to be used to read the contents of arbitrary local files accessible to the PHP process. An attacker able to author or influence a template's resource reference could exploit this to disclose sensitive file contents outside the intended template/config scope. This issue is fixed in version 5.8.4.

MITRE

Affected Software

3 affected componentsFixes available
Smarty smarty>=5.0.0<5.8.4
Smarty smarty=5.8.4
composer/smarty/smarty>=5.0.0<5.8.4
5.8.4

Remediation

Recommended actions to resolve this vulnerability, in priority order.

  1. Upgrade

    Upgrade composer/smarty/smarty to a version that resolves this vulnerability.

    Fixed in 5.8.4
  2. Upgrade

    Upgrade smarty/smarty to a version that resolves this vulnerability.

    Fixed in 5.8.4

Event History

Aug 7, 2026
CVE Published
via MITRE·03:04 PM
Data Sourced
via MITRE·03:04 PM
DescriptionWeakness
Advisory Published
via GitHub·03:10 PM
Data Sourced
via GitHub·03:10 PM
DescriptionWeaknessAffected Software
Free Weekly Intel

Don't miss critical vulnerabilities

Join thousands of security professionals who receive our weekly digest of trending CVEs, zero-days, and exploited vulnerabilities.

No spam. Unsubscribe anytime.

Frequently Asked Questions

1

What is the severity of CVE-2026-62996?

The severity of CVE-2026-62996 is categorized as risk 52.

2

How do I fix CVE-2026-62996?

To remediate CVE-2026-62996, upgrade to the latest version of Smarty that addresses this stream restriction bypass.

3

What vulnerabilities are associated with CVE-2026-62996?

CVE-2026-62996 is associated with path traversal, XSS, and code injection vulnerabilities.

4

How does CVE-2026-62996 exploit affected systems?

CVE-2026-62996 exploits affected systems by allowing unauthorized file access through PHP stream wrappers despite Smarty Security restrictions.

5

Which versions of Smarty are affected by CVE-2026-62996?

CVE-2026-62996 affects Smarty version 5.8.0 and potentially earlier versions.

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203