私は最近、関連する問題を抱えており、それについてこの記事を書きました。
ダウンロードは、WordPressのメディア処理を介してアップロードされると仮定します-または、ダウンロード用の添付ファイルIDを持っていることを前提としています。
ソリューションの概要
- (この意味でI「確保」アップロードディレクトリを作成するだけで平均使用
.htaccess
-などを経由してアップロードディレクトリ(またはそのサブディレクトリ)内のファイルに直接アクセスしようとする試みを阻止するためにmysite.com/wp-content/uploads/conf/2012/09/myconfidentialfile.pdf
)
- 添付ファイルIDを含むダウンロードリンクを作成します-これはWordPressを通過して、添付ファイルを表示するユーザーのアクセス許可を確認し、アクセスを許可/拒否します。
注意事項
- これは
.htaccess
セキュリティを提供するために利用します。これが利用できない/オンになっていない場合(nginxサーバーなど)、セキュリティはあまり得られません。ユーザーがuplodsディレクトリを参照しないようにすることができます。ただし、直接アクセスは機能します。
- 上記の通り。絶対的なセキュリティが必要な場合は、これを配布で使用しないでください。特定の設定が機能する場合は問題ありませんが、一般的には保証できません。私のリンクされた記事は部分的にこれに対処しようとしています。
- サムネイルを失います。フォルダーまたはサブフォルダーへの直接アクセスをブロックすると、そのフォルダー内のファイルのサムネイルを表示できなくなります。私のリンクされた記事の一部はこれに対処しようとしています。
直接アクセスのブロック
アップロードフォルダー(またはサブフォルダー-すべての機密資料は、このフォルダー内の任意の深さで存在する必要があります)でこれを行うには。.htaccess
次のファイルを配置します。
Order Deny,Allow
Deny from all
以下では、投稿タイプ「クライアント」に機密資料を添付することを想定しています。クライアント編集ページにアップロードされたメディアはすべてuploads/conf/
フォルダーに保存されます
保護されたアップロードディレクトリをセットアップする機能
function wpse26342_setup_uploads_dir(){
$wp_upload_dir = wp_upload_dir();
$protected_folder = trailingslashit($wp_upload_dir['basedir']) . 'conf';
// Do not allow direct access to files in protected folder
// Add rules to /uploads/conf/.htacess
$rules = "Order Deny,Allow\n";
$rules .= "Deny from all";
if( ! @file_get_contents( trailingslashit($protected_folder).'.htaccess' ) ) {
//Protected directory doesn't exist - create it.
wp_mkdir_p( $protected_folder);
}
@file_put_contents( trailingslashit($protected_folder).'.htaccess', $rules );
//Optional add blank index.php file to each sub-folder of protected folder.
}
機密資料のアップロード
/**
* Checks if content is being uploaded on the client edit-page
* Calls a function to ensure the protected file has the .htaccess rules
* Filters the upload destination to the protected file
*/
add_action('admin_init', 'wpse26342_maybe_change_uploads_dir', 999);
function wpse26342_maybe_change_uploads_dir() {
global $pagenow;
if ( ! empty( $_POST['post_id'] ) && ( 'async-upload.php' == $pagenow || 'media-upload.php' == $pagenow ) ) {
if ( 'client' == get_post_type( $_REQUEST['post_id'] ) ) {
//Uploading content on the edit-client page
//Make sure uploads directory is protected
wpse26342_setup_uploads_dir();
//Change the destination of the uploaded file to protected directory.
add_filter( 'upload_dir', 'wpse26342_set_uploads_dir' );
}
}
}
それが完了したら、アップロードされたコンテンツは内部にuploads/conf
あり、ブラウザを使用して直接アクセスしようとしても機能しません。
コンテンツをダウンロードする
これは簡単です。ダウンロードURLには何かを指定できますwww.site.com?wpse26342download=5
(5はアップロードされたコンテンツの添付IDです)。これを使用して、添付ファイルを識別し、現在のユーザーの権限を確認し、ダウンロードを許可します。
まず、クエリ変数を設定します
/**
* Adds wpse26342download to the public query variables
* This is used for the public download url
*/
add_action('query_vars','wpse26342_add_download_qv');
function wpse26342_add_download_qv( $qv ){
$qv[] = 'wpse26342download';
return $qv;
}}
次に、(おそらく)ダウンロードをトリガーするリスナーを設定します...
add_action('request','wpse26342_trigger_download');
function wpse26342_trigger_download( $query_vars ){
//Only continue if the query variable set and user is logged in...
if( !empty($query_vars['wpse26342download']) && is_user_logged_in() ){
//Get attachment download path
$attachment = (int) $query_vars['wpse26342download'];
$file = get_attached_file($attachment);
if( !$file )
return;
//Check if user has permission to download. If not abort.
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($file));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
exit();
}
return $query_vars;
}
最終コメント
上記のコードにはバグ/構文エラーが含まれている可能性があり、テストされていません。ご自身の責任で使用してください:)。
ダウンロードURLは、書き換えを使用して「プリティ」にすることができます。コメントで述べたように、index.php
閲覧を防ぐために保護されたフォルダのすべての子の内側に空白を追加することができます-しかし、これは.htaccess
とにかくルールによって防止されるべきです。
より安全な方法は、パブリックディレクトリの外部にパブリックファイルを保存することです。または、Amazon S3のような外部サービスで。後者の場合、有効なURLを生成してAmazonからファイルを取得する必要があります(秘密キーを使用)。これらは両方とも、ホスト/サードパーティサービスに対する一定レベルの信頼を必要とします。
私は、それらが「保護されたダウンロード」を提供することを示唆するプラグインを使用することには警戒します。十分なセキュリティを提供するものは見つかりませんでした。このソリューションの注意事項も避けてください-提案や批判を歓迎します。