# Server-side template injection via argv/config

Request data reaching argv, config paths, or template expressions evaluated server-side

_Area: Web injection and code execution. Seen in 2 disclosed reports; latest 2025-02-12. Updated 2026-10-24._

## How it works
Code assumes a value is trusted because of where it normally comes from: CLI flags, a config path, or a template attribute. When request data can populate that same value, the assumption breaks. The server then treats attacker input as a flag, a file path, or a template expression and evaluates it. In [E1](https://bugbountylibrary.com/r/blog%3Aassetnote-io-resources-research-how-an-obscure-php-footgun-led-to-rce-in-craft-cms.md) the app read `$_SERVER['argv']` to detect CLI without checking `PHP_SAPI`; with `register_argc_argv=On`, query-string tokens became CLI flags, letting an attacker set `--templatesPath` to a remote URL and inject Twig. In [E2](https://bugbountylibrary.com/r/blog%3Agithub-com-sudistark-bb-writeups-blob-main-2023-cve-2023-33733-rce-via-htmli-in-reportlab-md.md) a user comment was interpolated into a ReportLab `<para><font color=...>` template, and the color evaluator ran the attribute value. In [E4](https://bugbountylibrary.com/r/h1%3A858874.md) a Less/CSS editor ran with `javascriptEnabled`, so backtick expressions and `@plugin` imports executed JavaScript.

## Where it shows up
- Code branching on `isset($_SERVER['argv'])` or `empty($_SERVER['argv'])` to detect CLI, with no `PHP_SAPI` check [E1](https://bugbountylibrary.com/r/blog%3Aassetnote-io-resources-research-how-an-obscure-php-footgun-led-to-rce-in-craft-cms.md)
- `register_argc_argv=On` in Docker or default configs [E1](https://bugbountylibrary.com/r/blog%3Aassetnote-io-resources-research-how-an-obscure-php-footgun-led-to-rce-in-craft-cms.md)
- CLI option readers (`App::cliOption`) that accept paths or template directories [E1](https://bugbountylibrary.com/r/blog%3Aassetnote-io-resources-research-how-an-obscure-php-footgun-led-to-rce-in-craft-cms.md)
- User fields interpolated into markup or template strings before a parser evaluates attributes [E2](https://bugbountylibrary.com/r/blog%3Agithub-com-sudistark-bb-writeups-blob-main-2023-cve-2023-33733-rce-via-htmli-in-reportlab-md.md)
- CSS preprocessors (Less/Sass) exposed to users with JS evaluation or remote `@plugin`/`@import` [E4](https://bugbountylibrary.com/r/h1%3A858874.md)
- Sanitizer post-walks that skip containers the walker cannot descend into (shadow roots, template content) [E3](https://bugbountylibrary.com/r/ghsa%3AGHSA-cg2g-xh64-v4q7.md)

## How to review
Trace every request-controlled value into argv, config paths, template paths, and template expressions. The invariant: no request data may select a file path, flag, or expression that is evaluated server-side. Confirm CLI detection checks `PHP_SAPI === 'cli'`, not just argv presence [E1](https://bugbountylibrary.com/r/blog%3Aassetnote-io-resources-research-how-an-obscure-php-footgun-led-to-rce-in-craft-cms.md). For template engines, confirm user fields are passed as data, never concatenated into template source or evaluated attributes [E2](https://bugbountylibrary.com/r/blog%3Agithub-com-sudistark-bb-writeups-blob-main-2023-cve-2023-33733-rce-via-htmli-in-reportlab-md.md). For preprocessors, confirm JS evaluation and remote plugin loading are disabled [E4](https://bugbountylibrary.com/r/h1%3A858874.md). For sanitizers, confirm the scrub recurses into every container the walker can reach, including shadow roots [E3](https://bugbountylibrary.com/r/ghsa%3AGHSA-cg2g-xh64-v4q7.md).

## Variants seen
- CLI flag injection via query string into argv, selecting a remote template path [E1](https://bugbountylibrary.com/r/blog%3Aassetnote-io-resources-research-how-an-obscure-php-footgun-led-to-rce-in-craft-cms.md)
- Attribute-value eval inside a document-generation template [E2](https://bugbountylibrary.com/r/blog%3Agithub-com-sudistark-bb-writeups-blob-main-2023-cve-2023-33733-rce-via-htmli-in-reportlab-md.md)
- Preprocessor inline-JS and remote plugin execution [E4](https://bugbountylibrary.com/r/h1%3A858874.md)
- Sanitizer bypass where split expressions re-merge in an unscanned shadow root [E3](https://bugbountylibrary.com/r/ghsa%3AGHSA-cg2g-xh64-v4q7.md)

## Impact and severity
Led to unauthenticated RCE [E1](https://bugbountylibrary.com/r/blog%3Aassetnote-io-resources-research-how-an-obscure-php-footgun-led-to-rce-in-craft-cms.md), RCE plus cloud metadata theft [E2](https://bugbountylibrary.com/r/blog%3Agithub-com-sudistark-bb-writeups-blob-main-2023-cve-2023-33733-rce-via-htmli-in-reportlab-md.md), stored XSS against privileged editors [E4](https://bugbountylibrary.com/r/h1%3A858874.md), and sanitizer bypass enabling downstream template evaluation [E3](https://bugbountylibrary.com/r/ghsa%3AGHSA-cg2g-xh64-v4q7.md). Severity rises when the path is unauthenticated, when remote URLs are fetchable, and when the evaluated context has filesystem or network reach.

## Evidence
- E1: https://bugbountylibrary.com/r/blog%3Aassetnote-io-resources-research-how-an-obscure-php-footgun-led-to-rce-in-craft-cms.md
- E2: https://bugbountylibrary.com/r/blog%3Agithub-com-sudistark-bb-writeups-blob-main-2023-cve-2023-33733-rce-via-htmli-in-reportlab-md.md
- E3: https://bugbountylibrary.com/r/ghsa%3AGHSA-cg2g-xh64-v4q7.md
- E4: https://bugbountylibrary.com/r/h1%3A858874.md
