문의 폼에 하루 수십 통씩 광고 도배가 쌓여, 진짜 손님 문의가 그 속에 파묻힌다 — 작은 회사 웹사이트 문의 폼 스팸(봇) 차단의 5가지 원칙

문의 폼에 하루 수십 통씩 광고 도배가 쌓여, 진짜 손님 문의가 그 속에 파묻힌다 — 작은 회사 웹사이트 문의 폼 스팸(봇) 차단의 5가지 원칙
대표 이미지

문의 폼을 열어 둔 지 한 달, 사장님의 받은편지함에는 하루에도 수십 통씩 낯선 광고와 외국어 도배 글이 쌓인다. 정작 견적을 묻는 진짜 손님의 문의 한 통은 그 스팸 더미 사이에 파묻혀 이틀이 지나서야 눈에 띈다. 문제는 폼을 없애는 것이 아니라, 사람만 통과시키고 봇은 조용히 걸러 내는 것이다.

1. 사람 눈에는 안 보이고, 봇만 걸리는 함정을 둔다

가장 저렴하고 손님에게 부담이 없는 방어책이 허니팟(honeypot)이다. 폼에 화면상 보이지 않는 입력 칸을 하나 숨겨 두는 방식으로, 사람은 그 칸의 존재조차 모르고 지나가지만, 폼의 모든 칸을 기계적으로 채우는 봇은 여기에 값을 남긴다. 서버는 그 숨은 칸이 채워져 있으면 곧바로 스팸으로 판정해 버린다.

  • CSS로 숨기기: display:none이나 화면 밖으로 밀어내는 방식으로 사용자에게는 감춘다.
  • 자동완성 차단: 브라우저 자동입력이 실수로 채우지 않도록 autocomplete="off"를 걸어 둔다.

2. 손님만 뺀 채, 봇에게만 검문을 세운다

예전의 '찌그러진 글자 맞히기' 캡차는 손님을 지치게 해 문의 자체를 포기시켰다. 요즘은 손님이 아무것도 하지 않아도 뒤에서 사람인지 판단하는 보이지 않는 캡차가 표준이다. 구글 reCAPTCHA v3나 클라우드플레어 Turnstile은 마우스 움직임과 접속 패턴만으로 점수를 매겨, 의심스러운 요청에만 추가 확인을 요구한다. 손님 대다수는 검문이 있는 줄도 모르고 지나간다.

3. 같은 손이 1분에 열 번 두드리면 문을 잠근다

진짜 손님은 문의를 한 번, 많아야 두세 번 보낸다. 반면 봇은 같은 폼을 초 단위로 두드린다. 그래서 같은 IP나 같은 세션에서 일정 시간 안에 보낼 수 있는 횟수를 제한(rate limit)하면, 대량 발송형 스팸의 상당수가 그 문턱에서 막힌다. 예를 들어 '한 IP에서 1분에 3건까지'처럼 정상 사용에는 걸리지 않되 폭주는 잘라 내는 선을 잡는 것이 핵심이다.

4. 폼을 열자마자 0.5초 만에 보낸 것은 사람이 아니다

사람은 폼을 다 채우는 데 최소 몇 초에서 수십 초가 걸린다. 폼이 화면에 나타난 시각을 몰래 기록해 두었다가, 제출까지 걸린 시간이 비현실적으로 짧으면 봇으로 간주하는 최소 작성 시간 검증이 의외로 강력하다. 여기에 폼마다 발급하는 일회용 토큰(CSRF 토큰)을 함께 검증하면, 폼을 거치지 않고 서버로 직접 쏘는 자동 요청까지 함께 걸러진다.

5. 그래도 새어 든 스팸은 받은편지함 바깥에서 거른다

어떤 방어도 100%는 아니다. 앞단을 뚫고 들어온 소수의 스팸은 서버 측 필터가 마지막으로 잡는다. 링크가 지나치게 많거나, 특정 키워드가 반복되거나, 메시지에 한글이 한 글자도 없는 문의를 별도의 '스팸 격리함'으로 분리해 두면, 사장님의 받은편지함에는 사람의 문의만 남는다. 걸러 낸 것은 지우지 말고 따로 쌓아 두어야, 혹시 진짜 손님을 잘못 막지는 않았는지 가끔 되짚어 볼 수 있다.

막는 것과 불편하게 하는 것은 다르다

스팸 방어의 성패는 '봇을 얼마나 막았나'만큼이나 '손님을 얼마나 안 괴롭혔나'로 갈린다. 검문을 겹겹이 세울수록 봇은 줄지만, 그 벽에 진짜 손님이 먼저 지쳐 떠나면 문의 폼을 둔 이유가 사라진다. 그래서 눈에 보이지 않는 방어(허니팟·보이지 않는 캡차·작성 시간 검증)를 우선하고, 손님에게 부담을 주는 방식은 최후에만 꺼내는 순서가 정석이다.

CYAN 에이전시는 작은 회사의 홈페이지를 만들 때 문의 폼에 이 다섯 겹의 방어를 기본값으로 넣고, 스팸 격리함과 실제 문의를 분리해 사장님이 진짜 손님만 보게 설계한다. 문의 폼이 스팸으로 몸살을 앓고 있다면, 폼을 없애기 전에 거르는 순서부터 다시 짜 볼 일이다.