보안 가이드

IP별 요청 제한이 수만 개 IP에 분산된 검색 봇을 막지 못했던 사례

수만 개 IP에 분산된 검색 봇이 IP별 제한을 피해 API 할당량을 소진했습니다. 무슨 일이 있었고 서명된 토큰이 어떻게 이를 막았는지 정리합니다.

게시 2026-11-01 업데이트 2026-11-01 최종 확인 2026-11-01 6분 읽기
이 페이지에서

대상: 검색 또는 유사 기능이 외부 API를 호출하는 사이트의 운영자. 이 글은 이 사이트 운영자가 운영하는 한 사이트에서 실제로 발생한 일을 일반화한 것입니다. 사이트, 외부 서비스, 정확한 제한값이나 날짜는 밝히지 않으며, 공격 절차는 다루지 않습니다.

무슨 일이 있었나

이 사이트 운영자가 운영하는 사이트에서 검색 기능은 검색할 때마다 외부 API를 호출했습니다. 며칠 사이에 검색 트래픽이 평소의 약 20배로 늘었습니다. 외부 API에는 동시 처리 상한이 있었고, 대다수 검색(90% 이상)이 503을 반환했습니다.

처음에는 IP별 제한(분당 N회)이 이를 막아 줄 것이라고 가정했습니다. 그 가정은 틀렸습니다.

1

며칠 만에 검색 트래픽이 약 20배 증가

외부 API의 동시 처리 상한에 도달했고, 거의 모든 검색이 503을 반환했습니다. 이 시점에는 단순히 오류가 늘어난 것처럼 보였습니다.

2

첫 번째 가정: IP별 제한이 막아 줄 것이다 (틀림)

IP별 분당 횟수 제한은 매우 많은 호출을 하는 몇 개의 IP를 잡아낼 수 있습니다. 하지만 이 트래픽은 그런 유형이 아니었습니다.

3

측정 결과

하루 약 60,000건의 검색이 약 60,000개의 서로 다른 IP에서 들어왔고, IP당 약 한 번의 요청이었습니다. 패턴은 주거용 프록시 네트워크처럼 보였습니다. 사용자 에이전트는 일반 브라우저였고, Referer는 사이트 자체였으며, 검색어는 실제 제품명이었습니다. 가격 수집이 목적이었을 가능성이 높았습니다.

4

외부 API의 일일 할당량이 그날 이른 시간에 소진

봇의 검색이 할당량을 이른 시간에 소진했고, 일반 방문자는 하루 대부분 검색할 수 없었습니다.

5

실제 문제로 보이지 않았던 이유

할당량이 보호되고 있었기 때문에 외부 API는 정상으로 보였고, 사이트에는 오류만 늘어난 것으로 보였습니다. 할당량을 보호하는 것과 사용자가 기능을 사용할 수 있게 하는 것은 서로 다른 일이었습니다.

예상된 상황: 소수의 IP가 많은 호출을 보냄

IP별 제한에 걸림 → 차단됨 ✓

실제 상황: 약 60,000개 IP, IP당 한 번씩 요청

어느 IP도 제한에 도달하지 않음 → 외부 API의 할당량만 소진됨

= 세는 단위가 IP인 동안에는 이런 형태가 보이지 않습니다

IP별로 세면, IP마다 한 번씩 온 요청은 제한에 전혀 걸리지 않습니다. 봇이 더 넓게 분산될수록 IP별 제한은 이를 더 보지 못합니다.

상위 할당량이 보호되고 있다고 해서 사용자가 기능을 쓸 수 있다는 뜻은 아닙니다

외부 API의 할당량이나 동시 처리 한도를 보호하는 장치는 해당 API가 망가지지 않도록 하기 위해 존재합니다. 이 장치가 작동하는 동안 상위 서비스는 오류를 보이지 않습니다. 비용은 할당량을 잃은 쪽, 즉 사이트 자체의 방문자가 부담합니다.

보호 장치가 작동하고 있었기 때문에 문제가 알아채기 어려웠습니다. 지켜봐야 할 것은 실제 방문자가 검색할 때 얻는 성공률입니다.

어떻게 막았나

막지 못했던 설계

누구의 검색 요청이든 외부 API를 호출했습니다. 유일한 제한은 IP별 횟수였습니다. 분산된 트래픽은 각 IP의 횟수를 낮게 유지하므로 제한이 작동하지 않았습니다.

효과가 있었던 설계

외부 API는 사이트 자체 페이지가 발급한 서명된 토큰(쿠키)이 있는 검색에만 호출합니다. 토큰이 없으면 가벼운 페이지 또는 403을 반환합니다. 그 위에 시간당 상한을 전역 및 토큰별로 적용합니다.

적용한 조치
서명된 토큰
사이트 자체 페이지가 발급한 토큰을 외부 API 호출의 조건으로 삼았습니다. 토큰이 없으면 가벼운 페이지 또는 403
집계 보호
봇의 검색어로 부풀려져 있던 인기 검색어 순위에서 토큰이 없는 검색을 제외했습니다
시간당 상한
전역 상한과 토큰별 상한을 모두 적용했습니다

배포 직후 503은 0이 되었습니다. 현재 하루 약 100,000건의 토큰 없는 요청이 403을 받고, 정상 검색은 통과합니다.

교훈

  • IP별 제한은 분산된 봇에 효과가 없습니다. 제한을 아무리 낮게 해도 IP당 한 번의 요청은 아무것도 막지 못합니다.
  • 상위 할당량이 보호되고 있다는 것은 사용자가 기능을 사용할 수 있다는 것과 같지 않습니다. 보호 장치가 문제를 가릴 수 있습니다.
  • 순위 같은 집계는 오염됩니다. 외부 API를 보호하는 것과 함께, 집계에 무엇이 들어가는지도 제한하세요.

