From 31b0bb4158e438f495faf97db88a17f53f8aef65 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Wed, 31 Jul 2019 19:25:56 +0900 Subject: [PATCH] Fix #1180 remove session dependency from file download operation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 파일 다운로드시 사용하는 key의 검증 과정에 세션을 사용하지 않도록 변경함. 전자서명을 사용하여 동일한 IP 주소에서 1시간 동안 유효한 key를 생성함. --- modules/file/file.controller.php | 24 +++++++++++++----------- modules/file/lang/en.php | 1 + modules/file/lang/ko.php | 1 + 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/modules/file/file.controller.php b/modules/file/file.controller.php index 420c66851..392511f92 100644 --- a/modules/file/file.controller.php +++ b/modules/file/file.controller.php @@ -423,12 +423,10 @@ class fileController extends file ModuleHandler::triggerCall('file.downloadFile', 'after', $file_obj); // Redirect to procFileOutput using file key - if(!isset($_SESSION['__XE_FILE_KEY__']) || !is_string($_SESSION['__XE_FILE_KEY__']) || strlen($_SESSION['__XE_FILE_KEY__']) != 32) - { - $_SESSION['__XE_FILE_KEY__'] = Rhymix\Framework\Security::getRandom(32, 'hex'); - } - $file_key_data = $file_obj->file_srl . $file_obj->file_size . $file_obj->uploaded_filename . $_SERVER['REMOTE_ADDR']; - $file_key = substr(hash_hmac('sha256', $file_key_data, $_SESSION['__XE_FILE_KEY__']), 0, 32); + $file_key_timestamp = \RX_TIME; + $file_key_data = sprintf('%d:%d:%s:%s', $file_obj->file_srl, $file_key_timestamp, $file_obj->uploaded_filename, \RX_CLIENT_IP); + $file_key_sig = \Rhymix\Framework\Security::createSignature($file_key_data); + $file_key = dechex($file_key_timestamp) . $file_key_sig; header('Location: '.getNotEncodedUrl('', 'act', 'procFileOutput', 'file_srl', $file_srl, 'file_key', $file_key, 'force_download', Context::get('force_download') === 'Y' ? 'Y' : null)); Context::close(); exit(); @@ -446,16 +444,20 @@ class fileController extends file $file_config = $oFileModel->getFileConfig($file_obj->module_srl ?: null); $filesize = $file_obj->file_size; $filename = $file_obj->source_filename; - $etag = md5($file_srl . $file_key . $_SERVER['HTTP_USER_AGENT']); + $etag = md5($file_srl . $file_key . \RX_CLIENT_IP); // Check file key - if(strlen($file_key) != 32 || !isset($_SESSION['__XE_FILE_KEY__']) || !is_string($_SESSION['__XE_FILE_KEY__'])) + if(strlen($file_key) != 48 || !ctype_xdigit(substr($file_key, 0, 8))) { throw new Rhymix\Framework\Exceptions\InvalidRequest; } - $file_key_data = $file_srl . $file_obj->file_size . $file_obj->uploaded_filename . $_SERVER['REMOTE_ADDR']; - $file_key_compare = substr(hash_hmac('sha256', $file_key_data, $_SESSION['__XE_FILE_KEY__']), 0, 32); - if($file_key !== $file_key_compare) + $file_key_timestamp = hexdec(substr($file_key, 0, 8)); + if ($file_key_timestamp < \RX_TIME - 3600) + { + throw new Rhymix\Framework\Exceptions\InvalidRequest('msg_file_key_expired'); + } + $file_key_data = sprintf('%d:%d:%s:%s', $file_srl, $file_key_timestamp, $file_obj->uploaded_filename, \RX_CLIENT_IP); + if (!\Rhymix\Framework\Security::verifySignature($file_key_data, substr($file_key, 8))) { throw new Rhymix\Framework\Exceptions\InvalidRequest; } diff --git a/modules/file/lang/en.php b/modules/file/lang/en.php index 16eb7b425..870a012fb 100644 --- a/modules/file/lang/en.php +++ b/modules/file/lang/en.php @@ -41,6 +41,7 @@ $lang->msg_file_cart_is_null = 'Please select a file(s) to delete.'; $lang->msg_checked_file_is_deleted = '%d attachment(s) was(were) deleted.'; $lang->msg_exceeds_limit_size = 'This file exceeds the attachment limit.'; $lang->msg_file_not_found = 'Could not find requested file.'; +$lang->msg_file_key_expired = 'This download link is expired. Please initiate the download again.'; $lang->file_search_target_list['filename'] = 'File Name'; $lang->file_search_target_list['filesize_more'] = 'File Size(byte, more)'; $lang->file_search_target_list['filesize_mega_more'] = 'File Size(mbyte, more)'; diff --git a/modules/file/lang/ko.php b/modules/file/lang/ko.php index e271e80e7..bc271cbe2 100644 --- a/modules/file/lang/ko.php +++ b/modules/file/lang/ko.php @@ -42,6 +42,7 @@ $lang->msg_checked_file_is_deleted = '%d개의 첨부 파일이 삭제되었습 $lang->msg_exceeds_limit_size = '허용된 용량을 초과하여 첨부가 되지 않았습니다.'; $lang->msg_not_allowed_filetype = '업로드할 수 없는 파일 형식입니다.'; $lang->msg_file_not_found = '요청한 파일을 찾을 수 없습니다.'; +$lang->msg_file_key_expired = '다운로드 링크의 유효기간이 지났습니다. 다시 다운로드하여 주시기 바랍니다.'; $lang->file_search_target_list['filename'] = '파일 이름'; $lang->file_search_target_list['filesize_more'] = '파일 크기(byte, 이상)'; $lang->file_search_target_list['filesize_mega_more'] = '파일 크기(MB, 이상)';