💘HTML上でPythonコードが使える、PyScriptを用いて静的サイトを作成しました

こんにちは、B4の xryuseix です。今回はPythonのWeb上でのwasmを用いた実行環境である、 PyScript を用いて静的サイトを作成したお話をします。

作ったもの

画像をクリックするとデモページに飛びます。

レポジトリは こちら です。(←⭐️ を押すと幸せになれるらしいよ)

PyFuckとは

JsFuckのPythonバージョンです。デモサイトの上のテキストボックスにPythonコードを入力すると、e,x,c,h,r,(,+,1)の9文字しか使用しないPythonコードに変換します。

例えば、exec("print(1)")

exec(chr(111+1)+chr(111+1+1+1)+chr(11+11+11+11+11+11+11+11+11+1+1+1+1+1+1)+chr(11+11+11+11+11+11+11+11+11+11)+chr(111+1+1+1+1+1)+chr(11+11+11+1+1+1+1+1+1+1)+chr(11+11+11+11+1+1+1+1+1)+chr(11+11+11+1+1+1+1+1+1+1+1))

に変換されます。使用用途としては

  1. 簡単なPython難読化
  2. FlaskのSSTIとかで任意のPythonコードを実行でき、かつ文字種のvalidationがある場合のBypass
  3. CTFのPyjail問のBypass(リアルワールドでPyjailみたいなものはなさそうだが)

例えば、HSCTF9 paas (misc) で使用できました。

PyScriptとは

Hello World

PyScript とは、HTML内のpy-scriptタグにPythonコードを入れると、Pythonコードとして実行できるソフトウェアです(進次郎構文)。内部ではPyoditeを用いたwasm(Web Assembly)として実行しています(たぶん)。

使用方法としては以下のように、headタグにlinkタグとscriptタグでCDNリンクを設定し、py-scriptタグにPythonコード入れるだけです。

<!DOCTYPE html>
<html lang="ja">
  <head>
    <link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" />
    <script defer src="https://pyscript.net/alpha/pyscript.js"></script>
  </head>
  <body>
    <p id="title" class="text-center text-7xl"></p>
    <py-script output="title">
      print('Hello World!')
    </py-script>
  </body>
</html>

このHTMLファイルはそのままブラウザ上で動きますが、PyScriptの一部の機能はHTTPサーバを立てないと実行できません。その場合は例えばphp -S localhost:8080などで起動します。

また、PyScriptのCDNは(ほとんどの?)Tailwind CSSが使用できます。例えば、class="text-center"でテキストが中央に揃います。

モジュールのインポート

headタグの中にpy-envタグを入れ、その中にpathを設定すると、Pythonのモジュールをインポートできます。このようにすることでpy-scriptタグ内のコードを最小限に抑えることができます。また、cliアプリケーションと同じレポジトリ上でモジュールを共有することができます。これはHTTPサーバ上でないと動きません。

<!DOCTYPE html>
<html lang="ja">
  <head>
    <link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" />
    <script defer src="https://pyscript.net/alpha/pyscript.js"></script>
    <py-env>
      - paths:
        - ./modules/pyfuck.py
    </py-env>
  </head>
  <body>
    <p id="title" class="text-center text-7xl"></p>
    <py-script output="title">
      pyfuck = PyFuck.make_pyfuck("print(1)")
      print(type(pyfuck))
    </py-script>
  </body>
</html>

内部的には webpack と同じように、HTMLのレスポンス後にpythonファイルのリクエストが走るようになっています。

要素の取得・イベント操作

以下、py-scriptタグ内のお話です。ElementというPyScriptが定義しているクラスがあります。割とjQueryに近いような取得方法ですね(jQueryは関数ですが)。

foo = Element("sample-id").element.value

また、buttonタグがonClick属性が定義されているので、Element.element.onclickでonClickイベントで発火する関数を指定できます。

def foo():
    print("bar")
button = Element('sample-button')
button.element.onclick = foo

完成図

完成図は、satoki/PyFuck/index.html にあります。svgやTailwind CSSのせいでややこしくなっていますが、アプリケーションの特性と比較したらかなり簡潔なコードとなっています。PRは [satoki/PyFuck/pull/2] です。

まとめ

このように、PyScriptはすごく簡単にPythonプロジェクトをWeb上で公開できます。みなさんも既存のcliツールを静的Webサイトとして再実装してみてはいかがでしょうか。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です