제공 서비스
웹 보안 점검 소스코드 분석 (SAST) CRM 보안 진단 다크웹 유출 조회
요금제 스토어 블로그 파트너 마이페이지 무료 보안 점검
인증 보안 2026.05.02 · 조회 173

웹 로그인 보안 완전 가이드 — Brute force 차단·Rate limit·2FA 실전 구현 (2026)

공격자가 새 타깃에서 가장 먼저 두드리는 곳은 로그인 엔드포인트다. OWASP ASVS V2 기준 Brute force 탐지·Nginx Rate limit·TOTP 2FA 3중 레이어 구현 코드와, 다 만들어놓고도 뚫리는 함정 4가지를 정리했다.

Verizon DBIR 2024 보고서에 따르면 웹 애플리케이션 침해 사고의 77%가 탈취된 자격증명을 사용한 공격이다. Have I Been Pwned에 등록된 유출 계정 121억 개를 돌리는 Credential stuffing은 평균 0.5~2% 성공률이 나온다. 100만 건 시도에 최소 5,000개가 뚫린다는 뜻이다. OWASP ASVS V2 Authentication이 Brute force 방어를 필수 통제로 지정한 이유다.

"The use of authenticators that resist phishing and other attacks is one of the most effective security measures available." — NIST SP 800-63B Digital Identity Guidelines, §5.2.5

왜 로그인 엔드포인트가 1번 타깃인가

로그인 엔드포인트는 구조적으로 인증 없이 접근 가능해야 하고, 성공과 실패를 구분하는 응답을 반환해야 한다. Cloudflare Radar 집계 기준으로 전체 인터넷 트래픽의 약 30~40%가 자동화 봇에서 발생하며, 이 중 상당 비율이 인증 엔드포인트를 목표로 한다.

Brute force 차단은 어떻게 구현하나요

OWASP Authentication Cheat Sheet는 IP 기준과 계정 기준을 병행할 것을 명시한다.

실패 카운트와 IP 락 — Django + Redis 구현

import hashlib
from django.core.cache import cache
from django.http import JsonResponse

MAX_ATTEMPTS_BY_IP = 20
MAX_ATTEMPTS_BY_ACCOUNT = 5
LOCKOUT_SECONDS = 900

def check_brute_force(request, username):
    ip = get_client_ip(request)
    ip_key = f"bf:ip:{hashlib.sha256(ip.encode()).hexdigest()[:16]}"
    acc_key = f"bf:acc:{hashlib.sha256(username.encode()).hexdigest()[:16]}"
    if cache.get(ip_key, 0) >= MAX_ATTEMPTS_BY_IP or cache.get(acc_key, 0) >= MAX_ATTEMPTS_BY_ACCOUNT:
        return False
    return True

Rate Limit은 애플리케이션 레이어만으로 충분한가

충분하지 않다. Microsoft 보안팀이 발표한 데이터에 따르면 MFA + Rate limit 조합은 자동화 공격의 99.9%를 차단한다.

Nginx limit_req 설정

http {
    limit_req_zone $binary_remote_addr zone=login_limit:10m rate=5r/m;
    server {
        location /login {
            limit_req zone=login_limit burst=3 nodelay;
            limit_req_status 429;
            proxy_pass http://django_app;
        }
    }
}

Cloudflare Rate Limiting Rule

# Expression
(http.request.uri.path contains "/login" and http.request.method eq "POST")
# Period: 60s / Requests: 10 / Action: Block

2FA/MFA 방식별 비교 — TOTP·SMS·FIDO2 중 뭐가 좋나요

FIDO Alliance 2024 보고서에 따르면 Passkey를 지원하는 서비스는 글로벌 기준 2023년 대비 2배 이상 증가했다.

방식보안 수준피싱 저항구현 난이도운영 비용
TOTP높음중간낮음없음
Email OTP중간낮음낮음발송 비용
SMS OTP중간낮음중간SMS 비용
FIDO2 / Passkey최고높음높음없음
하드웨어 키최고높음높음키 구매비용
import pyotp

