メモリリーク、デッドロック、リダイレクトループ、JVMクラッシュ...バグだらけのWebアプリケーションを使ってバグを理解する

## 概要

Webアプリケーションの開発や保守をしていると、いろいろなバグに遭遇します。メモリリーク、デッドロック、リダイレクトループ、JVMクラッシュ等々、バグは様々です。こういったバグは、実際にコードを書いて、実行・再現させてツールで解析してみると理解が深まります。

ということで、いろいろなバグを実装した[Webアプリケーション](https://github.com/k-tamura/easybuggy/blob/master/README.jp.md)をつくってみました。現時点では、以下を簡単に再現できます。

- メモリリーク (Javaヒープ領域)
- メモリリーク (Permanent領域)
- メモリリーク (Cヒープ領域)
- デッドロック (Java)
- デッドロック (SQL)
- 完了しないプロセスの待機
- 無限ループ
- リダイレクトループ
- JVMクラッシュ
- ネットワークソケットリーク
- データベースコネクションリーク
- ファイルディスクリプタリーク 
- XSS
- SQLインジェクション
- ExceptionInInitializerError
- NoClassDefFoundError
- OutOfMemoryError (Java heap space) 
- OutOfMemoryError (Requested array size exceeds VM limit)
- OutOfMemoryError (unable to create new native thread)
- OutOfMemoryError (GC overhead limit exceeded)
- OutOfMemoryError (PermGen space)
- OutOfMemoryError (Direct buffer memory)
- StackOverflowError
- UnsatisfiedLinkError
- 整数オーバーフロー
- 丸め誤差
- 打ち切り誤差
- 情報落ち

<font color="Red">[2017/02/20 さらに以下を追加]</font>

- LDAPインジェクション
- コードインジェクション
- フォワードループ
- スレッドリーク
- 正規表現解析による遅延
- 文字化け

<font color="Red">[2017/03/08 さらに以下を追加]</font>

- OSコマンドインジェクション(OGNL式インジェクション)
- 拡張子制限の無いファイルアップロード
- オープンリダイレクト
- ブルートフォース攻撃可能なログイン画面

<font color="Red">[2017/03/26 さらに以下を追加]</font>

- CSRF (クロスサイトリクエストフォージェリ)
- クリックジャッキング
- サイズ制限の無いファイルアップロード
- ディレクトリトラバーサル
- メールヘッダーインジェクション
- 意図しないファイル公開
- 親切過ぎるエラーメッセージ
- 危険なファイルインクルード
- プラス演算子による文字列結合の遅延
- FactoryConfigurationError
- Nullバイトインジェクション
- XEE
- XXE

## Webアプリケーションの起動方法

Webアプリケーションを```git clone```(またはダウンロード)して、```mvn install exec:exec```で起動します。

```bash
$ git clone https://github.com/k-tamura/easybuggy
$ cd easybuggy
$ mvn clean install exec:exec
```

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

```
5 27, 2017 3:29:58 午後 org.apache.coyote.AbstractProtocol start
情報: Starting ProtocolHandler ["http-bio-8080"]
```

### その他の起動方法

[ここ](https://github.com/k-tamura/easybuggy/releases)からダウンロードしたeasybuggy.jarを実行(```java -jar easybuggy.jar```)するか、ROOT.warをTomcatなどのサーブレットコンテナにデプロイしても起動できます。このとき以下のようなJVMオプションを付けると問題が再現しやすくなります。

```bash
java -Xmx256m -XX:MaxPermSize=64m -XX:MaxDirectMemorySize=90m -XX:+UseSerialGC -Xloggc:logs/gc.log -XX:+PrintHeapAtGC -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=10M -XX:GCTimeLimit=15 -XX:GCHeapFreeLimit=50 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=logs/ -XX:ErrorFile=logs/hs_err_pid%p.log -XX:NativeMemoryTracking=summary -agentlib:jdwp=transport=dt_socket,server=y,address=9009,suspend=n -Dderby.stream.error.file=logs/derby.log -Dderby.infolog.append=true -Dderby.language.logStatementText=true -Dderby.locks.deadlockTrace=true -Dderby.locks.monitor=true -Dderby.storage.rowLocking=true -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=7900 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -jar easybuggy.jar
```

※easybuggy.jarとROOT.warは、```mvn package```でビルドされます。

起動したら次のURLにアクセスします。

http://localhost:8080

正常に起動していると以下のような画面が表示されます。

![mainPage.png](https://qiita-image-store.s3.amazonaws.com/0/43869/c3d390d2-27fb-6317-0f4e-5b6d0754211b.png)

リンクのいずれかをクリックすると、問題が発生します。が、その前にVisualVMやJConsoleなどを起動しておくと、どのような現象が起こっているか把握できます。以下は、Javaヒープ領域のメモリリークを起こして、OutOfMemoryErrorを発生させる過程を監視しているVisualVMの画面キャプチャです。

![OOME.png](https://qiita-image-store.s3.amazonaws.com/0/43869/8e3a9752-98f3-5ec3-f577-76b488a3bd7b.png)

これらのツールを使ったバグの解析方法などについては、今後簡単に説明します。

## 注意事項

OutOfMemoryError関連のリンク(特にネイティブメモリを操作するもの)をクリックすると、PCの動作が不安定になる可能性があります。CPUやメモリを制限したVM上で起動するなどしてから、**自己責任でリンクをクリックして下さい。**

## 詳細

このWebアプリケーションに関するデバッグやトラブルシューティングの方法については、[このページ](https://t246osslab.wordpress.com/2017/03/14/easybuggy-%E3%81%AE%E3%83%88%E3%83%AA%E3%82%BB%E3%83%84/)(日本語)か[このページ](https://github.com/k-tamura/easybuggy/wiki)(英語)を参考にして下さい。

## 補足

[Spring Bootでつくったこのアプリケーションのクローン](https://github.com/k-tamura/easybuggy4sb/blob/master/README.jp.md)もあります。

## デモ

以下は起動のデモです。

![mov_eb_ppt1.gif](https://qiita-image-store.s3.amazonaws.com/0/43869/c1a11416-fb4c-e75c-1312-1f28f4a014e6.gif)

## プレゼン資料

「第57回 脆弱性診断ええんやで(^^)　やられWebアプリケーションの倒し方」でお話しした(正確にはお話していただいた)「Easybuggy」についてのプレゼン資料です。

[![thumbnail](http://image.slidesharecdn.com/easybuggy-180116141313/95/slide-1-1024.jpg)](https://www.slideshare.net/KoheiTamura/easybuggy-86227462)

（<font color="Red">[2018/01/22 デモとプレゼン資料を追加]</font>）