[KVE-2026-1803] 쿠폰번호 생성에 안전한 난수원 적용

get_coupon_id() 가 microtime 기반 시드로 난수 생성기를 재시드하여
생성 가능한 쿠폰번호가 시드 공간 크기로 제한되던 문제를 수정한다.
기존 구현은 33^16 이 아닌 10^6 개의 값만 생성할 수 있어 전체 집합을
사전 계산할 수 있었다.

- get_random_token_string() 으로 난수 바이트를 얻어 쿠폰번호를 구성
- 문자 종류 수로 나누어 떨어지는 구간만 사용하여 문자 분포 편중 제거
- 헬퍼 미정의 환경을 위해 function_exists 가드 및 mt_rand 보완 경로 유지
- 쿠폰번호 형식(16자, 4자리 하이픈 구분)과 사용 문자는 기존과 동일

plugin/lgxpay/lgdacom/XPayClient.php 의 불필요한 재시드 호출 제거

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
(cherry picked from commit a6cf071f405c79904f7861d5e5efc118f29005dc)
This commit is contained in:
thisgun
2026-08-24 07:44:22 +00:00
parent 516eac386f
commit 0ae67a652c
2 changed files with 24 additions and 10 deletions
+24 -9
View File
@@ -1632,17 +1632,32 @@ function get_coupon_id()
{
$len = 16;
$chars = "ABCDEFGHJKLMNPQRSTUVWXYZ123456789";
srand((double)microtime()*1000000);
$i = 0;
$chars_len = strlen($chars);
$str = '';
while ($i < $len) {
$num = rand() % strlen($chars);
$tmp = substr($chars, $num, 1);
$str .= $tmp;
$i++;
if (function_exists('get_random_token_string')) {
// 문자 종류 수로 나누어 떨어지는 구간만 사용하여 특정 문자에 치우치지 않도록 한다.
$limit = 256 - (256 % $chars_len);
$round = 0;
while (strlen($str) < $len && $round < 8) {
$bytes = pack('H*', get_random_token_string($len + 8));
$bytes_len = strlen($bytes);
for ($i = 0; $i < $bytes_len && strlen($str) < $len; $i++) {
$num = ord($bytes[$i]);
if ($num >= $limit)
continue;
$str .= substr($chars, $num % $chars_len, 1);
}
$round++;
}
}
while (strlen($str) < $len) {
$str .= substr($chars, mt_rand(0, $chars_len - 1), 1);
}
$str = preg_replace("/([0-9A-Z]{4})([0-9A-Z]{4})([0-9A-Z]{4})([0-9A-Z]{4})/", "\\1-\\2-\\3-\\4", $str);
-1
View File
@@ -217,7 +217,6 @@ class XPayClient
}
else
{
mt_srand((double)microtime()*10000);//optional for php 4.2.0 and up.
$charid = strtoupper(md5(uniqid(rand(), true)));
$hyphen = chr(45);
//$uuid = chr(123).substr($charid, 0, 8).$hyphen.substr($charid, 8, 4).$hyphen.substr($charid,12, 4).$hyphen.substr($charid,16, 4).$hyphen.substr($charid,20,12).chr(125);