世にさらすサービスのコードでopenを使っているときに気をつけないといけないこと

例えば、jsonファイルをアップロードしてもらう仕組みを作ったとします。処理の流れは、受け取ったjsonファイルを一時ファイルとして保存し、ファイルopenしてごにょごにょと処理をするというものにしているとします。で、ファイルopenの部分を以下のように書いているとします。

open(my $fh, "$dir/$id.json") || die $!;
※$idは、アップロードしてくれた人が付けたファイル名とする

ようは、「アップロードされたファイルを$dir/というディレクトリ配下に$id.jsonという名前で一時保存したので、それをopenするよー。openに失敗したらdieするよー。」、ってなスクリプトです。この一行にはセキュリティ上の問題があって、$idが以下のような名前でjsonファイルを送ってこられたときに、とんでもないことになります。

$id = ";rm -rf /;";
$id = "/../../../etc/passwd;"

最低限必要な情報以外は、なるべく自分で生成した方がいいそうです。この場合、ファイル名をユーザーが付けたものにしておく必要がないなら自分でファイル名を付ける、ユーザーが付けたファイル名じゃないといけないなら正規表現やラッパーを使って確認するプロセスを踏む、ということをするべきだそうです。


なにもしてなくて、先輩に危ないよー、と注意されました。本当にこんな悪いことをする人がいるのか、と思っていたのですが、公式にリリースしているサービスのログを見ると、実際にこの攻撃をされてました。しかも、なぜか中国から。。。