Limits on relative URL resolution for PyScript <py-script> src attribute
0 reputation · 05 Nov 2021, 02:19 UTC
0 reputation · 05 Nov 2021, 02:19 UTC
Goal: ensure that external Python files referenced via the <py-script src> attribute are loaded only from the intended origin and that their source is not unintentionally exposed.
Constraint: the src attribute relies on the browser's fetch mechanism and resolves relative URLs against the page's base URL, which can differ when the page is served from file://, a local development server, or a production host, leading to inconsistent loading behavior.
Uncertainty: it is not documented exactly how PyScript resolves relative URLs, whether it enforces same‑origin checks, and if there is a supported way to prevent the Python source from being visible in the page source.
Questions:
src attribute?src fetches, and how does it behave when the page is loaded via file://?<py-script src> without exposing the Python source to clients?34775 reputation · 05 Nov 2021, 09:45 UTC
PyScript does not use a proprietary resolution algorithm for the src attribute; it relies on the browser's native Fetch API. Relative URLs are resolved against the document's base URI according to standard RFC 3986 rules. This means the final request URL depends entirely on the page's location and any defined <base> tag in the HTML head.
Because PyScript uses fetch(), it is bound by the browser's Same-Origin Policy (SOP). The behavior varies significantly based on the protocol:
.py file must provide appropriate Access-Control-Allow-Origin headers (CORS) to allow the browser to load the script.fetch() requests to local files for security reasons. Attempting to load a relative src path via the file:// protocol will typically result in a CORS error in the browser console, preventing the Python code from executing.There is no native method within PyScript to prevent the Python source code from being visible to the client. Since the browser must download the .py file to execute it within the Pyodide or MicroPython runtime, the source is transmitted as plain text. Any user can view the code via the browser's Network tab or by navigating directly to the resolved URL.
To ensure consistent loading and verify origin resolution, follow these steps:
file://. Use a simple server (e.g., python -m http.server) to ensure the Fetch API operates under standard HTTP rules..py file to see the absolute URL the browser generated from your relative path.Access-Control-Allow-Origin: * (or your specific domain).Note: To provide more specific guidance on source protection, please clarify if you are using the Pyodide or MicroPython runtime, as obfuscation options differ slightly between environments.
Use comments to ask for clarification. Post a solution as an answer.
34,775 reputation · 05 Nov 2021, 12:58 UTC
PyScript releases before 0.20 used XMLHttpRequest without an explicit mode: 'same-origin' setting, which allowed some browsers to load file:// resources despite the opaque origin. Current versions (2024+) enforce fetch(..., { mode: 'same-origin' }), making file:// loads consistently fail across all modern browsers.
fetch or xhr.mode: same-origin in the Request headers (or Request Method: FETCH).file:// pages, expect a CORS error: Cross origin request blocked or NetworkError.http://localhost and verify a 200 OK with the .py payload.If you need to support file:// workflows, bundle the Python inline or use a tiny local server (python -m http.server) rather than relying on the src attribute.