def generate_totp_secret():
    return pyotp.random_base32()

def verify_totp(secret, token):
    totp = pyotp.TOTP(secret)
    return totp.verify(token, valid_window=1)

다 구현해놓고도 뚫리는 함정 4가지

1. 비밀번호 재설정 토큰 무한 유효

OWASP Forgot Password Cheat Sheet는 재설정 토큰 유효시간을 15분 이내로 제한하고, 사용 후 즉시 무효화할 것을 명시한다.

2. 세션 고정 (Session Fixation)

Django는 기본적으로 로그인 시 cycle_key()를 자동으로 호출해서 세션 ID를 교체한다. 직접 세션을 다루는 코드가 있다면 반드시 로그인 성공 직후 세션을 재발급해야 한다.

3. X-Forwarded-For 우회

TRUSTED_PROXIES = {"10.0.0.1", "10.0.0.2"}

def get_real_ip(request):
    remote_addr = request.META.get("REMOTE_ADDR", "")
    if remote_addr not in TRUSTED_PROXIES:
        return remote_addr
    xff = request.META.get("HTTP_X_FORWARDED_FOR", "")
    return xff.split(",")[0].strip() if xff else remote_addr

4. 2FA 우회 — 비밀번호 재설정 백도어

OWASP ASVS V2.5.6 항목은 비밀번호 재설정 완료 후 모든 활성 세션을 강제 만료시킬 것을 요구한다. 보안 전문 기업 SENTRIX에서 웹 취약점 점검을 수행하다 보면 이 네 가지 패턴으로 우회가 되는 경우가 반복된다.

자주 묻는 질문

Brute force 차단을 IP 락으로만 해도 되나요?

충분하지 않습니다. NAT 환경에서는 정상 사용자가 같은 IP를 공유하기 때문에 한 명이 IP 락을 유발하면 나머지도 잠깁니다. IP 기준 + 계정 기준을 같이 적용해야 합니다.

SMS 2FA는 왜 권장하지 않나요?

SIM swap 공격에 취약합니다. 2019년 Twitter CEO 잭 도시 계정, 2020년 다수 암호화폐 거래소 계정이 SIM swap으로 뚫린 사례가 있습니다.

FIDO2/Passkey 구현은 복잡한가요?

Python의 py_webauthn 라이브러리가 WebAuthn 서버 로직 대부분을 처리해줍니다. 신규 서비스 기준으로 초기 구현에 2~3일이 현실적인 일정입니다.

Rate Limit 설정에서 합리적인 임계치는 얼마인가요?

OWASP Authentication Cheat Sheet 권고는 동일 IP 기준 분당 5~10회, 계정 기준 15분에 5회입니다.

Django 기본 인증을 쓰면 이 설정들이 자동으로 적용되나요?

아닙니다. Django 기본 인증 뷰는 Rate limit이나 Brute force 차단을 기본으로 제공하지 않습니다. django-axes 패키지를 추가하면 계정 잠금과 IP 차단을 설정으로 활성화할 수 있습니다.

로그인 페이지 직접 점검해보기

codescan.kr에서 로그인 페이지 URL을 입력하면 rate limit 미적용 여부, 인증 관련 헤더 누락, 세션 처리 이상 징후를 자동으로 탐지한다. 해킹대회 수상 경력의 보안 전문가가 설계한 룰셋 기반이다.

로그인 보안 브루트포스 차단 Rate limit 2FA MFA TOTP FIDO2 Passkey 인증 보안 Django 보안 Nginx 설정 OWASP

내 사이트도 점검해보세요

CodeScan으로 보안 취약점을 무료로 점검할 수 있습니다.

무료 스캔 시작하기 →
🛒
추천 상품
웹서비스 런칭 전 보안 세팅
런칭 전에 반드시 해야 하는 보안 설정을 원격으로 직접 해드립니다. HTTPS, 환경변수 분리, 보안 헤더…
220,000원 150,000원

🔒 바이브코딩 보안 체크리스트 받기

바이브코딩 보안 체크리스트(PDF)를 무료로 받아보세요.