バグだらけのWebアプリケーションをDjango 2（Python 3）で実装してみました

## 概要

[以前紹介した](https://qiita.com/tamura__246/items/7275c7406706fb0057e8)バグだらけのWebアプリケーション[「EasyBuggy」](https://github.com/k-tamura/easybuggy/blob/master/README.jp.md)のDjango 2.0ベースのクローンをつくってみました([「EasyBuggy Django」](https://github.com/k-tamura/easybuggy4django/blob/master/README.jp.rst))。

![easybuggy.png](https://qiita-image-store.s3.amazonaws.com/0/43869/b88b6aca-a4d6-a88d-193b-8dbdc8040557.png)


以下のコマンドでダウンロードから起動までできます。

```bash
$ git clone https://github.com/k-tamura/easybuggy4django.git
$ cd easybuggy4django/
$ pip install -r requirements.txt
$ python manage.py runserver
```

<table width="100%"><tr><td>:writing_hand_tone1: 起動するにはPython 3が必要です。`python manage.py runserver 9000`とすると9000番ポートで起動します。</td></tr><table>

※上記のコマンドを実行する前に、Pythonの仮想環境を構築しておくことをお勧めします。

```bash
$ python3 -m venv venv
$ source venv/bin/activate
```

以下のようなメッセージが表示されたら、Webアプリケーションの起動は完了しています。

```
System check identified no issues (0 silenced).
May 29, 2018 - 16:50:34
Django version 2.0.4, using settings 'config.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
```

http://localhost:8000 にアクセスすると、メインページが表示されます。

![mov_eb_dj.gif](https://qiita-image-store.s3.amazonaws.com/0/43869/696504db-88fd-5f4d-399c-4becaff2f48b.gif)

## このアプリの用途

「EasyBuggy」と同様に、様々な問題を再現させて、解析し、理解を深めることが目的です。現時点で実装しているのは、以下のバグや脆弱性です。

 - デッドロック(Python)
 - デッドロック(SQL)
 - 無限ループ
 - リダイレクトループ
 - メモリリーク
 - ネットワークソケットリーク
 - データベースコネクションリーク
 - ファイルディスクリプタリーク
 - スレッドリーク
 - 文字化け
 - 整数オーバーフロー
 - 丸め誤差
 - 打ち切り誤差
 - 情報落ち
 - XSS (クロスサイトスクリプティング)
 - SQLインジェクション
 - LDAPインジェクション
 - コードインジェクション
 - OSコマンドインジェクション
 - メールヘッダーインジェクション
 - サイズ制限の無いファイルアップロード
 - 拡張子制限の無いファイルアップロード
 - ブルートフォース攻撃可能なログイン画面
 - オープンリダイレクト可能なログイン画面
 - 親切過ぎる認証エラーメッセージ
 - CSRF (クロスサイトリクエストフォージェリ)
 - クリックジャッキング
 - XXE (XML外部エンティティ)

今回はPythonで実装しました。同様の機能でもJavaのときとは異なる動作をすることがあるので、勉強になりました。

## デモ

以下は、コードインジェクションにより、EasyBuggy Djangoを停止させるデモです。

![mov_eb_dj_demo.gif](https://qiita-image-store.s3.amazonaws.com/0/43869/8cc2391a-410e-10cd-ca10-c5581a3a39f7.gif)


## 構成の相違点

これまでに「EasyBuggy」のクローンとして、「EasyBuggy Boot」（Spring Bootベース）、「EasyBuggy Bootlin」（Spring Bootベースでkotlin実装）をつくったのですが、それらとの主な構成の相違点は以下の通りです。

|相違点|EasyBuggy|EasyBuggy Boot|EasyBuggy Bootlin|EasyBuggy Django|
--------|--------|--------|--------|--------
|言語|Java|Java|Kotlin|Python|
|ベースとなる技術|Servlet 3.0.1|Spring Boot 1.5.6 (Servlet 3.0.1)|Spring Boot 1.5.7 (Servlet 3.0.1)|Django 2.0|
|プレゼンテーション層|未使用 (一部 JSP 2.2 + JSTL 1.2)|Thymeleaf 2.1.5 (一部 JSP 2.3 + JSTL 1.2)|Thymeleaf 2.1.5 (一部 JSP 2.3 + JSTL 1.2)|Django 2.0|
|コンテナ|Tomcat 7.0.37|Tomcat 8.5.16|Tomcat 8.5.20|(Django組み込みの開発用Web サーバー)|
|DBクライアント/サーバー|JDBC / Derby 10.8.3.0|Spring JDBC 4.3.9 / Derby 10.12.1.1 (Java 7の場合)、または10.13.1.1 (Java 8の場合)|Spring JDBC 4.3.11 / Derby 10.13.1.1|PyMySQL 0.8.0 / MySQLサーバーが必要|
|LDAPクライアント/サーバー|Apache DS Client API 1.0.0 / Server 1.5.5|Spring LDAP 2.3.1 / unboundid-ldapsdk 3.2.1|Spring LDAP 2.3.1 / unboundid-ldapsdk 3.2.1|LDAP3 2.5 / 任意LDAPサーバーが必要|
|メール|JavaMail 1.5.1|JavaMail 1.5.1 (Spring Boot Mailで導入されるJavaMail 1.5.6をオーバーライド)|JavaMail 1.5.1 (Spring Boot Mailで導入されるJavaMail 1.5.6をオーバーライド)|smtplib(標準ライブラリ)|
|開発ツール|無し|Spring Boot Developer Tools 1.5.6|Spring Boot Developer Tools 1.5.7|無し|
|ビルドツール|Maven|Maven|Gradle|無し|
|実行環境|JRE 6以上をサポート|JRE 7以上をサポート|JRE 8以上をサポート|Python 3|

## 開発の方法

EasyBuggy Djangoの開発には、Pycharmを使用しています。「Run/Debug Cinfigurations」に`runserver`パラメーター付きで、`manage.py`の起動設定をしておけば、デバッグ、修正、即時動作確認ができます。

![Screenshot from 2018-05-30 13-17-45.png](https://qiita-image-store.s3.amazonaws.com/0/43869/e54e7a0b-37e9-7c68-3954-cec08f13a19f.png)


## 最後に

未実装の機能も課題もいろいろとあるんですが、公開してみました。PythonもDjangoも仕事で使ったことはほとんどないので、いろいろ指摘していただけるとうれしいです。「こんな実装で問題や脆弱性を作り込めるよ」という情報があれば、ぜひ教えて下さい。

## 参考

[Django Documentation セキュリティ上の問題のアーカイブ](https://docs.djangoproject.com/ja/2.0/releases/security/)