HTTP::Engine::Middleware::Staticのdocrootにシンボリックリンクを渡してはいけない

Arkでstaticなファイルが表示できないことがあるので何かと思ったら、HTTP::Engine::Middleware::Staticのdocrootにシンボリックリンクを渡していたのが原因でした。CPAN最新版のHTTP::Engine::Middleware 0.17で確認したけど、githubの最新版でも該当部分は同じなので再現するはず。OSはLeopard

HE::Middleware::Staticはbefore_handle()内で

    my $docroot = dir($self->docroot)->absolute;

としてdocrootを取得した上で、

    my $realpath = Cwd::realpath($file->absolute->stringify);
    if ($realpath) {
        # check directory traversal if realpath found
        return HTTP::Engine::Response->new( status => 403, body => 'forbidden') unless $docroot->subsumes($realpath);
    }

としてディレクトリトラバーサルの対策をしていますが、$realpathがrealpathを取っているのに対して、$docrootはrealpathではないので、シンボリックリンクを渡すとsubsumesが期待通りの判定をしてくれないケースがあります。

対策としては、$mw->installする時にdocrootにrealpathを投げるか、HE::Middleware::Staticがdocrootを取得する部分を

    my $docroot = dir(Cwd::realpath($self->docroot))->absolute;

に書き換えるとか。

# テストも書いてパッチをpull requestしました。経過待ち。