
Python PoC and exploit chain for CVE-2026-82531: Smarty template cache poisoning via forged SmartyNocache markers leading to PHP code execution, with check, payload, and Docker lab.
Python 3 PoC for CVE-2026-82531 — smarty-php/smarty — code injection (CWE-94) via forged SmartyNocache markers in extends + template cache regeneration → RCE on cache include().
| Field | Value |
|---|---|
| CVE | CVE-2026-82531 |
| Product | Smarty PHP template engine |
| Affected | < 4.5.8; 5.0.0 – 5.8.4 |
| Fixed | 4.5.8, 5.8.5 |
| CWE | CWE-94 — Improper Control of Code Generation |
| CVSS 4.0 | 9.2 Critical (CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N) |
| CVSS 3.1 | 8.1 High |
| PoCbit catalog | https://pocbit.org/pocs/ |
| PoCbit page | https://pocbit.org/pocs/cve-2026-82531 |
| Verify marker | POCBIT-82531-OK (base64 command output in HTTP body) |
| Advisories | GHSA-3w63-v7pm-cq9x |
Exploit focus: poc.py exploit runs warm → cache clear → poison (POST name=) → trigger; check, payload, Docker lab/ (Smarty 5.8.4). Outputs: hits.txt, exploited.txt.
Smarty compiles templates to PHP and may write cached output. When templates use extends: / block inheritance, the top-level compiled function can leave nocache_hash unset after a new PHP worker loads compiled files from disk.
During cache regeneration, Smarty_Internal_Runtime_UpdateCache builds a regex that splits “nocache” regions. A null hash produces an empty regex alternative, so attacker-controlled assign() data can forge:
/*%%SmartyNocache:%%*/ <?php ... ?> /*/%%SmartyNocache:%%*/
That block is copied verbatim into the generated cache PHP file (normal PHP-tag neutralization is skipped). The next request that includes the cache file executes the injected PHP → remote code execution.
exploit subcommand)| Phase | Action |
|---|---|
| 1 Warm | Benign name=world → compile + initial cache |
| 2 Clear | Remove cache files only (compiled templates stay) — lab exposes ?lab_clear_cache=1 |
| 3 Poison | name=<forged SmartyNocache + PHP shell_exec> → poisoned cache written |
| 4 Trigger | Benign name=benign → include() runs injected PHP; body contains POCBIT-82531-OK:<base64> |
Real targets need: caching on, extends templates, user-controlled assign, cache miss while compile dir is populated (TTL, restart, or admin flush).
Smarty extends: / kalıtım + önbellek kullanan uygulamalarda, nocache_hash null iken saldırganın assign ettiği sahte SmartyNocache bloğu cache PHP dosyasına ham PHP olarak yazılır; sonraki istekte include → RCE. PoCbit paketi: Docker lab + exploit tam zincir.
cd CVE-2026-82531
pip install -r requirements.txt
docker compose up --build -d
python poc.py check http://127.0.0.1:8088
python poc.py exploit --url http://127.0.0.1:8088 -c "id"
python poc.py exploit -i targets.example.txt -w 10 -c id
python poc.py payload -c "id"
After patching: delete/regenerate all template cache files.
Authorized security research and systems you own or have permission to test only.
NocacheHashInjectionTest.php (Smarty 5.8.5)CVE-2026-82531 — Smarty <4.5.8 / 5.x<5.8.5 cache-poisoning RCE (CWE-94, CVSS 4.0 9.2 AT:P). PoCbit PoC: extends+inheritance null nocache_hash → forged SmartyNocache marker in assign() → PHP in cache include. check/exploit/payload, Docker lab 5.8.4, hits.txt & exploited.txt. Fix 4.5.8 / 5.8.5. Marker POCBIT-82531-OK. https://pocbit.org/pocs/cve-2026-82531