Нещодавно у мене була пов'язана проблема, і я написав про це цю статтю .
Я вважаю, що завантаження завантажуються через обробку медіа WordPress - інакше у вас є ідентифікатор вкладення для завантаження.
Структура рішення
- Зробіть каталог завантажень "захищеним" (У цьому сенсі я просто маю на увазі використання
.htaccess
для блокування будь-якої спроби прямого доступу до файлів у каталозі завантажень (або в його підкаталозі) - наприклад, через mysite.com/wp-content/uploads/conf/2012/09/myconfidentialfile.pdf
)
- Створіть посилання для завантаження, включаючи ідентифікатор вкладеного файлу - це проходить через WordPress, щоб перевірити дозвіл користувача на перегляд вкладення, що дозволяє / забороняє доступ.
Коваджі
- Це використовує
.htaccess
для забезпечення безпеки . Якщо це недоступно / увімкнено (наприклад, nginx-сервери), ви не отримаєте великої безпеки. Ви можете запобігти перегляду користувачем каталогу оновлень. Але прямий доступ спрацює.
- Як зазначено вище. Це не повинно використовуватися для розповсюдження, якщо вам потрібна абсолютна безпека . Це добре, якщо ваша конкретна установка працює - але в цілому, це не може бути гарантовано. Моя пов'язана стаття частково намагається вирішити це питання.
- Ви втратите мініатюри . Блокування прямого доступу до папки або підпапки означатиме, що ескізи файлів у цій папці неможливо переглянути. Моя пов'язана стаття частково намагається вирішити це питання.
Блокування прямого доступу
Для цього в папці завантаження (або в підпапці - весь конфіденційний матеріал повинен знаходитися на будь-якій глибині всередині цієї папки). Помістіть .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-адресу для завантаження можна «уточнити» за допомогою переписувань. Як зазначено в коментарях, ви можете додати порожню index.php
частину всередині кожної дитини в захищеній папці, щоб не переглядати веб-сайт, але це все-таки повинно запобігати .htaccess
правилам.
Більш безпечним методом було б зберігання публічних файлів поза публічним каталогом. Або на зовнішньому сервісі, як Amazon S3. Для останнього вам потрібно створити дійсний URL для отримання файлу з Amazon (використовуючи ваш приватний ключ). І те, і інше вимагає певного рівня довіри до вашого хост / стороннього обслуговування.
Я б насторожено ставлюсь до використання будь-яких плагінів, які дозволяють запропонувати "захищені завантаження". Я не знайшов жодної, яка б забезпечувала достатню безпеку. Будь ласка, не зауважте це рішення - і я вітаю будь-які пропозиції чи зауваження.