delicious! newsing! buzzurlにブックマーク! Yahoo!ブックマーク ライブドア - この記事をクリップ! このエントリーを含むはてなブックマーク

php :: ファイルを強制的にダウンロードさせる

2007/6/6 (Wed) at 9:56 pm

追記。2010年5月26日。ディレクトリトラバーサルできちゃうのではないかというご指摘を頂きました。詳しくは下のコメントに!追記以上。

画像ファイル、mp3、pdf、ワード書類といった様々な拡張子のファイルをダウンロードさせたいときがあります。ブラウザで開くんじゃなくて、ダウンロードさせたいという。.htaccess に以下のように記述しとけばよいという話も出ますが、

AddType application/octet-stream .lzh .zip .mp3

残念ながらこの手はだめっぽい。IEが華麗にスルーしてくれます。php、perl等でcontent type headerを出力したほうがベター。ってわけでここにサンプルスクリプトがありました。Thank you!↓

これをやっとけば、ユーザーがpdfファイルをクリックしたときの、あの地獄の間を与えなくてよいという至福のユーザビリティが実現できますね。あれ、殺意を覚えますもん。世の中のすべてのpdfへのリンクがこれになっていたらば世界の犯罪は減ることでしょう。ラブ&ピース。

delicious! newsing! buzzurlにブックマーク! Yahoo!ブックマーク ライブドア - この記事をクリップ! このエントリーを含むはてなブックマーク

add your comment!
とほりすがり
2010/4/13, 6:10 AM
コメント アロー! one-px-ffffff-br one-px-ffffff-tr one-px-ffffff-bl one-px-ffffff-br

まさにこれを探してました!

すっげーありがとうございます!!

one-px-ffffff-tr one-px-ffffff-bl one-px-ffffff-br
add your comment!
2010/4/14, 12:33 PM
コメント アロー! one-px-ffffff-br one-px-ffffff-tr one-px-ffffff-bl one-px-ffffff-br

どうもです。この記事を書いたのはずいぶん前ですが、私もリンク先のスクリプトを昨年の暮れに使ってオッケーだったです。が、もしなにか不具合などがあったら教えてください。

one-px-ffffff-tr one-px-ffffff-bl one-px-ffffff-br
add your comment!
esperia
2010/5/25, 9:54 AM
コメント アロー! one-px-ffffff-br one-px-ffffff-tr one-px-ffffff-bl one-px-ffffff-br

このスクリプト、ディレクトリトラバーサルできるので非常にまずい気がします。さらに、同じ又は別の階層にphpファイル置いてると、そのphpのソースが丸見えです。

?file=index.php

最低でも、20行目付近のswitch文でダウンロードできるファイルの種類を絞って、default文の行を

default: exit();

にしておいたほうがいいと思います。

one-px-ffffff-tr one-px-ffffff-bl one-px-ffffff-br
add your comment!
2010/5/25, 10:27 AM
コメント アロー! one-px-ffffff-br one-px-ffffff-tr one-px-ffffff-bl one-px-ffffff-br

esperiaさん、

あ、そうですね、たしかに。phpファイル名自身を渡すってのは思いつきませんでした。ありがとうございます。

実際にこれを使うときには、phpファイルとダウンロードディレクトリは別の場所であるとして使うときが多いと思うのですが(私はいつもそのようにしています)、その場合、クエリ文字列にへんなもんが含まれていないかチェックする、とか、file_exists()の前にrealpath()を使うとか、というような処理を通せばいいのかなと思ったのですが、それでもまだまずい点がありますでしょうか。

one-px-ffffff-tr one-px-ffffff-bl one-px-ffffff-br
add your comment!
esperia
2010/5/26, 10:11 AM
コメント アロー! one-px-ffffff-br one-px-ffffff-tr one-px-ffffff-bl one-px-ffffff-br

問題は「../」が使えてしまうことで、サーバ内の拡張子付きファイルすべてがダウンロードの対象になってしまっていることなので、realpath()ではダメです。

決められた拡張子のものしかダウンロードしないようにしておくのが一番有効だと思います。(?file=./で、自身のソースは読まれてしまいますが。。)

あと、「../」「./」が含まれている場合は、全て無効なクエリとして処理する方法もあります。force-download.phpをドキュメントルート直下で動かすようにしておくと、システム内部のデータなどは読まれなくなります。

if(preg_match("/(../)/", $filename)) exit;

one-px-ffffff-tr one-px-ffffff-bl one-px-ffffff-br
add your comment!
esperia
2010/5/26, 3:49 PM
コメント アロー! one-px-ffffff-br one-px-ffffff-tr one-px-ffffff-bl one-px-ffffff-br

すみません、¥マークが取り除かれてますね…。半角で

if(preg_match("/(¥.¥.¥/)/", $filename)) exit;

です。

one-px-ffffff-tr one-px-ffffff-bl one-px-ffffff-br
add your comment!
2010/5/26, 3:51 PM
コメント アロー! one-px-ffffff-br one-px-ffffff-tr one-px-ffffff-bl one-px-ffffff-br

ご親切に教えてくださりありがとうございました!

one-px-ffffff-tr one-px-ffffff-bl one-px-ffffff-br
add your comment!
2010/5/26, 3:58 PM
コメント アロー! one-px-ffffff-br one-px-ffffff-tr one-px-ffffff-bl one-px-ffffff-br

あ、enマークがそうなっちゃうのか。重ね重ねすません!

ちょとテスト。

\

one-px-ffffff-tr one-px-ffffff-bl one-px-ffffff-br
add your comment!
2010/5/26, 4:04 PM
コメント アロー! one-px-ffffff-br one-px-ffffff-tr one-px-ffffff-bl one-px-ffffff-br

コメント部分にenマークが入っていると取り除かれるという点にいま気づきました。コメントした直後はオッケーなんだけど、リロードすると変わってしまうなあ。失礼。あとで直します。

one-px-ffffff-tr one-px-ffffff-bl one-px-ffffff-br

コメント・プリーズ!

お名前 (your name)
(required)
url
(optional) ※公開されます。
メールアドレス (email)
(optional) ※公開されません。管理者にだけわかります。
コメント (comment)
(required)

※クッキーに保存すると次回から入力を省略できるので便利ですが、お使いのコンピュータに情報が残りますので、公共のパソコンなどからアクセスするような場合はチェックをはずしたほうがよいでしょう。

※コメント中のhtmlタグは実体参照に変換されます。たとえば、『<』は『&lt;』というかんじになりますのでhtmlタグをそのまま書き込んでくださってオッケーです。

one-px-ffffff-tl one-px-ffffff-tr one-px-ffffff-bl one-px-ffffff-br

PROFILEcaption

藤居ヒロヤ。ウェブデザイナー/ウェブディレクター。ウェブデザインオフィス、3OT NET主宰。名古屋市中区。「優しいデザイン」「激しいデザイン」「正しいデザイン」「セクシーなデザイン」「泣けるデザイン」「もっともなデザイン」... 。あなただけのウェブデザインを丹精込めておつくり致します。見積り依頼等、お気軽にお問い合わせ下さい。

お問い合わせフォーム

RECENT ENTRIEScaption

RECENT COMMENTScaption

TOOLScaption

BOOKMARKScaption

RESOURCEScaption

ARCHIVEcaption