
탐지 규칙을 처음 켠 날, 경보가 울리면 바로 막도록 해 두었다고 해 봅시다. 실험실에서 그렇게 했더니 공격자 다섯을 막는 동안 주문이 많은 정상 사용자 5명도 429를 받았습니다. 주문 60건을 차례로 열어 본 것이 "서로 다른 주문을 많이 연다"는 규칙에 걸렸기 때문입니다. 규칙을 켜는 순서와 대응의 세기가 탐지만큼 중요합니다.

단계적 대응(graduated response)은 확신이 클수록 세게 반응하는 방식입니다.
Retry-After 헤더로 언제 다시 오라고 알려 줍니다.차단에는 언제나 TTL(만료 시간)을 붙입니다. CrowdSec도 기본 프로필이 IP를 4시간 차단하고, 반복되면 시간을 늘리는 식을 예시로 둡니다. TTL이 있으면 오탐이 저절로 풀리고, 진짜 공격자는 다시 걸립니다.
실험실 lab/detect.py의 Responder는 신원(계정) 기준 경보에만 반응합니다.
IP 기준 경보는 기록만 합니다. CGNAT 뒤의 정상 사용자를 함께 막지 않기 위해서입니다(8편). JWT.sub != Path.ID 규칙은 대응에서 뺐습니다. 정상 사용자 대부분에게 울리기 때문입니다(13편).
섀도 모드는 규칙을 켜되 대응은 하지 않고, 경보만 남겨 오탐을 재는 단계입니다. 같은 트래픽을 섀도 모드와 대응 모드로 돌려 비교했습니다. 앱에는 소유권 검사가 들어 있습니다.
| 설정 | 대응을 받은 정상 사용자 | 공격자에게 대응이 시작된 요청 |
|---|---|---|
| 섀도(대응 없음) | 0명 | 없음 |
| 대응, 규칙 전부 | 6명: 주문 많은 사용자 5명(429를 4~9번), 잘못 만든 앱 1명(429를 149번) | 빠른 열거 11번째, 느린 열거 8번째, IP 바꾸기 11번째, 계정 바꾸기 8번째, 퍼징 121번째, 폭주 수집 안 걸림 |
대응, distinct_objects 뺌 | 1명: 잘못 만든 앱(429를 149번) | 위와 같음 |
섀도 결과에서 distinct_objects 규칙의 오탐이 모두 주문 많은 사용자라는 것을 먼저 알았다면, 그 규칙을 대응에서 빼고 켤 수 있었습니다. 그래도 공격자를 막는 시점은 하나도 늦어지지 않았습니다. 다른 규칙(거부된 서로 다른 객체 수, 미끼)이 이미 잡고 있었기 때문입니다.
0.4초마다 같은 목록을 부르는 잘못 만든 앱에 429를 준 것은 오탐이라기보다 원하던 대응에 가깝습니다. 서버를 지키면서 그 앱 개발자에게 "너무 자주 부른다"를 알려 줍니다.
같은 표에서 폭주 수집은 한 번도 막히지 않았습니다. 60초 동안 600건을 보냈는데, 경보를 내는 규칙이 요청 수 규칙 하나뿐이었습니다. 같은 경보는 60초에 한 번만 나니 경보가 1개에서 멈췄고, 대응은 "기록"에서 올라가지 않았습니다.
여기서 배울 점은 두 가지입니다. 하나, 규칙 하나만 반응하는 공격에는 그 규칙의 대응 단계를 따로 정해야 합니다. 폭주라면 요청 수 규칙이 곧바로 429를 내는 게 맞습니다. 둘, 이런 빈틈은 대응을 켜고 재 봐야 보입니다. 섀도 모드만으로는 "경보가 울렸다"까지만 압니다.
같은 대응 규칙을 소유권 검사를 뺀 앱에 걸어 봤습니다. 열거 공격 네 가지로 나간 남의 주문 수입니다.
| 대응 없음 | 단계적 대응 | |
|---|---|---|
| 빠른 열거 | 299건 | 13건 |
| 느린 열거 | 80건 | 62건 |
| IP 바꾸기 | 200건 | 45건 |
| 계정 바꾸기 | 78건 | 74건 |
| 합계 | 657건 | 194건 |
탐지와 대응은 유출을 70% 줄였지만 0으로 만들지 못했습니다. 느린 열거와 계정 바꾸기는 거의 그대로 새었습니다. 탐지는 예방이 아닙니다. 예방(소유권 검사)을 넣은 앱에서는 처음부터 0건입니다.
대응을 켜기 전에 정해 둘 것입니다.
모든 링크는 2026-10-30에 확인했습니다.
lab/results/run-secure-enforce/leak.json, run-secure-enforce-tuned/leak.json, run-vuln-shadow/leak.json, run-vuln-enforce/leak.json(2026-10-30 실행)이전 글 방어선 1-③: 미끼 객체 하나가 경보 천 개보다 낫다
다음 글 방어선 2-①: WAF와 OWASP CRS가 잡는 것, 못 잡는 것
시리즈 전체 목록 해킹 시도를 몇 초 안에 잡는 서버 전체 목록