CVE-2025-23211: How a Jinja2 SSTI Vulnerability Turns Recipes Into RCE

When you think about vulnerabilities in web applications, classics like SQL Injection or XSS probably come to mind. But some flaws are hidden in plain sight, and one of them is SSTI—Server-Side Template Injection. This type of bug doesn’t just let attackers mess with your page; it can turn a seemingly innocent field into a backdoor for remote code execution.

And since we’re talking about Tandoor Recipes, here’s the twist: sometimes, the most dangerous ingredient in your web app isn’t in the food—it’s in the code. In this article, we’ll explore the CVE-2025-23211 vulnerability found in Tandoor Recipes, understand how SSTI works, and see why leaving your templates unchecked can cook up serious trouble for your server.

What Is a Template in Web Applications?

Web templates are everywhere. Basically, they let developers build dynamic pages by mixing static HTML with dynamic content—like showing a user’s name, order status, or your favorite recipe ingredients. Template engines (such as Jinja2 for Python, Twig for PHP, or Handlebars for Node.js) take these templates and user-supplied data, then render the final HTML sent to your browser.

For example, in Jinja2, a developer might use:

jinjaCopiarEditarHello, {{ user_name }}!

The template engine replaces the placeholder with the actual value at runtime.

What Is SSTI and Why Does It Happen?

SSTI (Server-Side Template Injection) happens when user-controlled input is inserted directly into a template, and the template engine processes it as code—not just as plain text. If an attacker can inject something like {{ 7*7 }} and the server accepts and interprets it, that’s SSTI.

But why does this happen in the first place? Usually, it’s because developers:

  • Trust user input too much—assuming some fields are “harmless” and don’t need validation.
  • Directly concatenate or inject raw user data into templates, without sanitizing or escaping it.
  • Use powerful template engines that allow access to internal functions and even system commands.

The result: a field that was meant to show a simple instruction or message can become an entry point for code execution on the server. That’s a serious risk.

Risks for Applications and Businesses

If an SSTI vulnerability is present, the risks go far beyond just “messing up the page”:

  • Remote Code Execution (RCE): Attackers can run any command as the server user. That’s total compromise.
  • Data Theft: Sensitive files, configuration data, environment variables, or even database credentials can be accessed and stolen.
  • Pivoting: An attacker could use the compromised server as a stepping stone to move deeper into your network.
  • Defacement or Sabotage: Content can be altered or deleted, or your service can be disrupted.
  • Regulatory Fines and Reputation Damage: A breach may trigger compliance penalties and serious damage to your company’s reputation.

In short, a single SSTI vulnerability can lead to severe financial, operational, and legal consequences for your business—impacting everything from service availability to user privacy.

Proof of Concept (PoC)

Let’s see this in action using the real CVE-2025-23211 vulnerability found in Tandoor Recipes.
Tandoor Recipes is an open-source web application designed to help users manage, share, and organize their favorite cooking recipes online. Under the hood, it’s a typical Python web app using the popular Jinja2 template engine.

For this PoC, we’ll run a vulnerable version of Tandoor (v1.5.23) locally using Docker, then inject a Jinja2 payload that executes system commands.

The vulnerable input is the “Instructions” one:

This input allows an attacker run a O.S command by inserting this payload:

{{()|attr('\x5f\x5fclass\x5f\x5f')|attr('\x5f\x5fbase\x5f\x5f')|attr('\x5f\x5fsubclasses\x5f\x5f')()|attr('\x5f\x5fgetitem\x5f\x5f')(418)('id',shell=True,stdout=-1)|attr('communicate')()|attr('\x5f\x5fgetitem\x5f\x5f')(0)|attr('decode')('utf-8')}}

That will runs the “id” command by Linux. But it’s could be a command for a reverse shell, allowing remote acces to the application server.

On save and view the recipe:

We got a RCE:

Conclusion

SSTI vulnerabilities are the kind of threat that can turn a small coding oversight into a full-blown server compromise. The CVE-2025-23211 case in Tandoor Recipes shows how dangerous it can be to trust user input in template engines. Always sanitize and validate input, keep dependencies up-to-date, and review your code for template injection risks—because attackers are always looking for these “hidden” entry points.

When it comes to security, never leave your application’s recipe open for anyone to season. One wrong ingredient could spoil the whole dish—and in this case, that dish is your entire server.


Comentários

One response to “CVE-2025-23211: How a Jinja2 SSTI Vulnerability Turns Recipes Into RCE”

  1. good.

Leave a Reply

Discover more from VSec

Subscribe now to keep reading and get access to the full archive.

Continue reading