기본값 있는 $strDate 뒤에 기본값 없는 $nCount 가 선언되어 PHP 8.0+
에서 경고가 발생하던 것을 $nCount=0 기본값 부여로 해소.
- plugin/sms5/sms5.lib.php: Add(), Add2()
- lib/icode.lms.lib.php: Add() (LMS 부모 클래스 동일 패턴)
LMS 분기 호출부는 $strDate, $nCount 를 항상 함께 전달하므로
동작 변화 없음. PHP 5.2~8.3 호환 유지.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- adm/shop_admin/orderform.php: 주문상세 hidden 의 od_hp 출력에
get_text() 적용 (인접한 od_name 과 동일 처리, 누락분 보완)
- bbs/member_cert_refresh_update.php: 본인확인 갱신 후 이동 URL 에
check_url_host() 적용
- plugin/social/includes/functions.php: 소셜 로그인/연동 후 이동
URL 2곳에 동일하게 check_url_host() 적용
login_check.php 등 기존 코드와 동일한 호스트 검증 패턴으로,
같은 도메인/상대경로 복귀는 그대로 동작하고 타 도메인 이동만 차단.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
토스페이먼츠 결제 요청 폼의 customerName hidden 필드에 주문자명
($od_name)이 인코딩 없이 출력되던 것을 get_text() 적용으로 정리.
직전 주문 필드 인코딩 처리와 동일한 맥락의 마무리.
hidden value 의 엔티티는 결제 SDK 가 값을 읽을 때 브라우저가
디코딩하므로 토스로 전달되는 구매자명에는 영향 없음.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
영카트 주문자명/받는분/입금자명(od_name, od_b_name, od_deposit_name)
이 일부 출력 지점에서 인코딩 없이 노출되어, 저장된 값이 HTML/속성
컨텍스트에서 그대로 렌더링되던 문제 수정. 다음 출력에 get_text() 적용:
- adm/shop_admin/orderform.php, sale1today.php (관리자 주문 화면)
- shop/orderinquiryview.php (PC/모바일/테마 주문조회)
- shop/{inicis,kcp,lg,nicepay,toss}/taxsave_form.php (현금영수증 발행 폼)
- shop/mail/orderupdate{1,2,3}.mail.php, ordermail.mail.php (주문 메일)
비회원 주문 시 입력값이 관리자 화면에서 실행될 수 있는 경로를 차단.
폼 value 의 엔티티는 브라우저 제출 시 디코딩되므로 PG 전송값 및
정상 표시에는 영향 없음.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
.gitignore 에는 이미 data/ 가 등록되어 있으나 data/.htaccess
한 파일이 이전부터 트래킹되고 있어 배포본에 함께 포함되던 문제 정리.
디스크 파일은 그대로 두고 인덱스에서만 제거.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
KCP 가이드 개정으로 가상계좌 발급 정상 응답이 0000 에서 V000 으로
변경되어, 기존 코드가 발급 성공을 실패로 인식하던 문제를 수정.
결제 hub 의 res_cd 비교 두 곳에서 V000 을 0000 과 동등하게 처리.
가상계좌 입금 완료 처리는 Webhook 입금통보가 담당하므로 본 변경과
무관. 취소/현금영수증/본인인증 경로는 V000 응답 대상이 아니므로
0000 단독 비교 유지.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
카카오 우편번호 서비스의 oncomplete 콜백이 userSelectedType
으로 'R'(도로명) 또는 'J'(지번)을 반환하는데, 서버 측 정규식이
'N|R' 만 허용해 지번 선택 시 빈 문자열로 저장되던 문제를 수정.
N 은 print_address() 의 도로명 표기 분기를 위한 레거시 값으로
호환을 위해 유지.
적용 위치: 회원가입(bbs/register_form_update.php), PC/모바일
주문(shop/, mobile/shop/ orderformupdate.php), 관리자 미완료
주문(adm/shop_admin/inorderformupdate.php) 의 7곳.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
lib/common.lib.php 에 csv_safe_cell() 헬퍼 추가 (function_exists
가드 포함). 셀 값이 = + - @ TAB CR 로 시작하면 작은따옴표를 prefix
하여 스프레드시트가 수식으로 해석하지 못하도록 변환.
다음 출력 지점에서 사용자 입력 컬럼에 적용:
- adm/shop_admin/orderprintresult.php (CSV + XLS 두 분기)
- adm/shop_admin/orderdeliveryexcel.php
- adm/member_list_exel_export.php
- adm/sms_admin/num_book_file_download.php
호출부는 function_exists('csv_safe_cell') ? ... : 원본 폴백 형태로
감싸서 lib 미업데이트 환경에서도 fatal error 없이 동작하도록 함.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
이전 커밋(e53689ac3)의 미수금 처리 방식은 사용자에게 결제 금액과
다른 청구가 발생해 혼란/분쟁을 유발할 수 있어, 동시 주문 race 로
포인트 잔액이 부족하면 결제 자체를 취소하는 방식으로 변경.
- PG 결제가 진행된 경우 (\$tno 존재): cancel_pg.inc.php 로 환불 요청
- 장바구니 복구: 기존 line 839 동일 패턴 (od_id = tmp_cart_id, ct_status = '쇼핑')
- 주문 삭제: g5_shop_order_table 에서 od_id 제거
- 사용자에게 die 로 명확한 오류 메시지 표시
lock timeout 케이스도 동일하게 결제 취소 처리 (보수적).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
shop/orderformupdate.php / mobile/shop/orderformupdate.php 의 포인트
검증과 차감 사이에 TOCTOU race 가 존재하여, 동일 회원이 여러 세션으로
동시에 주문 제출 시 같은 포인트 잔액을 반복 검증 통과 → 다중 차감으로
mb_point 가 음수가 되는 double spend 가 가능했음.
insert_point() 의 기존 named lock 은 (mb_id, rel_table, rel_id, rel_action)
조합 키 기반이라 서로 다른 od_id 주문 간에는 lock 이 다르고, 주문 차감
호출에 rel_* 가 전달되지 않아 lock 미적용 상태였음.
조치: KVE-2026-0687 (쇼핑몰 쿠폰) 와 동일한 회원 단위 MySQL GET_LOCK
패턴을 적용. lock 획득 후 g5_point SUM 으로 잔액을 재조회하여
- 충분하면 정상 차감
- race 로 부족하면 사용 가능한 만큼만 차감 + 부족분은 od_receipt_point
보정 + od_misu(미수금) 으로 반영하여 매장 손실 방지.
MyISAM 정책상 트랜잭션 금지이므로 named lock 으로 직렬화하는 방식이
가장 적합. 데스크톱·모바일 동일 패턴 적용.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
KVE-2026-0876 동일 패턴 추가 발견 5건 일괄 수정.
- shop/itemuselist.php / mobile/shop/itemuselist.php (상품후기 목록)
- shop/itemqalist.php / mobile/shop/itemqalist.php (상품문의 목록)
→ 비회원 접근 가능한 공개 페이지에서 sst/sod 가 ORDER BY 절에
검증 없이 삽입되어 CASE WHEN/SLEEP 기반 blind SQLi 가능했음.
sst 는 컬럼 화이트리스트, sod 는 asc/desc 정규식으로 검증.
- bbs/list.php (게시판 목록)
→ sst 는 wr_datetime/wr_hit/wr_good/wr_nogood 화이트리스트 적용
되어 있으나 sod 가 검증 누락되어 ORDER BY 절에 함수 표현식
삽입이 가능했음. sod 에 asc/desc 정규식 검증 추가.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
shop/kcp/pp_cli_hub_lib.php, shop/kcp/pp_ax_hub_lib.php 의
mf_do_tx() Windows 분기가 사용자 입력이 포함된 KCP CLI 인자를
큰따옴표로 감싼 단일 문자열로 만들어 mf_exec() 첫 인자로 전달했고,
mf_exec() 는 첫 인자를 escape 없이 exec() 에 넘겨 Windows cmd.exe
메타문자(`"`, `&` 등)로 인증 없는 OS 명령 실행이 가능했음.
Linux 분기와 동일하게 실행 파일 경로와 콤마 구분 인자 문자열을
분리하여 mf_exec($bin_exe, $args) 형태로 호출하도록 변경.
mf_exec() 의 foreach 가 두 번째 이후 인자에 escapeshellarg() 를
자동 적용하여 cmd.exe 메타문자가 안전하게 wrapping 됨.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- adm/qa_config_update.php / adm/contentformupdate.php :
qa_include_head/tail, co_include_head/tail 가 super 가드 없이 변경 가능해
하위 관리자가 임의 PHP 경로를 include 시킬 수 있던 LFI 위험을
board_form_update.php 와 동일한 패턴(super 외에는 기존 값 유지)으로 차단.
- adm/member_form_update.php / adm/member_list_update.php :
신규 회원 생성·일괄 수정 시 부여하려는 mb_level 상한 검증이 없어
하위 관리자가 자기보다 높은 등급을 부여할 수 있던 권한 상승을 차단.
- adm/shop_admin/categorylistupdate.php /
adm/shop_admin/itemformupdate.php :
is_include_path_check 호출에서 두 번째 인자(is_input=1) 누락으로
rar/php/zip wrapper 등 경로 wrapper 차단이 동작하지 않던 부분을
is_include_path_check($file, 1) 로 강화.
- adm/shop_admin/orderdeliveryupdate.php /
adm/shop_admin/orderpartcancelupdate.php /
adm/sendmail_test.php :
상태 변경 동작에 check_admin_token() 누락으로 발생하던 CSRF 위험을
토큰 검증 추가로 차단. sendmail_test 폼에는 hidden token 필드 추가.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
install/install_db.php 의 g5_shop_prefix 가 dbconfig.php 의
define('G5_SHOP_TABLE_PREFIX','...') 문자열에 작은따옴표 escape 없이
삽입되어, 설치 전 노출된 인스톨러를 통해 임의 PHP 코드 주입 후 RCE
가능하던 문제를 수정. table_prefix·admin_id 와 동일하게 [^0-9a-z_]+
정규식 검증을 추가하여 영문자·숫자·언더스코어만 허용하도록 함.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
view_comment.skin.php 8종(skin/, mobile/skin/, theme/basic/ 하위 basic·
gallery)에서 댓글 수정($w == 'cu') 시 \$c_wr_content 가 textarea 내부에
이스케이프 없이 출력되어 </textarea> 페이로드로 탈출 가능하던 문제를
get_text() 적용으로 일괄 수정. 게시글 본문 수정(bbs/write.php) 과
동일한 escape 패턴을 댓글 수정에도 적용함.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
bbs/move_update.php 가 원본 게시판 기준 $is_admin 만 검사하고 사용자
입력 chk_bo_table[] 의 대상 게시판에 대해서는 존재 여부만 확인하던
문제를 수정. 게시판 관리자(board)·그룹 관리자(group) 권한일 경우
대상 게시판의 bo_admin 또는 그룹의 gr_admin 이 본인인지 재검증하고,
일치하지 않으면 해당 대상 게시판 처리를 건너뛰도록 함. super 관리자는
기존 동작 유지.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
bbs/alert.php, bbs/alert_close.php 가 alert("$msg") 형태로 메시지를
JS 문자열 컨텍스트에 직접 삽입하던 부분을 수정. lib/common.lib.php 에
PHP 5.2 호환 폴백을 갖춘 get_js_safe_string() 헬퍼를 추가하고,
호출부에는 function_exists 가드를 걸어 부분 패치 환경에서도 안전하게
폴백되도록 함.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
XenoPostToForm::makeInputArray() 에서 POST 값·배열 인덱스는 이스케이프
되지만 최상위 POST 키 이름이 name 속성에 그대로 삽입되던 문제를 수정.
재귀 진입 시점에 htmlspecialchars() 로 키를 이스케이프하여 모든 깊이에서
안전하도록 함.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
MySQL GET_LOCK 으로 동일 회원·동일 쿠폰 다운로드 요청을 직렬화하여,
동시 요청 시 is_coupon_downloaded() 체크를 중복 통과해 쿠폰이 중복
발급되는 문제를 방지함.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
수신설정 섹션이 폼에 표시되지 않는 경우(cf_use_promotion 미사용, 휴대폰 미사용,
아이코드 미사용 등) _default 변수가 undefined 상태가 되어 비교 시 항상 "변경됨"으로
판단되던 문제를 해결. _default 변수를 명시적으로 초기화하고, 폼에 없는 항목은
기존 DB 값을 유지하도록 수정.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
rand() 대신 CSPRNG 기반 get_random_token_string() 사용
- mb_nonce: 128비트 CSPRNG 토큰으로 시드 브루트포스 차단
- change_password: CSPRNG 기반 10자리 hex로 변경
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
skin_dir 파라미터에 디렉토리 트래버설 검증이 없어
임의 경로의 PHP 파일을 include할 수 있는 취약점을
clean_relative_paths()로 경로 조작 문자열 제거하여 수정
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
$_SERVER['REQUEST_URI']를 JavaScript 문자열에 이스케이프 없이
출력하여 URL을 통한 Reflected XSS가 가능한 취약점을
json_encode()로 안전하게 이스케이프 처리
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
popup.php에서 mylink 진입 시 Referer 검증 및 세션 토큰 설정
functions.php에서 social_user_profile_replace() 호출 전 세션 토큰 검증
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
비회원 폼메일 발송 시 From 헤더를 관리자 이메일로 고정하고 사용자 입력은 Reply-To로 설정
formmail_send.php에 세션 기반 발송 횟수 제한 추가 (직접 POST 우회 방지)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
register_email_update.php에 로그인 검증·소유권 강제·ckey HMAC 검증·SQL 이스케이프 추가
member_cert_refresh_update.php에 로그인 검증 및 소유권 강제 추가 (연관 IDOR 선제 조치)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
sql_query()의 에러 처리가 die()로 SQL 쿼리 전문, MySQL 에러 메시지,
스크립트 파일 경로를 사용자에게 그대로 노출하고 있었음. 기본값
G5_DISPLAY_SQL_ERROR=false 덕분에 일반 호출에서는 트리거되지 않으나,
일부 admin 파일이 명시적으로 sql_query(\$sql, true)로 호출하여
관리자에게 raw SQL을 노출했고, SQLi 공격 시도 중 발생한 에러로 DB
구조(테이블/컬럼명)가 학습되어 정밀 공격에 활용될 수 있었음.
조치:
- 서버 로그(error_log)에는 항상 상세 기록 → 운영자가 디버깅 가능
- \$is_debug 모드(G5_DEBUG=true 또는 super admin)에서만 상세 표시
+ XSS 방지를 위해 htmlspecialchars로 escape
- 그 외 환경에서는 "데이터베이스 처리 중 오류가 발생했습니다." 만 표시
- mysqli/mysql 폴백 분기 둘 다 동일하게 적용
변경:
- lib/common.lib.php:1932 (mysqli 분기)
- lib/common.lib.php:1942 (mysql 분기, 레거시 PHP 5.x 폴백)
PHP 5.2.17 호환 유지 (htmlspecialchars + ENT_QUOTES 모두 PHP 4.0+).