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


概要

以前紹介したバグだらけのWebアプリケーション「EasyBuggy」のDjango 2.0ベースのクローンをつくってみました(「EasyBuggy Django」)。

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

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

起動するにはPython 3が必要です。python manage.py runserver 9000とすると9000番ポートで起動します。

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

$ 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 にアクセスすると、メインページが表示されます。

このアプリの用途

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

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

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

デモ

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

構成の相違点

これまでに「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の起動設定をしておけば、デバッグ、修正、即時動作確認ができます。

最後に

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

参考

Django Documentation セキュリティ上の問題のアーカイブ