쿠키 속성 하나 빠지면 세션이 탈취된다
로그인 기능을 만들면 세션 쿠키가 생긴다. 이 쿠키에 적절한 보안 속성이 없으면 XSS 공격 한 번에 세션이 통째로 탈취된다. 공격자가 피해자의 쿠키를 얻으면 비밀번호 없이도 해당 계정으로 로그인할 수 있다.
핵심 속성 3가지
HttpOnly — JavaScript에서 쿠키 접근 차단
HttpOnly가 없으면 document.cookie로 쿠키를 읽을 수 있다. XSS 취약점이 있으면 공격자 스크립트가 이 방법으로 세션 쿠키를 탈취한다.
Set-Cookie: session_id=abc123; HttpOnly
Secure — HTTPS에서만 전송
Secure 플래그가 없으면 HTTP로도 쿠키가 전송된다. 공용 WiFi 환경에서 중간자 공격(MITM)으로 쿠키를 가로챌 수 있다.
Set-Cookie: session_id=abc123; Secure; HttpOnly
SameSite — CSRF 공격 차단
SameSite 속성은 다른 도메인에서 발생한 요청에 쿠키를 포함할지 제어한다.
- Strict: 외부 도메인에서 오는 모든 요청에 쿠키 미전송. 가장 안전하지만 외부 링크로 접근 시 로그아웃 상태가 됨
- Lax: GET 방식의 최상위 레벨 탐색에만 쿠키 전송. 대부분의 경우 적합한 균형점
- None: 제한 없음. Secure 속성 필수
Set-Cookie: session_id=abc123; Secure; HttpOnly; SameSite=Lax
프레임워크별 설정 방법
Django
# settings.py
SESSION_COOKIE_SECURE = True # Secure
SESSION_COOKIE_HTTPONLY = True # HttpOnly
SESSION_COOKIE_SAMESITE = 'Lax' # SameSite
CSRF_COOKIE_SECURE = True
CSRF_COOKIE_HTTPONLY = True
CSRF_COOKIE_SAMESITE = 'Lax'
Express.js
app.use(session({
secret: process.env.SESSION_SECRET,
cookie: {
secure: true, // Secure (HTTPS 필수)
httpOnly: true, // HttpOnly
sameSite: 'lax', // SameSite
maxAge: 3600000 // 1시간 만료
}
}));
Next.js (next-auth)
// next-auth는 기본적으로 보안 설정을 잘 해줌
// 추가로 커스텀할 경우:
export const authOptions = {
cookies: {
sessionToken: {
options: {
httpOnly: true,
sameSite: 'lax',
path: '/',
secure: process.env.NODE_ENV === 'production',
},
},
},
};
쿠키 설정이 올바른지는 브라우저 개발자도구 → Application → Cookies에서 확인하거나, CodeScan의 쿠키 스캔 항목에서 자동 점검할 수 있다.