← Studio Hirameki 홈
Engineering Note

장난처럼 시작한 봇 차단 엔진

무엇을 막으려 했고, 무엇을 막았고, 왜 싸게 파는가 · Studio Hirameki

솔직히 이건 거창한 사업 계획서에서 나온 게 아니다.

처음엔 “봇과 사람을 구분한다” 같은 목표조차 없었다. 그냥 장난삼아 게임 에임핵(aimbot)을 잡아보던 게 시작이었다. 사람의 조준과 핵의 조준, 그 움직임이 다르지 않을까 하는 그 정도의 호기심. 그런데 만들어 놓고 눌러 보니 — 뭐야, 되잖아?

사람의 손은 완벽하지 않다. 그 불완전함이 지문처럼 남는다. 에임핵을 잡던 그 원리가 결제창의 매크로에도, 수강신청의 봇에도 그대로 통했다. 캡차 하나 없이, 마우스가 움직인 ‘물리’만 보고서. (어쩌다 여기까지 왔는지 전체 이야기는 — 이게 좀 더 유명해지거나 팔리거나 하면 — 언젠가 풀 기회가 있을지도 모르겠다.)


이 엔진이 막으려는 것들

봇은 한 종류가 아니다. 대충 뭉뚱그려 “매크로”라고 부르지만, 방어하는 입장에서 보면 완전히 다른 세 부류다.

① 좌표를 찍어 누르는 봇. 마우스를 실제로 움직이지 않고, 버튼의 좌표로 바로 순간이동해 클릭한다. 셀레니움·오토핫키·파이썬 매크로가 여기 속한다. 화면상으로는 정상 클릭과 구분되지 않는다.

② 브라우저를 아예 건너뛰는 봇. 가장 골치 아픈 부류. 브라우저를 안 쓰고 서버의 결제·예약 API를 직접 두드린다. 프론트엔드 화면에선 관측조차 되지 않는다. 애초에 화면을 안 거치니까.

③ 사람을 흉내 내는 봇. 가장 정교한 계층. 마우스 궤적을 인위적으로 만들어 사람처럼 위장한다. 통계적 행동 분석만 하는 방어는 여기서 뚫린다.

진지하게 만들려면, 이 셋을 다 상대해야 한다는 걸 알게 됐다. 그래서 장난이 프로젝트가 됐다.

그래서, 막았나

말보다 로그다. 우리가 직접 만든 봇만이 아니라, 시중에 도는 대부분의 매크로를 구해다 붙여 봤다. 막혔다.

더 중요한 건 반대쪽 — 진짜 사람을 잘못 막지는 않는가였다. 맥·윈도우·노트북·데스크톱에, 서로 다른 마우스와 트랙패드까지, 하드웨어를 최대한 흩어 놓고, 최대한 많은 사람을 모아 실제 클릭을 쏟아부었다. 지금까지 해 본 바로는 — 오탐은 사실상 뜨지 않는다. 결제 SaaS에서 이건 봇을 잡는 것만큼 중요하다 — 진짜 고객을 단 한 명이라도 막으면, 그건 봇보다 더 큰 손실이니까. “매크로만 막아야지, 진짜 고객까지 막으면 안 된다”는 게 처음부터 지금까지의 원칙이다.

대략적인 원리 (자세한 건 밝히지 않는다)

사람이 버튼을 누를 때 커서에는 관성이 남는다. 손목의 미세한 떨림, 목표를 향한 자연스러운 가속과 감속, 완벽하게 매끄럽지 않은 곡선. 봇의 좌표 클릭에는 이 물리적 흔적이 없다. 흔적을 위조하더라도, 위조된 움직임에는 사람에게선 나오지 않는 미세한 부자연스러움이 남는다.

우리가 어떤 신호를 어떻게 재는지는 밝히지 않는다(특허 출원 중이고, 그게 해자다). 다만 관점은 한 문장으로 요약된다. 캡차처럼 “당신, 사람 맞습니까?”라고 묻는 대신, “이 움직임이 육체를 가진 인간의 것이 확실한가?”를 본다. 전자는 물어보면 봇도 통과할 수 있다. 후자는 물어볼 필요조차 없다 — 몸이 없으면, 몸이 만드는 물리도 없으니까.

그리고 이건 데스크톱만의 이야기가 아니다. 모바일 터치도 똑같이 본다 — 손가락이 화면을 누르는 데에도 사람의 물리가 남으니까. 정확히 어떻게 하는지는 밝힐 수 없지만, 이건 꽤 어려운 문제였고, 그래도 꽤 잘 풀린 것 같다.

당신이 누구인지는 묻지 않는다

여기엔 개인적인 신념이 하나 있다. 나는 오래전부터, 사람인지 아닌지를 판정하겠다고 개인정보를 요구하는 게 싫었다. 로그인을 해라, 전화번호를 남겨라, 신분을 확인하겠다 — 봇을 걸러낸다는 명분으로 정작 사람의 익명성을 벗긴다.

인터넷의 익명성과 표현의 자유는, 내가 누구인지 드러내지 않고도 ‘내가 인간임’을 증명할 수 있을 때 지켜진다고 믿는다. 그래서 우리는 쿠키도, 개인정보도 쓰지 않는다. 당신이 누구인지엔 관심이 없다. 우리가 보는 건 오직 — 마우스가, 손가락이 어떻게 움직였는가. 그 물리뿐이다.

쉬운 문제가 아니라는 건 안다. 그리고 다들 어려워서 시도조차 하지 않는다는 것도 — 직접 해 보고 나서야 왜 안 하는지 알았다. 그래도, 누군가는 해야 한다고 생각했다.

왜 이렇게 싸게 받나

자주 받는 질문이다. 답은 마케팅이 아니라 원가 구조에 있다.