사이트에서 할 일

아래 순서는 이 사이트 자체의 조언이며, 인용된 출처의 공식 입장이 아닙니다.

1

비용이 드는 작업 전에 사이트 발급 토큰을 확인

외부 API 호출처럼 비용이나 할당량을 소비하는 단계 전에, 자체 페이지가 발급한 서명된 토큰이 있는지 확인하세요. 토큰에 만료 시간을 두고 서버에서 검증하세요. 토큰이 없으면 진행하지 말고 가벼운 페이지 또는 403을 반환하세요.

2

토큰이 없는 트래픽은 집계에서 제외

인기 검색어, 검색어 통계, 추천은 토큰이 있는 검색으로만 만드세요. 그래야 봇의 검색어가 사이트에 표시되는 내용에 섞이지 않습니다.

3

전역 및 토큰별 상한 설정

IP별 횟수 대신 시간당 전역 상한과 토큰별 상한을 사용하세요. 전역 상한은 외부 API의 할당량이 모두 소진되는 것을 막는 마지막 안전장치입니다.

4

결과 캐싱과 큐잉 추가

반복되는 검색어는 외부 API를 다시 호출하지 않고 캐시에서 제공하고, 혼잡할 때는 요청을 큐에 넣으세요. 한 가지 조치가 우회되더라도 할당량이 한꺼번에 사라질 가능성이 줄어듭니다.

5

방문자가 경험하는 성공률 모니터링

외부 API의 오류율만이 아니라, 검색이 성공하는 실제 방문자의 비율을 기록하고 이 비율이 떨어지면 알림을 설정하세요. 이것이 조직 보안 기준선에서 말하는 "무언가 잘못되었음을 알아챌 수 있는 상태"입니다.

토큰은 인증이 아니라 공격자의 비용을 높입니다

토큰은 인증이 아닙니다. 토큰이 주는 효과는 검색 URL을 단순히 두드리는 트래픽을 멈추는 것이며, 완전한 방어가 아닙니다.

그래서 토큰은 캐싱, 큐잉, 토큰별 상한과 함께 사용합니다. 이 사이트의 견해로는, 봇이 매번 새 토큰을 받아 온다면 토큰별 상한은 도움이 되지 않으므로 항상 전역 상한 및 캐싱과 짝지어 사용해야 합니다. 요청 제한과 남용 통제에서와 같이, 이 사이트의 견해는 남용의 성공률을 0으로 만드는 것이 아니라 남용이 비용을 들일 가치가 없도록 만드는 것입니다.

출처 (1차 자료)

  • OWASP API Security Top 10 2023, "API4:2023 Unrestricted Resource Consumption" — api-security.owasp.org (일정 시간 내 클라이언트가 API와 상호작용하는 빈도 제한, 외부 서비스의 지출 한도 설정)
  • OWASP Automated Threats, "OAT-011 Scraping" — owasp.github.io (스크레이핑을 가격 담합 등 다른 곳에서 사용하기 위해 콘텐츠나 데이터를 수집하는 행위로 정의, 인증이 필요 없는 데이터가 표적이 될 수 있음)

다음으로 읽을 글

FAQ

Q일부 봇에 대해 IP별 요청 제한이 실패하는 이유는 무엇인가요?
A

공격자가 요청을 여러 IP에 분산하면 각 IP가 어떤 제한보다도 낮게 유지되기 때문입니다. 이 사이트 운영자가 운영하는 한 사이트에서는 하루 약 60,000건의 검색이 약 60,000개의 서로 다른 IP에서 들어왔고, IP당 약 한 번씩이었습니다. 제한을 아무리 낮게 설정해도 한 번의 요청은 제한에 도달하지 않습니다. IP는 보조 신호로만 사용하고, 클라이언트가 무엇을 할 권한이 있는지 나타내는 기준, 예를 들어 자체 페이지가 발급한 토큰으로 집계하세요.

Q검색을 이용하는 봇은 일반 방문자에게 어떤 영향을 미치나요?
A

모든 검색이 외부 API를 호출한다면, 봇은 해당 API의 동시 처리 허용량과 일일 할당량을 소비합니다. 이 사이트에서는 대부분의 검색이 503을 반환했고, 할당량은 그날 이른 시간에 소진되어 일반 방문자는 하루 대부분 검색할 수 없었습니다. 인기 검색어 순위 같은 집계도 봇의 검색어로 채워져 실제 방문자가 검색하는 내용과 어긋나게 됩니다.

Q서명된 토큰(쿠키)을 요구하면 봇을 완전히 막을 수 있나요?
A

아닙니다. 토큰은 인증이 아니며, 공격자의 비용을 높일 뿐입니다. 결과 캐싱, 큐잉, 토큰별 상한과 함께 사용하여 한 가지 조치가 우회되더라도 피해가 제한되도록 하세요.

Q외부 API의 오류를 모니터링하는 것만으로 충분한가요?
A

아닙니다. 상위 할당량을 보호하는 장치가 있으면 문제는 단순한 오류처럼 보이고 상위 서비스는 정상으로 보입니다. 지켜봐야 할 것은 실제 방문자가 검색할 때 경험하는 성공률입니다. 상위 서비스의 오류율만으로는 방문자가 기능을 사용할 수 없다는 사실을 알 수 없습니다.