Mediaプラグインをアップロード処理の基本から学ぶ(2) - 制限, 検証
PHPのアップロード処理
PHPのアップロードサポートでは、基本的にアップロードされたファイルの以下の情報が$_FILES*1に連想配列として入ります。*2
- name - アップロード元のファイル名
- type - MIMEタイプ
- size - ファイル容量(バイト)
- tmp_name - 一時ファイルとして保存されたアップロードファイルのパス
- error - アップロードに成功したか(エラー内容)
これらを元に、ファイルの検証・移動を行います。
1. name - アップロード元のファイル名
送信元から送られてくるファイル名が入りますが、これはあまり信用してはいけません。
悪意のあるファイル名の送信により、プログラム上で対策を行わないと上位ディレクトリのファイルにアクセスされる危険性もあります。
また、ファイル名がマルチバイトである場合、ファイルシステムによってはアクセスが不可能であるかまたは困難となる可能性があります。
これを回避するために、Transferビヘイビアのtransfer()メソッドを、モデルが同名のメソッドを実装することによりオーバーライドする必要があります。
具体的な実装に関しては、docs/TUTORIAL at from davidpersson/media - GitHubを参考にしてください。
2. type - MIMEタイプ
MIMEタイプが入りますが、マニュアルにもある通り、送信側から送られてきたヘッダーの内容がそのまま入るので、これは信用できません。
Mediaプラグインは、上述のmmライブラリを使ってMIMEタイプを自動解析します。
MIMEタイプの解析の方法は様々ありますが、例えばFileInfoなどを使って解析することができます。
これはmmのMime_Typeの設定で変更することができます。
3. size - ファイル容量(バイト)
ファイルのバイト数が入ります。
PHPの設定によりファイルサイズも制御できますが、アップロードされるファイルの種類によってファイル容量を抑制する場合は、アプリケーション側で処理をする必要が出てきます。
これをMediaプラグインはcheckSizeバリデーションで行います。
ファイルの移動
ファイルの移動を行う時に、その移動元、移動先が正しい場所であるか検証する必要があります。
ファイルの場所
もしシステムファイルにアクセスできたり、または特定のディレクトリにアップロードファイルが書き込まれることがあったら、非常に危険な事態に陥る可能性があります。
これを検証するために、MeidaプラグインのcheckLocationバリデーションが利用できます。例えば、/tmp、APP/tmp、APP/webroot/media(MEDIA定数)等を指定します。
ファイルのアクセス権限(パーミッション)
移動元のファイルは読み込み可能であり、移動先のディレクトリは書き込み可能である必要があります。
そうでない場合、アップロードが必ず失敗することは想像の範疇だと思います。
これは、MediaプラグインでcheckAccessバリデーションを使用することで検証できます。
また、移動元のファイルにもし実行可能属性が付いていたらどうでしょうか。
そうなる状況はあり得るかという疑問はありますが、実際共有サーバーなどで/tmpなどに悪意のある操作をされることは想定できます。
これを検証するために、MediaプラグインにはcheckPermissionバリデーションが用意されています。
その他の制限、検証
次回予告
いかがだったでしょうか。アップロードの検証だけでも多くの面からの処理が必要になることが理解できると思います。
次回はアップロードされたファイルの変換と配置についてになります。
サムネイルの生成など、アプリケーションのロジックにも関わるところで、一番関心を引くところではないでしょうか。
次回: Mediaプラグインをアップロード処理の基本から学ぶ(3) - 変換, 配置 -
*1:CakePHPでは、FormHelper#file()などで出力したinput[type=file]の内容は、$_FILESからディスパッチャを通して$this->dataに格納されます。
*2:PHP: POST メソッドによるアップロード - Manual
*3:この記事で**バリデーションと表記しているものはTransferビヘイビアのものを指す