From 6afae656121e65ed75e9fe77dc9c7d74837a5649 Mon Sep 17 00:00:00 2001 From: Arcturus Date: Sat, 5 Oct 2024 05:50:43 +0900 Subject: [PATCH] patch secure: https://github.com/gnuboard/gnuboard5/commit/c95168fb0ce0d8ca2253a43cc08b339a82989535 and update --- AvocadoEdition_Light/adm/admin.lib.php | 7 +- AvocadoEdition_Light/bbs/login_check.php | 2 +- AvocadoEdition_Light/common.php | 2 + AvocadoEdition_Light/lib/common.lib.php | 82 ++++++++++++++++++++++-- AvocadoEdition_Light/lib/url.lib.php | 11 ---- 5 files changed, 83 insertions(+), 21 deletions(-) diff --git a/AvocadoEdition_Light/adm/admin.lib.php b/AvocadoEdition_Light/adm/admin.lib.php index df9ca90..91d44e7 100644 --- a/AvocadoEdition_Light/adm/admin.lib.php +++ b/AvocadoEdition_Light/adm/admin.lib.php @@ -457,13 +457,12 @@ if (!$member['mb_id']) { } } -// 관리자의 아이피, 브라우저와 다르다면 세션을 끊고 관리자에게 메일을 보낸다. -$admin_key = md5($member['mb_datetime'] . $_SERVER['REMOTE_ADDR'] . $_SERVER['HTTP_USER_AGENT']); -if (get_session('ss_mb_key') !== $admin_key) { - +// 관리자의 클라이언트를 검증하여 일치하지 않으면 세션을 끊고 관리자에게 메일을 보낸다. +if (!verify_mb_key($member)) { session_destroy(); include_once(G5_LIB_PATH . '/mailer.lib.php'); + // 메일 알림 mailer($member['mb_nick'], $member['mb_email'], $member['mb_email'], 'XSS 공격 알림', $_SERVER['REMOTE_ADDR'] . ' 아이피로 XSS 공격이 있었습니다.\n\n관리자 권한을 탈취하려는 접근이므로 주의하시기 바랍니다.\n\n해당 아이피는 차단하시고 의심되는 게시물이 있는지 확인하시기 바랍니다.\n\n' . G5_URL, 0); diff --git a/AvocadoEdition_Light/bbs/login_check.php b/AvocadoEdition_Light/bbs/login_check.php index b794d05..d77c624 100644 --- a/AvocadoEdition_Light/bbs/login_check.php +++ b/AvocadoEdition_Light/bbs/login_check.php @@ -46,7 +46,7 @@ if (!(defined('SKIP_SESSION_REGENERATE_ID') && SKIP_SESSION_REGENERATE_ID)) { } set_session('ss_mb_id', $mb['mb_id']); -set_session('ss_mb_key', md5($mb['mb_datetime'] . $_SERVER['REMOTE_ADDR'] . $_SERVER['HTTP_USER_AGENT'])); +generate_mb_key($mb); if ($config['cf_use_point']) { $sum_point = get_point_sum($mb['mb_id']); diff --git a/AvocadoEdition_Light/common.php b/AvocadoEdition_Light/common.php index 60fa0dd..9494a64 100644 --- a/AvocadoEdition_Light/common.php +++ b/AvocadoEdition_Light/common.php @@ -276,6 +276,8 @@ include_once G5_LIB_PATH . '/get_data.lib.php'; include_once G5_LIB_PATH . '/cache.lib.php'; include_once G5_LIB_PATH . '/url.lib.php'; +$g5_object = new G5_object_cache(); + //============================================================================== // 공통 //------------------------------------------------------------------------------ diff --git a/AvocadoEdition_Light/lib/common.lib.php b/AvocadoEdition_Light/lib/common.lib.php index 3e447c7..a8dfc5a 100644 --- a/AvocadoEdition_Light/lib/common.lib.php +++ b/AvocadoEdition_Light/lib/common.lib.php @@ -685,9 +685,22 @@ function get_sql_search($search_ca_name, $search_field, $search_text, $search_op // 게시판 테이블에서 하나의 행을 읽음 -function get_write($write_table, $wr_id) +function get_write($write_table, $wr_id, $is_cache = false) { - return sql_fetch(" select * from $write_table where wr_id = '$wr_id' "); + global $g5, $g5_object; + + $wr_bo_table = preg_replace('/^' . preg_quote($g5['write_prefix']) . '/i', '', $write_table); + + $write = $g5_object->get('bbs', $wr_id, $wr_bo_table); + + if (!$write || $is_cache == false) { + $sql = " select * from {$write_table} where wr_id = '{$wr_id}' "; + $write = sql_fetch($sql); + + $g5_object->set('bbs', $wr_id, $write, $wr_bo_table); + } + + return $write; } @@ -1714,7 +1727,7 @@ function get_table_define($table, $crlf = "\n") $kname = 'FULLTEXT|$kname'; } if (!isset($index[$kname])) { - $index[$kname] = []; + $index[$kname] = array(); } if ($sub_part > 1) { $index[$kname][] = $row['Column_name'] . '(' . $sub_part . ')'; @@ -1724,7 +1737,7 @@ function get_table_define($table, $crlf = "\n") } // end while sql_free_result($result); - while (list($x, $columns) = @each($index)) { + foreach ((array) $index as $x => $columns) { $schema_create .= ',' . $crlf; if ($x == 'PRIMARY') { $schema_create .= ' PRIMARY KEY ('; @@ -1740,7 +1753,7 @@ function get_table_define($table, $crlf = "\n") $schema_create .= $crlf . ') ENGINE=MyISAM DEFAULT CHARSET=utf8'; - return $schema_create; + return get_db_create_replace($schema_create); } // end of the 'PMA_getTableDef()' function @@ -2003,6 +2016,53 @@ function check_token() return true; } +/** + * 브라우저 검증을 위한 세션 반환 및 재생성 + * @param array $member 로그인 된 회원의 정보. 가입일시(mb_datetime)를 반드시 포함해야 한다. + * @param bool $regenerate true 이면 재생성 + * @return string + */ +function ss_mb_key($member, $regenerate = false) +{ + $client_key = ($regenerate) ? null : get_cookie('mb_client_key'); + + if (!$client_key) { + $client_key = get_random_token_string(16); + set_cookie('mb_client_key', $client_key, G5_SERVER_TIME * -1); + } + + $mb_key = md5($member['mb_datetime'] . $client_key) . md5($_SERVER['HTTP_USER_AGENT']); + + return $mb_key; +} + +/** + * 회원의 클라이언트 검증 + * @param array $member 로그인 된 회원의 정보. 가입일시(mb_datetime)를 반드시 포함해야 한다. + * @return bool + */ +function verify_mb_key($member) +{ + $mb_key = ss_mb_key($member); + $verified = get_session('ss_mb_key') === $mb_key; + + if (!$verified) { + ss_mb_key($member, true); + } + + return $verified; +} + +/** + * 회원의 클라이언트 검증 키 생성 + * 클라이언트 키를 다시 생성하여 생성된 키는 `ss_mb_key` 세션에 저장됨 + * @param array $member 로그인 된 회원의 정보. 가입일시(mb_datetime)를 반드시 포함해야 한다. + */ +function generate_mb_key($member) +{ + $mb_key = ss_mb_key($member, true); + set_session('ss_mb_key', $mb_key); +} // 문자열에 utf8 문자가 들어 있는지 검사하는 함수 // 코드 : http://in2.php.net/manual/en/function.mb-check-encoding.php#95289 @@ -3526,3 +3586,15 @@ function is_include_path_check($path = '', $is_input = '') return true; } + +function get_random_token_string($length = 6) +{ + if (function_exists('random_bytes')) { + return bin2hex(random_bytes($length)); + } + + $characters = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; + $output = substr(str_shuffle($characters), 0, $length); + + return bin2hex($output); +} diff --git a/AvocadoEdition_Light/lib/url.lib.php b/AvocadoEdition_Light/lib/url.lib.php index 268e66b..98a521a 100644 --- a/AvocadoEdition_Light/lib/url.lib.php +++ b/AvocadoEdition_Light/lib/url.lib.php @@ -295,17 +295,6 @@ function check_case_exist_title($data, $case = G5_BBS_DIR, $is_redirect = false) g5_delete_cache_by_prefix('content-' . $data['co_id'] . '-'); $redirect_url = get_pretty_url($case, $data['co_id']); } - } else if (defined('G5_SHOP_DIR') && $case == G5_SHOP_DIR && isset($data['it_seo_title'])) { - $db_table = $g5['g5_shop_item_table']; - - if (shop_exist_check_seo_title($data['it_seo_title'], $case, $db_table, $data['it_id'])) { - $seo_title = $data['it_seo_title'] . '-' . substr(get_random_token_string(4), 4); - $sql = " update `{$db_table}` set it_seo_title = '" . sql_real_escape_string($seo_title) . "' where it_id = '{$data['it_id']}' "; - sql_query($sql, false); - - get_shop_item($data['it_id'], false); - $redirect_url = get_pretty_url($case, $data['it_id']); - } } if ($is_redirect && $seo_title && $redirect_url) {