diff --git a/bbs/download.php b/bbs/download.php index f0f70afb7..78c1bff70 100644 --- a/bbs/download.php +++ b/bbs/download.php @@ -22,6 +22,14 @@ $file = sql_fetch($sql); if (!$file['bf_file']) alert_close('파일 정보가 존재하지 않습니다.'); +$nonce = isset($_REQUEST['nonce']) ? preg_replace('/[^0-9a-z\|]/i', '', $_REQUEST['nonce']) : ''; + +if (function_exists('download_file_nonce_is_valid')){ + if(! download_file_nonce_is_valid($nonce, $bo_table, $wr_id)){ + alert('토큰 유효시간이 지났거나 토큰이 유효하지 않습니다.\\n브라우저를 새로고침 후 다시 시도해 주세요.', G5_URL); + } +} + // JavaScript 불가일 때 $js = (isset($_GET['js'])) ? $_GET['js'] : ''; if($js != 'on' && $board['bo_download_point'] < 0) { diff --git a/lib/common.lib.php b/lib/common.lib.php index f6054ec86..98048a048 100644 --- a/lib/common.lib.php +++ b/lib/common.lib.php @@ -295,6 +295,30 @@ function get_filesize($size) return $size; } +// 파일다운로드 링크 생성시 nonce 키 추가, 7200은 2시간동안 유효 +function download_file_nonce_key($bo_table, $wr_id, $timeoutSeconds=7200) +{ + $secret = get_token_encryption_key(sha1($bo_table.session_id().$wr_id)); + $salt = get_random_token_string(10); + $maxTime = G5_SERVER_TIME + $timeoutSeconds; + $nonce = $salt . '|' . $maxTime . '|' . sha1($salt . $secret . $maxTime); + + return $nonce; +} + +// 파일다운로드시 nonce key를 체크한다. +function download_file_nonce_is_valid($nonce, $bo_table, $wr_id) +{ + if (! is_string($nonce)) return false; + $secret = get_token_encryption_key(sha1($bo_table.session_id().$wr_id)); + $a = explode('|', $nonce); + if (count($a) !== 3) return false; + list($salt, $maxTime, $hash) = $a; + if (sha1($salt . $secret . $maxTime) !== $hash) return false; + if (G5_SERVER_TIME > (int) $maxTime) return false; + + return true; +} // 게시글에 첨부된 파일을 얻는다. (배열로 반환) function get_file($bo_table, $wr_id) @@ -304,11 +328,12 @@ function get_file($bo_table, $wr_id) $file['count'] = 0; $sql = " select * from {$g5['board_file_table']} where bo_table = '$bo_table' and wr_id = '$wr_id' order by bf_no "; $result = sql_query($sql); + $nonce = download_file_nonce_key($bo_table, $wr_id); while ($row = sql_fetch_array($result)) { $no = (int) $row['bf_no']; $bf_content = $row['bf_content'] ? html_purifier($row['bf_content']) : ''; - $file[$no]['href'] = G5_BBS_URL."/download.php?bo_table=$bo_table&wr_id=$wr_id&no=$no" . $qstr; + $file[$no]['href'] = G5_BBS_URL."/download.php?bo_table=$bo_table&wr_id=$wr_id&no=$no&nonce=$nonce" . $qstr; $file[$no]['download'] = $row['bf_download']; // 4.00.11 - 파일 path 추가 $file[$no]['path'] = G5_DATA_URL.'/file/'.$bo_table; @@ -579,6 +604,8 @@ function check_html_link_nofollow($type=''){ // Open : HTML Purifier is open-source and highly customizable function html_purifier($html) { + global $is_admin; + $f = file(G5_PLUGIN_PATH.'/htmlpurifier/safeiframe.txt'); $domains = array(); foreach($f as $domain){ @@ -589,8 +616,8 @@ function html_purifier($html) array_push($domains, $domain); } } - // 내 도메인도 추가 - array_push($domains, $_SERVER['HTTP_HOST'].'/'); + // 관리자인 경우에만 내 도메인을 추가 + if ($is_admin) array_push($domains, $_SERVER['HTTP_HOST'].'/'); $safeiframe = implode('|', $domains); include_once(G5_PLUGIN_PATH.'/htmlpurifier/HTMLPurifier.standalone.php');