앱 보안 강화를 위한 reCAPTCHA와 IP 기반 사기 탐지 구현
카테고리
프로그래밍/소프트웨어 개발
서브카테고리
보안
대상자
- 웹 앱 개발자 및 보안 엔지니어
- 중간 난이도: reCAPTCHA API와 Redis 사용 경험 필요
핵심 요약
- reCAPTCHA + IP 기반 탐지 :
reCAPTCHA 실패 횟수
를 Redis로 추적하여 5회 이상 시 IP 차단 - 코드 구현 핵심 :
zod
로 JSON 검증,ioredis
로 실패 카운터 관리,MAX_FAILS
,FAIL_WINDOW
,BLOCK_TIME
파라미터 조정 - 보안 강화 효과 : 단일 실패 시 사용자 차단 방지, 단기 반복 실패 시 자동 차단, 성공 시 카운터 리셋
섹션별 세부 요약
1. 문제 상황 분석
- 사용자 오류 대응 : 네트워크 문제 등으로 인한 단일 reCAPTCHA 실패는 사용자 차단 금지
- 봇 공장 대응 : IP 주소 변경을 통한 반복적 공격 탐지 필요
- 중첩 보안 전략 : reCAPTCHA + IP 실패 카운터로 보안 강화
2. 구현 단계
- reCAPTCHA 검증 API 호출
- Google의
siteverify
API로 token 검증 - JSON 응답에
success
필드와error-codes
배열 포함 - Redis 키 정의
FAIL_KEY(ip)
: 실패 횟수 저장BLOCK_KEY(ip)
: 차단 상태 저장MAX_FAILS=5
,FAIL_WINDOW=1시간
,BLOCK_TIME=24시간
설정- 실패 카운터 관리 함수
```ts
async function recordFailure(ip: string) {
const key = FAIL_KEY(ip);
const count = await redis.incr(key);
if (count >= MAX_FAILS) {
await redis.set(BLOCK_KEY(ip), "1", "EX", BLOCK_TIME);
}
}
```
- 성공 시 카운터 리셋
```ts
async function resetFailures(ip: string) {
await redis.del(FAIL_KEY(ip));
}
```
3. 통합 함수 구현
- 차단 상태 확인 :
isBlocked(ip)
함수로 Redis에 저장된 차단 키 검증 - Google API 호출 및 데이터 검증
zod
스키마로 JSON 응답 검증SiteVerify
스키마:
```ts
const SiteVerify = z.object({
success: z.boolean(),
"error-codes": z.array(z.string()).optional(),
});
```
- 실패 시 로깅 및 차단
- 네트워크 오류, JSON 파싱 실패, reCAPTCHA 실패 시
recordFailure(ip)
호출
결론
- 사용법 팁 :
MAX_FAILS
,FAIL_WINDOW
,BLOCK_TIME
을 트래픽 패턴에 맞게 조정하여 보안/사용자 경험 균형 유지 - 실무 적용 예 : 로그인/회원가입 폼에서 reCAPTCHA와 IP 기반 탐지 결합하여 자동화 공격 차단
- 장점 요약 : 복잡한 아키텍처 없이 Redis + reCAPTCHA로 가볍게 보안 강화 가능