ฉันเพิ่งมีปัญหาที่เกี่ยวข้องและเขียนบทความเกี่ยวกับเรื่องนี้
ฉันจะสมมติว่าการดาวน์โหลดถูกอัพโหลดผ่านการจัดการสื่อของ WordPress - หรือคุณมี ID ไฟล์แนบสำหรับการดาวน์โหลด
เค้าร่างของการแก้ปัญหา
- ทำให้ภาพที่ส่งไดเรกทอรี 'ความปลอดภัย' (ในความรู้สึกนี้ฉันเพียงแค่ใช้ค่าเฉลี่ย
.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 คือรหัสสิ่งที่แนบมาของเนื้อหาที่อัปโหลด) เราใช้สิ่งนี้เพื่อระบุสิ่งที่แนบมาตรวจสอบการอนุญาตของผู้ใช้ปัจจุบันและอนุญาตให้ดาวน์โหลด
ก่อนอื่นให้ตั้งค่าตัวแปรคิวรี
/**
* 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 การดาวน์โหลดสามารถ 'prettified' โดยใช้การเขียนซ้ำ ตามที่ระบุไว้ในความคิดเห็นที่คุณสามารถเพิ่มว่างเปล่าindex.php
ภายในลูกของโฟลเดอร์ที่มีการป้องกันทุกคนที่จะป้องกันไม่ให้เกิดการเรียกดู - แต่นี้ควรได้รับการป้องกันโดย.htaccess
กฎระเบียบอยู่แล้ว
วิธีที่ปลอดภัยกว่านั้นก็คือการจัดเก็บไฟล์สาธารณะนอกไดเรกทอรีสาธารณะ หรือในบริการภายนอกเช่น Amazon S3 สำหรับหลังคุณจะต้องสร้าง URL ที่ถูกต้องเพื่อดึงไฟล์จาก Amazon (ใช้รหัสส่วนตัวของคุณ) ทั้งสองสิ่งนี้ต้องการความเชื่อถือในระดับหนึ่งในบริการโฮสต์ / บุคคลที่สามของคุณ
ฉันจะระมัดระวังเกี่ยวกับการใช้ปลั๊กอินใด ๆ ที่แนะนำให้พวกเขาเสนอ 'ดาวน์โหลดที่ได้รับการป้องกัน' ฉันไม่พบสิ่งใดที่ให้ความปลอดภัยที่ดีพอ โปรดอย่าข้อเตือนใจของการแก้ปัญหานี้ด้วย - และฉันยินดีรับข้อเสนอแนะหรือคำวิจารณ์