CVE-2025-24374 - Twig Templating Engine "??" Operator Output Escaping Vulnerability Explained

On February 2025, a new security vulnerability was discovered and disclosed in Twig, the popular template engine for PHP. This flaw, now tracked as CVE-2025-24374, could put your web applications at risk of Cross-Site Scripting (XSS) when using the null coalescing operator (??) in your Twig templates. Let's look at what happened, who is affected, and how to stay secure—all explained in simple terms.

What Is the Vulnerability? (CVE-2025-24374)

Twig is widely used in PHP projects (especially with frameworks like Symfony) to safely render HTML. By default, it automatically "escapes" output so that user input doesn't result in malicious code being injected into web pages. However, a recent bug emerged: when the "??" operator is used, Twig failed to escape the value on the left side of this operator, leaving it open for XSS attacks.

Here's a simple code example

{{ user.username ?? 'Guest' }}

Intended behavior: Both user.username and "Guest" should be *escaped*, so that anything suspicious—like <script> tags—would not run.

Vulnerable behavior (before 3.19.): Only "Guest" is always escaped, while user.username is *not* escaped when shown, if present! So a malicious username like "><script>alert(1)</script> could be rendered as actual HTML code.

#### Reference: GitHub Security Advisory

Breaking Down the "??" Operator in Twig

The ?? operator is called the null coalescing operator. It's commonly used to display a default value if the left value is not set or is null:

{{ user.name ?? 'Anonymous' }}

If it doesn't exist, display "Anonymous".

This is standard across many template engines and makes writing readable templates much easier.

The Exploit: What Could Happen?

If you use the ?? operator to display user-controlled data, and escape is not applied, an attacker could register with a name like:

<script>alert('XSS!')</script>

When your page renders

{{ user.username ?? 'Anonymous' }}

That script would actually run in the victim's browser if the user is logged in, causing an XSS attack.

Assuming the vulnerable Twig version (<3.19.) and autoescaping is enabled

User input:
user.username = '<img src=x onerror=alert(1)>'

Twig template

{{ user.username ?? 'Guest' }}

Rendered HTML (in vulnerable versions)

<img src=x onerror=alert(1)>

Effect:
The malicious script would execute as soon as the image fails to load.

Projects relying on Twig’s default escaping for XSS safety

If your templates never use the ?? operator, or only use safe, internal data on its left side, you may not be affected—but it’s still recommended to upgrade.

Solution: Update to Twig 3.19. or higher

Twig maintainers released v3.19. which patches this security issue. The update ensures *both* sides of the ?? operator are correctly escaped.

To update with Composer

composer update twig/twig

Or, for a specific version

composer require twig/twig:"^3.19."

Patch Notes

Refer to the release changelog for more details.

Be careful with output: Even with built-in escaping, be wary of rendering user input.

- Review template code: Look for places using ??, and make sure no unchecked user data can be rendered.

References

- Twig Official Site
- Twig Release v3.19.
- Twig Changelog
- GitHub Advisory (Placeholder)

Final Thoughts

CVE-2025-24374 reminds us that even trusted template engines like Twig can have subtle issues with escaping. Always keep your dependencies up to date and follow security best practices when dealing with user input.

If you manage a PHP website or app using Twig, make sure to check your version and update as soon as possible to avoid this (and potential future) vulnerabilities.

Stay safe, patch smart, and keep shipping secure code!

Timeline

Published on: 01/29/2025 16:15:44 UTC