---
id: GHSA-v853-p72q-4cfw
title: >-
  Quart leaks raw request body (incl. plaintext passwords) to stdout via stray
  debug print in Body.__await__
summary: >-
  Quart leaks raw request body (incl. plaintext passwords) to stdout via stray
  debug print in Body.__await__
severity: high
cvss: 7.5
cwe:
  - CWE-532
vendor: quart
product: quart
ecosystem: pip
affected:
  - quart = 0.23.0
patched:
  - quart 0.23.1
published: '2026-10-05'
updated: '2026-10-05'
sourceUpdated: '2026-10-05T22:49:45Z'
source: GHSA
sourceUrl: 'https://github.com/advisories/GHSA-v853-p72q-4cfw'
references:
  - url: 'https://github.com/pallets/quart/security/advisories/GHSA-v853-p72q-4cfw'
  - url: >-
      https://github.com/pallets/quart/commit/e8eb3b8a0cb98e7574bf3841312fc7f96883d055
  - url: 'https://github.com/pallets/quart/releases/tag/0.23.1'
  - url: 'https://github.com/advisories/GHSA-v853-p72q-4cfw'
tags:
  - ghsa
  - pip
ingestedAt: '2026-10-05T23:36:21.176Z'
---

## Overview

### Summary
Quart 0.23.0 contains a stray debug statement (`print(data)`) inside `Body.__await__` in `quart/wrappers/request.py`. Any request whose body is awaited — `await request.form`, `await request.get_data()`, WTForms `validate_on_submit()`, etc. — has its raw, unparsed body printed to stdout, including plaintext form fields such as passwords and CSRF tokens. Confirmed present in 0.23.0, confirmed absent in 0.22.0.

### Details
In `src/quart/wrappers/request.py`, `Body.__await__` accumulates the request body into a bytearray:

​```python
data = bytearray()
while not self._queue.empty():
    data.extend(self._queue.get_nowait())
    print(data)          # <-- not present in 0.22.0
    if (
        self._max_content_length is not None
        and len(data) > self._max_content_length
    ):
        raise RequestEntityTooLarge()
​```

This fires for every request that awaits its body — the overwhelming majority of POST/PUT routes in a typical Quart app (form submissions, JSON APIs via `request.get_json()`, file uploads, etc.).

### PoC
1. `pip install quart==0.23.0` (requires Python 3.13+)
2. Minimal route:
​```python
@app.route("/login", methods=["POST"])
async def login():
    form_data = await request.form
    ...
​```
3. Submit a POST with form data, e.g. a login form with `staff_id`/`password` fields.
4. Observe stdout: the full raw body is printed as `bytearray(b'csrf_token=...&staff_id=...&password=...')`.

Confirmed via source diff against 0.22.0's `request.py`, where this line does not exist.

### Impact
Any app that captures stdout in logs (terminal redirect, systemd/journald, Docker logs, cloud log aggregation, etc.) will have every submitted form body — including login credentials — written to logs in plaintext. This affects any Quart 0.23.0 app handling authentication or any sensitive form data, and is trivially triggerable by any user simply submitting a form (no attacker action required beyond normal use).

## Affected packages

- `quart = 0.23.0`

## Remediation

Upgrade to a patched release:

- `quart 0.23.1`
