Skip to content

이메일 무단 가입 방지 ​

최근 서비스 제품에서 비정상적인 사용자(해외 IP)가 이메일 인증을 손쉽게 통과하고 계정을 생성하는 일이 있었다.

이메일 인증만 거치게 하면 비정상적인 계정 생성은 충분히 막을 수 있을 줄 알았다. 겉으로는 안전해 보이는 이메일 인증이 실제로는 얼마나 쉽게 우회할 수 있는 취약한 상태였는지를 되돌아보고, 단계별로 적용할 수 있는 방어 전략을 살펴본다.

이메일 인증의 허점 ​

회원가입 시 인증 메일을 발송하고 코드를 확인받는 절차는 분명히 존재했으나, 수신 이메일 주소에 대한 사전 유효성 검증 단계 가 없었다. 형식만 맞으면 덜컥 메일부터 발송해 버렸고, 실존 메일함을 거치니 대량 가입은 걸러질 것이라 안일하게 판단했다.

이번 공격자는 널리 알려진 공개 임시 메일 도메인이 아니라, fldubai.com 도메인을 사용해 가입을 시도했다.
해당 도메인의 MX 레코드를 추적해 보면 in.mail.tm으로 연결된다.

mail.tm은 REST API를 통해 실시간으로 임시 이메일 계정을 생성하고 수신함을 가로챌 수 있도록 지원하는 일회용 메일 플랫폼이다. 공격자는 mail.tm이 제공하는 도메인 풀을 활용해, 일반적인 정적 차단 목록을 가볍게 우회하고 스크립트로 인증 코드를 자동 수신하여 계정을 생성한 것이다.

많은 개발자가 SMTP로 메일을 보낼 때 발송이 성공하면 신뢰할 수 있는 정상 이메일 주소로 전달된다고 착각한다. SMTP 환경에서 이메일 주소 검증은 발신 서버가 아니라 수신 서버에서 판별 한다는 사실을 망각하거나 알지 못하기 때문이다.

SPF와 DKIM이 적용되었더라도 발신 서버는 상대 도메인의 메일 서버로 메시지를 넘길 뿐이다. 공격자가 임시 이메일 서비스를 이용하지 않고 직접 자체 메일 수신 서버를 구축해서 사용했더라도, 그대로 인증 메일을 정상 수신해 코드를 가로챌 수 있다. 이메일 인증 코드를 보내는 쪽에서는 아무런 이상을 감지하지 못하는 허점 이다.

다계층 방어 파이프라인 구축 ​

단계별 회원가입 검증 파이프라인

단순히 이메일 인증 하나만 믿고 가입 경로를 열어둘 수는 없다. 폼 화면 진입부터 최종 계정 활성화까지 단계별로 검증 장치를 엮어두는 다계층 방어 구조를 정리해 보았다.

  • 봇 탐지 및 속도 제어: 스마트 캡차와 IP 속도 제한으로 자동화 스크립트와 반복 요청 차단
  • 이메일 도메인 검증: 허용 도메인 확인과 외부 검증 API로 일회용 임시 메일 필터링
  • 전화번호 회선 검증: 사전 회선 조회를 통해 VoIP 가상 번호 차단
  • 유효 회선 SMS OTP 발송: 검증된 실제 통신사 휴대폰 번호에만 인증 코드 발송
  • 승인 대기 및 수동 승인: 계정 생성 후 권한을 격리하고 관리자의 명시적 승인을 거쳐 활성화

봇 탐지와 속도 제어 ​

이메일이나 전화번호를 검증하기 전에 회원가입 경로 앞단에서 공격자의 자동화 도구를 먼저 걸러내야 한다. 최근 AI 에이전트를 통한 공격이 많아진 만큼, 봇 차단이나 요청 속도 제한이 없으면 일차적인 방어가 되지 않는다.

브라우저 검증을 거치지 않는 스크립트 호출을 원천 차단하고, 일반 사용자와 다르게 인증과 가입 요청을 빠르게 수행하는 행위를 물리적으로 지연시키는 안전장치가 선행되어야 한다.

스마트 캡차 ​

기존의 그림 맞추기나 글자 입력 캡차는 AI 에이전트도 쉽게 우회할 수 있어 실질적인 방어가 되지 못하고 거부감만 줄 수 있다. 사용자 경험을 고려해서 퍼즐을 푸는 것보다는 백그라운드로 동작하는 스마트 캡차 방식이 적절해 보인다.

대표적으로 무료로 강력한 탐지 성능을 제공하는 Cloudflare Turnstile이나, 자체적으로 호스팅할 수 있는 오픈소스인 trycap.dev 등을 선택지로 검토해 볼 수 있다.

동일 IP 기반 속도 제한(Rate Limiting) 병행 ​

스마트 캡차와 더불어 단시간에 동일 IP에서 발생하는 연속 가입 시도를 인프라 레벨이나 애플리케이션에서 제한해야 한다. 캡차 통과 시도 자체가 대량으로 몰려 부하를 일으키는 것을 막고, 짧은 간격으로 요청을 쏟아내는 비정상 IP에는 즉시 429 Too Many Requests를 반환해 서버 자원과 외부 검증 비용을 보호한다.

