특정 인증 방식을 설계할 때는 단순히 "어떻게 구현할 것인가"보다 **"공격자가 이 설계의 약점을 어떻게 파고들 것인가"**를 먼저 고려해야 합니다.
가장 대표적인 세 가지 인증 방식(세션, JWT, OAuth)의 설계 시 발생할 수 있는 주요 보안 취약점과 그 대응 방안을 정리해 드립니다.
1. 세션 기반 인증 (Session-based)
서버 메모리나 DB에 상태를 저장하는 방식에서 발생하는 취약점입니다.
- 취약점: 세션 하이재킹 (Session Hijacking)
- 설명: 공격자가 사용자의 Session ID가 담긴 쿠키를 탈취하여 사용자 행세를 하는 공격입니다.
- 설계 결함: 쿠키에 보안 옵션을 설정하지 않거나, 세션 만료 시간을 너무 길게 잡은 경우 발생합니다.
- 대응 설계:
- HttpOnly 플래그: 자바스크립트(XSS)를 통한 쿠키 접근 차단.
- Secure 플래그: HTTPS 연결에서만 쿠키 전송.
- 세션 타임아웃: 일정 시간 미활동 시 세션 강제 종료.
2. JWT 기반 인증 (Stateless Token)
토큰 자체에 정보를 담아 클라이언트가 들고 다니는 방식의 취약점입니다.
- 취약점 1: 알고리즘 없음 (None Algorithm) 공격
- 설명: JWT 헤더의 alg 필드를 none으로 조작하여 서명 검증을 우회하는 방식입니다.
- 설계 결함: 서버에서 alg: none을 허용하도록 라이브러리가 설정된 경우 발생합니다.
- 취약점 2: 토큰 탈취 및 무효화 불가
- 설명: JWT는 서버가 상태를 갖지 않으므로, 한번 탈취되면 만료 전까지 강제로 로그아웃시킬 방법이 없습니다.
- 대응 설계:
- Secret Key 관리: 복잡도가 높은 키를 사용하고 노출을 철저히 차단.
- Access/Refresh Token 분리: Access 토큰은 수명을 짧게(예: 30분), Refresh 토큰은 DB/Redis에 저장하여 관리(필요 시 차단 가능).
3. OAuth 2.0 및 소셜 로그인
제3자(Google, Kakao 등)를 통해 인증을 위임받는 방식의 취약점입니다.
- 취약점: 리다이렉트 URI 조작 (Redirect URI Manipulation)
- 설명: 인증 성공 후 사용자를 돌려보낼 주소(redirect_uri)를 공격자의 서버 주소로 바꿔서 인증 코드(Authorization Code)를 가로챕니다.
- 설계 결함: 서버에서 허용된 리다이렉트 주소 목록(Allow-list)을 엄격하게 검증하지 않을 때 발생합니다.
- 대응 설계:
- Exact Match 검증: 등록된 URI와 100% 일치하는지 확인.
- State 파라미터 사용: CSRF 공격 방지를 위해 요청 시 랜덤 값을 보내고 콜백 시 동일한지 확인.
4. 공통 인증 보안 설계 원칙 (정리)
| 설계 항목 | 보안 위협 | 방어 전략 |
| 비밀번호 저장 | 데이터베이스 유출 | BCrypt, Argon2 등 단방향 해시 + 솔팅(Salting) |
| 로그인 시도 | 브루트 포스 (무작위 대입) | 계정 잠금 정책 또는 CAPTCHA 도입 |
| 전송 구간 | 중간자 공격 (MITM) | 전 구간 TLS(HTTPS) 적용 필수 |
| 에러 메시지 | 정보 노출 | "아이디가 틀렸습니다" 대신 "아이디 또는 비밀번호가 잘못되었습니다"로 모호하게 처리 |
설계 시 주의할 점
인증 시스템을 직접 설계할 때 가장 위험한 것은 **"독자적인 암호화/인증 알고리즘을 만드는 것"**입니다. 검증된 표준(Spring Security, JJWT 등)을 사용하되, 위의 설정값들을 보안 원칙에 맞게 튜닝하는 것이 가장 안전합니다.
현재 준비 중인 프로젝트에서 **어떤 인증 방식(세션 vs JWT 등)**을 선택할지 고민 중이신가요? 상황에 맞는 방식을 추천해 드릴 수 있습니다.