From 7e65a297bf2aeb661cd3fb87141fcc9f2b91979c Mon Sep 17 00:00:00 2001 From: thisgun Date: Tue, 7 Apr 2026 08:03:21 +0000 Subject: [PATCH] =?UTF-8?q?[KVE-2026-0608]=EA=B7=B8=EB=88=84=EB=B3=B4?= =?UTF-8?q?=EB=93=9C5=20Race=20Condition=20=EC=B7=A8=EC=95=BD=EC=A0=90=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - bbs/poll_update.php: 설문조사 중복 투표 방지 (FIND_IN_SET을 WHERE에 포함한 원자적 UPDATE) - bbs/good.php: 추천/비추천 카운터 부풀리기 방지 (INSERT IGNORE 우선 후 카운터 증가) - lib/common.lib.php: insert_point() 포인트 중복 지급 방지 (MySQL named lock GET_LOCK 사용) --- bbs/good.php | 27 +++++++++++++++------- bbs/poll_update.php | 56 +++++++++++++++------------------------------ lib/common.lib.php | 15 +++++++++++- 3 files changed, 52 insertions(+), 46 deletions(-) diff --git a/bbs/good.php b/bbs/good.php index d0f66d802..84a8ed93d 100644 --- a/bbs/good.php +++ b/bbs/good.php @@ -76,16 +76,22 @@ if(isset($_POST['js']) && $_POST['js'] === "on") { } else { - // 추천(찬성), 비추천(반대) 카운트 증가 + // 레이스 컨디션 방지: g5_board_good 테이블의 UNIQUE KEY(bo_table, wr_id, mb_id)를 + // 이용해 INSERT IGNORE를 먼저 수행하고, 성공한 경우에만 카운터를 증가시킨다. + sql_query(" insert ignore into {$g5['board_good_table']} set bo_table = '{$bo_table}', wr_id = '{$wr_id}', mb_id = '{$member['mb_id']}', bg_flag = '{$good}', bg_datetime = '".G5_TIME_YMDHIS."' "); + if (get_sql_affected_rows() <= 0) { + $error = '이미 추천 또는 비추천 하신 글 입니다.'; + print_result($error, $count); + } + + // INSERT 성공 시에만 카운터 증가 sql_query(" update {$g5['write_prefix']}{$bo_table} set wr_{$good} = wr_{$good} + 1 where wr_id = '{$wr_id}' "); - // 내역 생성 - sql_query(" insert {$g5['board_good_table']} set bo_table = '{$bo_table}', wr_id = '{$wr_id}', mb_id = '{$member['mb_id']}', bg_flag = '{$good}', bg_datetime = '".G5_TIME_YMDHIS."' "); $sql = " select wr_{$good} as count from {$g5['write_prefix']}{$bo_table} where wr_id = '$wr_id' "; $row = sql_fetch($sql); $count = $row['count']; - + run_event('bbs_increase_good_json', $bo_table, $wr_id, $good); print_result($error, $count); @@ -140,10 +146,15 @@ if(isset($_POST['js']) && $_POST['js'] === "on") { } else { - // 추천(찬성), 비추천(반대) 카운트 증가 + // 레이스 컨디션 방지: g5_board_good 테이블의 UNIQUE KEY(bo_table, wr_id, mb_id)를 + // 이용해 INSERT IGNORE를 먼저 수행하고, 성공한 경우에만 카운터를 증가시킨다. + sql_query(" insert ignore into {$g5['board_good_table']} set bo_table = '{$bo_table}', wr_id = '{$wr_id}', mb_id = '{$member['mb_id']}', bg_flag = '{$good}', bg_datetime = '".G5_TIME_YMDHIS."' "); + if (get_sql_affected_rows() <= 0) { + alert('이미 추천 또는 비추천 하신 글 입니다.'); + } + + // INSERT 성공 시에만 카운터 증가 sql_query(" update {$g5['write_prefix']}{$bo_table} set wr_{$good} = wr_{$good} + 1 where wr_id = '{$wr_id}' "); - // 내역 생성 - sql_query(" insert {$g5['board_good_table']} set bo_table = '{$bo_table}', wr_id = '{$wr_id}', mb_id = '{$member['mb_id']}', bg_flag = '{$good}', bg_datetime = '".G5_TIME_YMDHIS."' "); if ($good == 'good') $status = '추천'; @@ -151,7 +162,7 @@ if(isset($_POST['js']) && $_POST['js'] === "on") { $status = '비추천'; $href = get_pretty_url($bo_table, $wr_id); - + run_event('bbs_increase_good_html', $bo_table, $wr_id, $good, $href); alert("이 글을 $status 하셨습니다.", '', false); diff --git a/bbs/poll_update.php b/bbs/poll_update.php index d6fb5d809..66b2aee3f 100644 --- a/bbs/poll_update.php +++ b/bbs/poll_update.php @@ -14,50 +14,32 @@ $gb_poll = isset($_POST['gb_poll']) ? preg_replace('/[^0-9]/', '', $_POST['gb_po if(!$gb_poll) alert_close('항목을 선택하세요.'); -$search_mb_id = false; -$search_ip = false; - -if($is_member) { - // 투표했던 회원아이디들 중에서 찾아본다 - $ids = explode(',', trim($po['mb_ids'])); - for ($i=0; $i