대부분의 봇 방어는 트래픽을 자기 서버로 흡수해서 걸러낸다. 봇이 폭주하면 서버 비용도 함께 폭증한다. 그래서 트래픽량에 따라 요금을 매길 수밖에 없다 — 하필 선착순 발매·예매 오픈처럼 트래픽이 폭발하는 순간에 요금이 같이 튄다.

우리는 판정을 엣지(edge)에서 한다. 트래픽이 100배로 뛰어도 우리 원가는 거의 그대로다. 그래서 정액으로, 트래픽 무제한으로 받아도 남는다. “트래픽이 폭주해도 추가 요금 0”은 우리에겐 광고 문구가 아니라 원가 구조에서 나오는 사실이다. 그리고 그 구조는 트래픽 흡수형 경쟁자가 쉽게 따라올 수 없다.

그런데 이건 원가만의 문제가 아니라, 어느 정도는 신념이기도 하다. 돈이 없다는 이유만으로 봇에 노출되어야 할 이유는 없다고 생각했다. 대형 플랫폼은 수억을 들여 방어를 산다. 정작 수수료를 아끼려 자체 시스템을 굴리는 작은 기획사, 소극장, 동네 쇼핑몰은 그대로 무방비로 남는다. 봇 방어가 잘사는 쪽만 누리는 사치품이어야 할 이유는 없다.

어마어마한 트래픽을, 작은 컴퓨터 안에서

선착순·발매가 열리는 순간, 우리는 그 폭발하는 트래픽을 고객 대신 받아 내야 한다. 문제는 이걸 전통적인 중앙 서버로 하려면 비용이 막대하다는 거였다. 평소엔 놀다가 발매 순간에만 수백 배로 튀는 트래픽을 감당하려면, 서버를 늘 크게 잡아 둬야 하니까. 비용만의 문제도 아니었다 — 콜드 스타트, 지연, 지역별 편차 같은 것들이 줄줄이 따라왔다.

해답은 서버리스, 정확히는 사용자와 가장 가까운 엣지(edge)에서 도는 아주 작은 런타임이었다. 트래픽이 100배로 뛰어도 알아서 흩어져 처리되고, 원가는 거의 오르지 않는다. 앞에서 말한 “정액 무제한”이 바로 여기서 나온다.

그런데 — 여기서부터가 진짜 지옥이었다. 그 작은 컴퓨터 안에, 봇을 판별하는 로직을 전부 밀어 넣어서, 결제 클릭 한 번에 실시간으로 돌아가게 만들어야 했다. 메모리도, 실행 시간도, 쓸 수 있는 자원이 극도로 빠듯한 환경에서. 몇 번을 갈아엎었는지 세지도 못하겠다. (물론 — 결국 해냈다. 안 그랬으면 이 글도 없다.)

붙이기 싫었던 백엔드 한 줄

고백하자면, 백엔드에 코드를 붙이게 하는 게 싫었다. 고객이 손대야 하는 코드가 한 줄이라도 늘면 그건 DX(개발자 경험)를 갉아먹는다. 우리 이상은 “프론트에 세 줄, 끝”이었다.

그런데 위의 ②번 봇 — 브라우저를 건너뛰고 API를 직접 때리는 봇 — 은 프론트엔드만으로는 구조적으로 관측조차 안 된다. 화면을 안 거치는 걸 화면에서 잡을 방법은 없다. 그래서 DX를 조금 희생하고, 백엔드에 딱 한 줄을 붙였다. 대신 그 한 줄을 최대한 가볍게 만들었다 — fire-and-forget, 결제 흐름에 최대한 지연을 주지 않게. 그리고 백엔드조차 만질 수 없는 고객을 위해선, 코드 0줄로 앞단에서 거르는 길(리버스 프록시)까지 열어 뒀다.

B2B 솔루션이라고 해서 무조건 비싸고, 복잡하고, DX를 갉아먹어야 할 이유는 없다고 생각한다. 그게 이 프로젝트의 설계 철학이다.

그런데 — 한국 봇의 실체는 아무도 모른다

가장 불편한 진실. “매크로가 얼마나 심각한가?”에 대한 제대로 된 통계는 사실상 없다. 이유는 단순하다. 못 잡으니까. 못 잡는 것을 셀 수는 없다.

우리가 아는 건 정황뿐이다. 크몽 같은 곳에서 골프·캠핑 예약 매크로가 공공연히 팔리고, GitHub에는 수강신청·티켓팅 봇 소스가 공개돼 있고, 국민권익위에 접수된 골프 부킹 매크로 관련 민원은 2년 새 6.5배로 뛰었다. 업계 일부 추정은 대학 수강신청 트래픽의 절반 가까이가 매크로라고 말한다. 그런데 이건 전부 추정이다. 진짜 숫자는 아무도 모른다 — 막지 못했으니까.

그래서 우리가 하려는 첫 단계는, 최소한 그 숫자를 볼 수 있게 만드는 것이다. 그래서 도입 전에 봇 트래픽을 무료로 측정해 준다. 차단하지 않고, 그냥 “얼마나 들어오는지”를 리포트로 보여준다.


아직 우리가 모든 봇을 다 잡는다고 말하지는 않겠다. 그런 주장을 하는 안티봇은 대체로 거짓말이다. 봇과 방어는 계속 진화한다. 다만 우리는 남들이 잘 안 보는 축 — 물리 — 을 본다. 캡차 없이, 진짜 고객을 막지 않으면서, 싸게. 그거면 충분히 다르다고 믿는다.

당신 사이트엔 봇이 얼마나 들어올까요?

차단하기 전에, 얼마나 들어오는지부터 무료로 보여드립니다.

Studio Hirameki 알아보기

문의 · chori@hrmk.studio