유출된 카드가 우리 PG로 돌아왔다
배경
2025년 9월에 국내 대형 카드사에서 개인정보 유출 사건이 있었다. 297만 명분이 털렸고, 그 중 28만 명 정도는 카드번호, 유효기간, CVC, 비밀번호 일부까지 같이 나갔다고 했다. 사건 직후에 카드사 쪽에서는 “현재까지 부정결제 피해는 확인되지 않았다”고 발표했다.
유출 사건은 터진 날 끝나지 않는다. 몇 달 뒤에 현장에서 조용히 드러난다. 유출로부터 대략 7개월이 지난 시점에, 우리 PG로 그 정황으로 보이는 수기결제 2건이 올라왔다. 그때 받은 메일 한 통부터 정리해둔다.
글에 나오는 회사명, 가맹점, TID, 담당자 이름은 전부 가렸다.
T26XXXXXXX로 쓰인 값은 실제 TID가 아니다.
시스템 구조
우리는 2차 PG다. 가맹점과 1차 PG 사이에 껴 있는 중계 구간이다.
1
가맹점 → 2차 PG (우리) → 1차 PG → VAN → 카드사
문제가 된 결제 방식은 카유비생 수기결제였다.
- 카드번호
- 유효기간
- 카드 비밀번호 앞 2자리
- 생년월일 (또는 사업자번호)
이 네 개만 있으면 승인이 떨어진다. 화면에서 사용자가 직접 치는 경우도 있고, 어디서 얻은 값이든 그대로 태워서 요청을 보내면 그만인 구조다. 이번 이슈의 출발은 여기다.
메일 한 통
어느 날 가맹점 개발사에서 메일이 하나 들어왔다.
“주문자와 카드 명의자가 다른데 결제가 정상 진행된 것 같습니다. 확인 부탁드립니다. TID: T26XXXXX032 / T26XXXXX038”
처음엔 단순 검증 누락 이슈인 줄 알았다. 그래서 1차 회신을 이렇게 보냈다.
“1차 PG 구간에서 명의 검증 로직이 정상적으로 동작하지 않았을 가능성이 있어 보입니다…”
메일을 보내고 몇 분 안 돼서 이 문장이 뭔가 이상하다는 걸 알아챘다. 우리 시스템에 없는 기능을 있는 것처럼 써버린 문장이었다.
정정
곧바로 2차 메일을 보내서 정정했다.
“저희 시스템에는 카드 명의자명과 주문자명을 비교하는 로직 자체가 존재하지 않습니다. 앞서 드린 표현은 정확하지 않아 정정합니다.”
카유비생 수기결제가 확인하는 건 사실 두 가지뿐이다.
1
2
1. 카드가 유효한가 (카드번호 + 유효기간)
2. 소지자 인증이 되는가 (비밀번호 + 생년월일)
“주문자명이 카드 명의자와 같은가” 는 어느 레이어에도 안 들어간다. 가맹점 회원정보의 주문자명과 카드사의 카드 소유자 정보는 애초에 다른 데이터다. 가맹점 입장에서는 당연한 상식처럼 느껴지는데, PG, 카드사 쪽 스펙에는 그 항목이 없다.
버그가 아니라 스펙이라는 얘기다.
두 건을 나란히 놓고 봤다
정정 메일 보낸 뒤에 TID 2건을 놓고 비교해봤다.
1
2
3
4
5
6
[TID 1] [TID 2]
카드번호 동일 ← 동일
유효기간 동일 ← 동일
비밀번호 검증 통과 ← 통과
생년월일 검증 통과 ← 통과
주문자명 A ← B (유일하게 다른 값)
두 건의 차이가 주문자명 하나였다. 그리고 주문자명은 카드 인증에 전혀 쓰이지 않는 값이다. 수기결제 통과에 필요한 네 개(카드번호, 유효기간, 비밀번호, 생년월일)는 2025년 9월 유출 건에 포함됐던 항목들과 정확히 겹친다.
그러니까 이 2건은 “주문자명만 바꾸면 유출 카드로 수기결제가 그대로 통과된다”는 걸 알고 있는 누군가의 손에서 나왔다고 보는 게 자연스러웠다.
로직이 오동작한 게 아니다. 스펙대로 정확히 동작해서 이렇게 된 거다. 고칠 데가 없어서 더 불편한 케이스다.
어디서 막을 수 있는가
이게 막히려면 어디서 막혀야 하는지 정리를 해봤다.
| 레이어 | 할 수 있는 일 |
|---|---|
| 카드사 FDS | 이상거래탐지. 다만 유출 직후에는 패턴 학습이 어려움 |
| 카드 재발급 | 유출 카드 자체를 폐기. 소유자가 직접 신고해야 시작됨 |
| 가맹점 | 주문자명과 카드명의자명을 따로 대조. PG 기본 기능이 아님 |
| PG | 이상 패턴 로그 수집, 가맹점 알림 정도 |
근본적으로는 카드사 FDS와 카드 재발급이 답이고, 현장 대응 관점에서 보면 가맹점이 주문자명 불일치 시그널을 PG에 올려주는 게 제일 빠른 조기 탐지 경로다. 이번 건이 딱 그 경로로 들어온 케이스였다.
유선 안내
메일 주고받는 걸로는 부족할 것 같아서 바로 가맹점에 전화했다.
1
2
3
1. 이 2건은 취소 처리가 먼저다. 운영팀으로 TID 넘기면 개별 처리 가능하다.
2. 해당 카드는 이미 외부에 정보가 나갔을 가능성이 크다.
3. 카드 소유자가 카드사에 신고해서 폐기 후 재발급 받는 방향이 맞다.
여기서 한 가지 짚을 게 있는데, 카드 폐기와 재발급은 엄밀히는 카드 소유자와 카드사 사이의 건이다. PG가 대신 처리할 수 있는 영역이 아니다. 그래서 안내 경로가 “가맹점 → 실사용자 → 카드사”로 흘러간다. 이걸 담당자에게 명확히 전달해두지 않으면 중간에서 흐름이 끊긴다.
돌아보며
추측을 문장으로 써버린 1차 회신
“명의 검증 로직이 오동작했을 가능성” 이라고 쓴 게 문제였다. 그 로직이 있다는 전제를 문장 안에 깔아버린 거다. 결제 쪽은 PG, 1차 PG, VAN, 카드사가 겹쳐 있어서 표현 하나가 책임 방향을 바꿀 수 있다.
모를 때는 “확인 중”이라고 쓰면 된다. 근데 그 순간엔 그게 잘 안 보였다. 바로 정정 메일 나가고 유선으로 다시 확인한 건 다행이긴 한데, 1차에 나가지 말았어야 할 문장이었다.
PG의 기본 스펙과 가맹점 상식의 간극
가맹점은 주문자 = 카드명의자가 당연하다고 본다. PG와 카드사 스펙은 그걸 검증하지 않는다. 이 차이를 응대할 때마다 풀어서 설명하지 않으면, 가맹점은 PG 버그로 읽고, PG는 스펙대로 동작이라고 답하는 대화가 반복된다.
유출은 한참 뒤에 돌아온다
2025년 9월에 나간 정보가 2026년 4월에 수기결제로 들어오는 건 전혀 이상한 일이 아니었다. 유효기간이 남아있거나 카드가 재발급되기 전까지는 그 정보가 계속 유효하니까. PG, VAN, 카드사는 들어온 거래를 스펙대로 처리할 뿐이고, 이걸 실무 구간에서 걸러주는 건 결국 카드사 FDS다. 그게 우리까지 내려오지 않으면 우리 쪽에서는 “주문자명 불일치” 정도로만 얼핏 드러난다.
마무리
1차 PG와 VAN 구간 쪽은 아직 조사 중이다. 다만 입력값 패턴만 놓고 보면, 유출된 카드 정보를 쥔 누군가가 주문자명만 바꿔 넣었다는 가정이 현재까진 제일 말이 된다.
가맹점 문의 하나를 어디까지 따라가느냐가 결국 결제 개발자가 하는 일이라고 생각한다. “스펙이 그렇습니다”로 끝낼 수도 있었는데, 그 뒤를 따라가면 유출 카드 한 장을 더 못 쓰게 만들 수 있는 흐름이 있다. 이번 건은 그렇게 처리됐다.