[security]KVE-2026-0687 쇼핑몰 쿠폰 다운로드 TOCTOU Race Condition 수정
MySQL GET_LOCK 으로 동일 회원·동일 쿠폰 다운로드 요청을 직렬화하여, 동시 요청 시 is_coupon_downloaded() 체크를 중복 통과해 쿠폰이 중복 발급되는 문제를 방지함. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
b12bf551ec
commit
efaefbbd0e
@@ -18,13 +18,23 @@ if(!$cp['cz_id'])
|
||||
if(!($cp['cz_start'] <= G5_TIME_YMD && $cp['cz_end'] >= G5_TIME_YMD))
|
||||
die(json_encode(array('error' => '다운로드할 수 없는 쿠폰입니다.')));
|
||||
|
||||
// 발급여부
|
||||
if(is_coupon_downloaded($member['mb_id'], $cp['cz_id']))
|
||||
// 동시 요청으로 인한 쿠폰 중복 발급 방지
|
||||
$lock_key = 'g5_coupon_dl_'.$cz_id.'_'.addslashes($member['mb_id']);
|
||||
$lock_row = sql_fetch(" select get_lock('$lock_key', 5) as lk ");
|
||||
if(empty($lock_row['lk']))
|
||||
die(json_encode(array('error' => '잠시 후 다시 시도해 주십시오.')));
|
||||
|
||||
// 발급여부 (락 획득 후 재확인)
|
||||
if(is_coupon_downloaded($member['mb_id'], $cp['cz_id'])) {
|
||||
sql_query(" do release_lock('$lock_key') ");
|
||||
die(json_encode(array('error' => '이미 다운로드하신 쿠폰입니다.')));
|
||||
}
|
||||
|
||||
// 포인트 쿠폰은 회원포인트 체크
|
||||
if($cp['cz_type'] && ($member['mb_point'] - $cp['cz_point']) < 0)
|
||||
if($cp['cz_type'] && ($member['mb_point'] - $cp['cz_point']) < 0) {
|
||||
sql_query(" do release_lock('$lock_key') ");
|
||||
die(json_encode(array('error' => '보유하신 포인트가 부족하여 쿠폰을 다운로드할 수 없습니다.')));
|
||||
}
|
||||
|
||||
// 쿠폰발급
|
||||
$j = 0;
|
||||
@@ -37,8 +47,10 @@ do {
|
||||
if(!$row3['cnt'])
|
||||
break;
|
||||
else {
|
||||
if($j > 20)
|
||||
if($j > 20) {
|
||||
sql_query(" do release_lock('$lock_key') ");
|
||||
die(json_encode(array('error' => 'Coupon ID Error')));
|
||||
}
|
||||
}
|
||||
$j++;
|
||||
} while(1);
|
||||
@@ -65,4 +77,6 @@ if($result && $cp['cz_type'])
|
||||
// 다운로드 증가
|
||||
sql_query(" update {$g5['g5_shop_coupon_zone_table']} set cz_download = cz_download + 1 where cz_id = '$cz_id' ");
|
||||
|
||||
sql_query(" do release_lock('$lock_key') ");
|
||||
|
||||
die(json_encode(array('error' => '')));
|
||||
|
||||
Reference in New Issue
Block a user