์ต๊ทผ PyCon US 2022์ ๋ฐํ ์ค PyScript๊ฐ ๊ณต๊ฐ๋์์ต๋๋ค. PyScript๋ HTML์์ Python ์ฝ๋๋ฅผ ์ฌ์ฉํ ์ ์๋๋ก ์ ๊ณตํ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ก ์ต๊ทผ ์์ฒญ๋ ๋ฒ์ฉ์ฑ๊ณผ ๋ฎ์ ๋ฌ๋ ์ปค๋ธ๋ฅผ ๊ฐ์ง Python์ด ์น์ผ๋ก ํ์ฅํ๋ ๋ถ๋ถ์ด๋ผ ๊ด์ฌ๋ ๋ง๊ณ ๋ง๋ ๋ง์ต๋๋ค.
HMLT ๋ด๋ถ์์ ์ฝ๋๋ฅผ ์ฐ๋ ๋ฐฉ์์ด PHP์ ๋ญ๋ผ ๋ค๋ฅด๋๋ ์ด์ผ๊ธฐ๋ ์์ต๋๋ค. ์คํ๋ ค ์๋๋ฅผ ์ญํํ๋ค๋ ์ด์ผ๊ธฐ๋ ๋ดค๋ ๊ฒ ๊ฐ๋ค์.
๋์์ธ ํจํด์ด๋ ์ฝ๋์ ๋ํ ๋ด์ฉ์ ๊ฐ๋ฐ์๋ถ๋ค์ด ๋ง์ด ์ ๊ฒฝ์ฐ์ค ๋ด์ฉ์ด๊ณ , ์ฐ๋ฆฌ๋ ๋ณด์ ์์ง๋์ด๋ง์ด๋ ๋ณด์์ชฝ ๊ด์ ์์๋ ํ๋ฒ ์ดํด๋ด์ผํด์ ์ ๋ฉฐ์น ๊ฐ๋ณ๊ฒ ๊ณ ๋ฏผํด๋ณด๊ณ ๊ธ๋ก ์์ฑํด๋ด ๋๋ค.
PyScript
PHP์์ <?php ?>
๋ฌธ๋ฒ์ผ๋ก PHP ๊ตฌ๋ฌธ์ ์ฌ์ฉํ๋ ๊ฒ๊ณผ ๋น์ทํฉ๋๋ค. <py-script>
ํ๊ทธ๋ฅผ ์์ฑํ ๋ถ๋ถ์ python ๋ฌธ๋ฒ์ผ๋ก ๋์ํ๊ฒ ๋ฉ๋๋ค.
<html>
<py-script> print('Hiiii') </py-script>|
</html>
์ค์ js ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊น์ง ํฌํจํ ๋ด์ฉ์ ์๋์ ๊ฐ๊ฒ ๋ค์.
<html>
<head>
<link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" />
<script defer src="https://pyscript.net/alpha/pyscript.js"></script>
</head>
<body>
<py-script> print('Hello, World!')</py-script>
</body>
</html>
How to work
PyScript๋ Pyodide์ ๊ธฐ๋ฐ์ผ๋ก ๊ฐ๋ฐ๋์์ต๋๋ค. ์ด๋ ์น์ด์ ๋ธ๋ฆฌ(WASM)๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๋ธ๋ผ์ฐ์ ์ Node.js๋ฅผ ์ํ ํ์ด์ฌ ๋ฐฐํฌํ์ ๋๋ค.
์ฐธ๊ณ ๋ก WASM์ ์ ๊ฐ ์์ ์ โ์น ์ด์ ๋ธ๋ฆฌ(Web Assembly)๋ ์ด๋ป๊ฒ ๋ณด์ ์ทจ์ฝ์ ๋ถ์์ ํ ๊น์?โ๋ ๊ธ์ ์์ฑํ์์ต๋๋ค. ์ฌ๊ธฐ์ WASM์ด ๋ญ์ง, ์ด๋ป๊ฒ ๋ณด์ ํ ์คํ ์ ํ ์ ์๋์ง ๋ณด์ค ์ ์์ต๋๋ค.
์์ธํ ๋์์ ๋ณธ๊ฑด ์๋์ง๋ง ์ด์จ๋ PyScript๋ WASM ๊ธฐ๋ฐ์ผ๋ก Python(cPython)์ ๋์ํ์ฌ ์คํํ๋ค๋ ๊ฒ์ ์ ์ ์์ต๋๋ค.
Elements
Script
<py-script>
๋ ์น ํ์ด์ง ๋ด์์ ์คํ ๊ฐ๋ฅํ ํ์ด์ฌ ์ฝ๋๋ฅผ ์ ์ํ๋ ๋ฐ ์ฌ์ฉํฉ๋๋ค. ํด๋น Element๋ ํ์ด์ง์ ๋ ๋๋ง๋์ง ์๊ณ ๋ง์น <script>
ํ๊ทธ์ ๊ฐ์ด ๋ก์ง๋ง ๋์ํฉ๋๋ค. src ์์ฑ๋ ๋น์ทํ๊ฒ ์ฌ์ฉํ ์ ์์ต๋๋ค.
<py-script src="/app.py"></py-script>
Repl
ํ์ด์ง์ ์ฝ๋ ํธ์ง๊ธฐ๋ก ๋ ๋๋ง๋๊ณ ์ฌ์ฉ์๊ฐ ์คํํ ์ ์๋ ์ฝ๋๋ฅผ ์์ฑํ ์ ์๋ REPL์ ๋ง๋ญ๋๋ค.
Examples
- https://github.com/pyscript/pyscript/tree/main/pyscriptjs/examples
Security
์ ๊ฐ ์์์ PyScript๊ฐ WASM ๊ธฐ๋ฐ์ผ๋ก ๋์ํ๋ค๊ณ ํ์ต๋๋ค. ๊ฒฐ๊ตญ ๋จ์ํ ๋ฌธ๋ฒ๋ง ๋งคํ์ํจ๊ฒ ์๋๋ผ ์ค์ ๋ก Python์ด ๊ตฌ๋๋ ์ ์๊ธฐ ๋๋ฌธ์ ์ฌ์ฉ์์๊ฒ ํ์ด์ง์ ๋ํ ์ ์ด๊ถ์ ์ฃผ๊ฑฐ๋ XSS ๋ฑ์ ์ด์๊ฐ ์๋ ๊ฒฝ์ฐ ์ข ๋ ๋ฆฌ์คํฌ๊ฐ ์ฆ๊ฐํ๊ฒ ๋ฉ๋๋ค.
Sensitive data exposure
Python ์ฝ๋๊ฐ FE๋จ์์ ์ฌ์ฉ๋๋ค๋ฉด ์ํ์ด ์ฝ๋ฉ์์๋ ๊ด์ ์ด ์ฝ๊ฐ ๋ณํ๊ฒ ๋ฉ๋๋ค. ๋ณดํต Secret์ด๋ Key ๋ฑ์ ์ ๋ณด๋ ๋ฐฑ์๋์์ ์ฒ๋ฆฌํ๋๋ก ํ์ง๋ง, FE์์ ์ฝ๊ฒ Python ๋ชจ๋์ ์ฌ์ฉํ ์ ์๋ ๊ฒฝ์ฐ ๋ถ๋ช ํ ์ผ๋ถ ๊ฐ๋ฐ์๋ ์ค์ํ ์ ๋ณด๋ฅผ PyScript ๋จ์์ ์ฌ์ฉํ ์๋ ์์ต๋๋ค.
๋ง์ฝ ์ด๋ ๊ฒ ์ฌ์ฉ๋๋ ๊ฒฝ์ฐ ์ฝ๊ฒ ์ค์์ ๋ณด๋ฅผ ํ์ทจํ ์ ์์ด์ ์ฐ์์ ์ธ ๊ณต๊ฒฉ์ผ๋ก ์ด์ด์ง ์ ์์ต๋๋ค.
Leak without browser policy
์ฝ๋ ๋์์ด WASM ๋ด๋ถ์์ ๋ณ๋๋ก์ ๋ฐ์ด๋๋ฆฌ๋ก ๋ฐ์ํ๊ธฐ ๋๋ฌธ์ ๊ธฐ์กด Browser์์์ ๋ณด์ ์ ์ฑ ๊ณผ ํต์ ๋ก์ง์ ์ ์ฉ๋ฐ์ง ๋ชปํ๋ ๊ฒฝ์ฐ๊ฐ ๋ฐ์ํฉ๋๋ค. ๊ทธ๋์ ๊ณต๊ฒฉ์๊ฐ ๋ฐ์ดํฐ๋ฅผ ๋นผ๋๋ฆฌ๋๋ฐ ์์ด์ CSP ๋ฑ์ผ๋ก ์ ํ์ ๋ฐ๋๋ผ๋, PyScirpt ์ฝ๋๋ฅผ ํตํด์ ์ฐํํ์ฌ ๋ฐ์ดํฐ๋ฅผ ์ ์ถํ ์ ์๋ ๊ฒฝ์ฐ๊ฐ ์์ ๊ฒ ๊ฐ์ต๋๋ค.
DOS
Javascript ์ฒ๋ผ ๋ธ๋ผ์ฐ์ ์ ๋ด์ฅ๋์ด ๋ฐ์ ํ๊ฒ ๋์ํ๋ ๊ฒ์ด ์๋ WASM์ผ๋ก ์ฒ๋ฆฌํ๊ธฐ ๋๋ฌธ์ ๊ตฌ์ฑ์ ๋ฐ๋ผ ์ค๋ฒํค๋๊ฐ ํด ์ ์์ต๋๋ค. ๊ฒฐ๊ตญ ์ด๋ฅผ ์ ์ด์ฉํ๋ฉด ๊ฐ๋จํ ์ฝ๋๋ก๋ ์ถฉ๋ถํ ๋จ์ผ ๋๋ ๊ด๋ฒ์ํ ์ฌ์ฉ์๋ฅผ ๋์์ผ๋ก DOS๋ฅผ ์ผ์ผํค๊ธฐ ์ถฉ๋ถํ๋จ ๊ฒ์ ์ ์ ์์ต๋๋ค.
XSS
PyScript๋ฅผ ํตํด์ XSS ์ฐํ ํจํด์ ์ถฉ๋ถํ ๋ง๋ค ์ ์์ต๋๋ค. ๋ง์ฝ Deny-list ๊ธฐ๋ฐ์ ๊ฒ์ฆ ๋ก์ง์ด๋ผ๋ฉด ๋น์ฐํ <py-script>
๋ฑ์ ํจํด์ ๋น ์ ธ์์ ํ๋ฅ ์ด ๋์์ ํ๊ทธ ๊ธฐ๋ฐ์ผ๋ก๋ ์ถฉ๋ถํ ์ฐํํ ์ ์๊ณ , ๋ง์ฝ ์ฃผ์ ๊ณต๊ฒฉ ๊ตฌ๋ฌธ ๋ฑ์ผ๋ก Escape ์ฒ๋ฆฌํ๋ค๊ณ ํด๋ Python ์ฝ๋๋ฅผ ํตํด ์ฝ๊ฒ ๋๋
ํํ์ฌ XSS ๋์ ๋ก์ง์ ๋ฌด๋ ฅํ ์ํฌ ์๋ ์์ต๋๋ค.
Bypassing Sandbox
๊ธฐ๋ณธ์ ์ผ๋ก os ๋ฑ ์ฌ๋ฌ ๋ชจ๋์ ๋ก๋ํ ์ ์๊ธฐ ๋๋ฌธ์ Command Execute์ ๊ฐ๋ฅ์ฑ ๋ํ ์กด์ฌํฉ๋๋ค. ๋ค๋ง Pyodide์ด ์ด๋ฌํ ๋ณด์ ๋ฌธ์ ๋ Sandboxing ๋ฑ์ ๊ธฐ์ ๋ก ํต์ ํ๋ ๊ฒ ๊ฐ์ต๋๋ค.
๊ทธ๋๋ Pyodide์์ ์ด๋ฌํ ๋ณด์ ๋ก์ง์ ๋ํ ์ฐํ๊ฐ ๋ฐ์ํ๋ ๊ฒฝ์ฐ ๋จ์ํ ํด๋น ๋ชจ๋๋ง์ ๋ฌธ์ ๊ฐ ์๋ PyScript์์ ๊ด๋ฒ์ํ ์ฌ์ฉ์๋ฅผ ๋์์ผ๋ก Command Execution ๋ฑ์ด ๋ฐ์ํ ์ ์์ด์ ๋ฌธ์ ๊ฐ๋ ๊ฒ ๊ฐ์ต๋๋ค. ํน์๋ PyScript๋ฅผ ์ฌ์ฉํ๊ฒ ๋๋ค๋ฉด ์ด์ ์ ๊ณ ๋ คํ๊ณ ๋ณด์ ์ด์์ ๋ํด์ ๋ฏผ๊ฐํ๊ฒ ์ฒดํฌํ๊ณ ์์ด์ผํ ๊ฒ ๊ฐ๋ค์.
Etc
์ด์ธ์๋ WASM์ ๋ํ ๋ณด์ ์ด์๋ถํฐ ๋ก์ง์ ์ธ ๋ถ๋ถ, ํ์ด์ฌ ์ฝ๋์์ ๋ฌธ์ ๋ฑ์ผ๋ก ์ฌ๋ฌ๊ฐ์ง ์ด์๊ฐ ๋ํ๋ ์ ์์ ๊ฒ ๊ฐ์ต๋๋ค ๐ญ
References
- https://pyscript.net
- https://twitter.com/mariatta/status/1520439766130454530
- https://www.hahwul.com/2018/10/06/hacking-security-analysis-web-assembly/