이메일 도메인 검증 ​

앞단에서 봇과 요청을 걸러내더라도 공격자가 새로운 임시 메일 도메인을 끌어오거나 신뢰할 수 있는 이메일을 직접 사용해 가입을 시도할 수 있다. 임의의 도메인으로 인증 메일을 무차별 발송하는 구조를 열어두는 한 공격을 원천 차단하기는 어렵다.

결국 근본적인 해결책은 신뢰할 수 있는 이메일 도메인을 명시적으로 허용하는 것 이다.

구글(gmail.com)이나 네이버(naver.com), 카카오(kakao.com)처럼 대중적으로 검증된 이메일만 허용하고, 허용 목록에 없는 도메인은 메일 자체를 발송하지 않는다. 개인 도메인이나 B2B 파트너로 문의되는 회사 도메인은 관리자가 확인 후 시스템에 별도로 추가해 운영하면 된다.

일회용 메일 판별과 차단 ​

신뢰할 수 있는 도메인을 별도로 관리하지 않을 것이라면, 최소한 일회용 메일 서비스부터 판별해서 차단해야 한다.

오픈소스 블랙리스트 목록에서 먼저 걸러내고, 목록에 없는 도메인에 대해서만 Kickbox Disposable Email API 같은 전문 검증 솔루션에 질의해 최신 일회용 여부를 판별한다. 이렇게 단계를 나누면 외부 API 호출 비용과 네트워크 지연 시간을 크게 아낄 수 있다.

회원가입 IP 세션 유지

회원가입 전 과정에서 동일한 IP를 유지하도록 검증하는 것도 중요해요. 이메일 인증을 요청한 IP와 실제 최종 가입을 시도하는 IP가 달라지는 비정상적인 흐름을 걸러낼 수 있어요.

본인인증과 회선 검증 ​

이번 사태를 두고 사내에서는 "본인인증 필수 설정을 풀어버려서 터진 사고" 라는 의견이 나왔다.

하지만 본인인증 해제 여부와 상관없이 무단 가입은 언제든 터질 수 있는 문제였다. 과거 해외 사용자를 지원하면서 가입자의 타임존이 한국이 아니면 본인인증을 생략하는 우회 경로 를 열어둔 적이 있다. 이후 국내외 형평성을 맞춘다며 국내 본인인증마저 해제하고 이메일 인증으로 통일했지만, 조작하기 쉬운 타임존 분기라는 설계 부채를 애초부터 방치했던 것이 근본 원인이었다.

본인인증 대신 SMS OTP(Twilio Verify)를 공통으로 요구하더라도 한계는 마찬가지다. 전화번호 역시 일회용 가상 번호(VoIP) 서비스가 널려 있어 이메일 인증처럼 쉽게 뚫린다. 오히려 공격자의 무차별 번호 입력으로 불필요한 SMS 발송 비용에 대한 피해가 발생할 수 있다. 따라서 SMS 인증을 도입하더라도 가상 번호를 걸러내려면 Twilio Lookup 등으로 회선 유형을 먼저 조회해 VoIP를 차단하는 검증이 함께 이루어져야 한다.

비정상 가입 시도 IP 차단

가상 번호나 비정상적인 인증 시도로 차단된 요청은 해당 가입 시도 IP를 일시적으로 차단하는 정책을 함께 두는 것이 좋아요. 지속적인 우회 시도와 불필요한 비용 발생을 줄일 수 있어요.

해외 사용자 명시적 승인 절차 ​

글로벌 서비스 측면으로 볼 때 해외 사용자에게 엄격한 본인확인 단계를 붙이기는 현실적으로 어렵다. 계정 생성을 막는 기술적 조치만으로는 한계가 분명히 존재한다.

결국 가입 즉시 계정을 열어주는 자동 승인 대신, 정상적인 사용자를 식별하고 시스템적으로 수동 승인하는 단계를 두는 정책 이 가장 확실하다. 가입 신청이 들어오면 계정을 즉각 활성화하지 않고 PENDING_APPROVAL(승인 대기) 상태로 제한해 둔다.

국내와 해외의 가입 흐름을 억지로 맞추려다 안전장치를 풀어버리기보다, 국내 사용자는 포트원 본인인증으로 자동 승인하고 해외 사용자는 관리자의 명시적 승인 을 거치도록 정책을 분리하는 것이 가장 현실적이고 안전한 선택이다.

관리자가 정상 사용자로 판단해 가입을 승인하면, 해당 이메일 도메인을 신뢰할 수 있는 도메인 목록에 자동 등록하도록 연계할 수 있다.

인증 없이 호출되는 경로

공격자는 계정을 생성하더라도 로그인할 수 없도록 제한되므로 인증 없이 호출되는 취약한 경로 탐색으로 공격 대상을 변경할 거예요. 어쨌든 인증된 계정으로 호출할 수 있는 파라미터 조작 취약점은 어느 정도 방어할 수 있는 패턴이 돼요.

Released under the MIT License.