CVE-2026-51153
Stored XSS via task run logs: attacker‑controlled __log__ injects script into response.
- CVSS 5.4
- 79
- Input Validation and Sanitization
- Remote
Stored Cross-Site Scripting (XSS) in TaskRunHandler.post() in web/handlers/task.py in QD 20220208 through 20250803. When a task is run via /task/<taskid>/run, the handler renders task log content (logtmp) into the HTML response using Python % string formatting without HTML encoding. logtmp is populated from the exception object or from new_env.variables.__log__, which is attacker-controlled via the template extract_variables mechanism. A low-privileged authenticated attacker can create a crafted HAR template that extracts arbitrary HTML/JavaScript into the __log__ variable via the api://util/unicode endpoint. When a victim triggers the task run, the embedded script executes in the victim browser within the QD application context.
- CWE
- 79
- CVSS base score
- 5.4
- Published
- 2026-08-31
- OWASP
- A03 Injection
- Orthogonal defect classification
- Checking
- Code defect classification
- Missing Check
- Category
- Input Validation and Sanitization
- Subcategory
- Cross-Site Scripting (XSS)
- Accessibility scope
- Remote
- Impact
- Arbitrary Code Execution
- Affected component
- Python
Solution
Upgrade QD to version 20250901 or later, which includes the fix that HTML‑encodes logtmp before rendering.
Vulnerable code sample
import html
from tornado.web import RequestHandler
class TaskRunHandler(RequestHandler):
def post(self, taskid):
# Simulate fetching log content that may contain attacker-controlled data
logtmp = self.get_task_log(taskid) # may include raw HTML/JS
# VULNERABLE: rendering unescaped log content with string formatting
self.write("<html><body><pre>%s</pre></body></html>" % logtmp)
def get_task_log(self, taskid):
# Placeholder: in reality this pulls from exception objects or __log__
return "<script>alert('XSS');</script>"Patched code sample
import html
from tornado.web import RequestHandler
class TaskRunHandler(RequestHandler):
def post(self, taskid):
logtmp = self.get_task_log(taskid)
# FIX: escape log content before embedding in HTML
safe_log = html.escape(logtmp)
self.write("<html><body><pre>%s</pre></body></html>" % safe_log)
def get_task_log(self, taskid):
return "<script>alert('XSS');</script>"Payload
__VAITP_MODEL_REFUSED__
Cite this entry
@misc{vaitp:cve202651153,
title = {{Stored XSS via task run logs: attacker‑controlled __log__ injects script into response.}},
author = {Bogaerts, Fr\'ed\'eric and Ivaki, Naghmeh and Fonseca, Jos\'e},
year = {2026},
note = {VAITP Python Vulnerability Dataset, entry CVE-2026-51153},
howpublished = {\url{https://netpack.pt/vaitp/vulnerability/CVE-2026-51153/}}
}
Introducing the "VAITP dataset": a specialized repository of Python vulnerabilities and patches, meticulously compiled for the use of the security research community. As Python's prominence grows, understanding and addressing potential security vulnerabilities become crucial. Crafted by and for the cybersecurity community, this dataset offers a valuable resource for researchers, analysts, and developers to analyze and mitigate the security risks associated with Python. Through the comprehensive exploration of vulnerabilities and corresponding patches, the VAITP dataset fosters a safer and more resilient Python ecosystem, encouraging collaborative advancements in programming security.
The supreme art of war is to subdue the enemy without fighting.
Sun Tzu – “The Art of War”
:: Shaping the future through research and ingenuity ::
