웹 취약점 2026.05.22 · 조회 3895

Session Fixation: 로그인 전 세션 ID가 탈취 진입점이 되는 이유 [2026]

로그인 후 세션 ID를 새로 발급하지 않으면 공격자가 미리 심어둔 ID로 사용자 세션을 탈취한다. Django/Express 표준 세션 재발급 코드와 4가지 실수를 정리했다.

S
보안 전문 기업 SENTRIX 레드팀
해킹대회 수상 · 보안 실무 10년 · 실전 진단 경험을 바탕으로 작성합니다.
웹사이트를 운영하고 있다면
보안 헤더·인증서·공개 노출부터 무료로 점검하세요. 결과 링크는 이메일로 받습니다. 로그인 이후 권한·업무 로직은 별도 검증이 필요합니다.

다음 화면에서 이메일과 점검 권한을 확인합니다. 회원가입·카드 없이 무료 요약을 받고, 상세 리포트는 선택 구매합니다.

Session Fixation은 공격자가 사용자가 로그인하기 전에 알려진 세션 ID를 심어두고, 로그인 후 동일 ID로 사용자 세션을 탈취하는 인증 우회 공격이다.
AI 코딩 도구가 만든 코드에서 가장 자주 누락되며, 누락 시 인증 우회·데이터 탈취·서비스 마비로 직결된다.
이 글은 자주 발생하는 실수 패턴, 표준 구현 코드, 30초 자가진단, 24시간 패치 순서를 정리했다.

한눈에 보는 핵심

Q. 로그인 후 세션 ID를 왜 새로 발급해야 하나요? A. 공격자가 사전에 발급된 세션 ID를 미리 알고 있다면 사용자가 로그인한 뒤에도 동일 ID로 인증 상태에 접근 가능합니다. Q. Django는 자동으로 처리하나요? A. django.contrib.auth.login()이 자동 세션 키 회전을 수행하지만 커스텀 인증 흐름은 직접 cycle_key() 호출이 필요합니다. Q. HttpOnly·Secure 쿠키만으로 충분한가요? A. 충분하지 않습니다. XSS·MITM 차단은 하지만 사전 심기 공격은 세션 재발급으로만 막힙니다.

자주 발생하는 실수 패턴

#패턴위험도
1로그인 후 세션 키 회전 누락치명
2커스텀 인증 흐름에서 cycle_key() 미호출치명
3세션 쿠키에 HttpOnly·Secure·SameSite 미적용높음
4로그아웃 시 세션 무효화 누락높음

표준 구현 코드

# Django 표준 — 로그인 후 자동 세션 키 회전
from django.contrib.auth import login as auth_login

def login_view(request):
    user = authenticate(request, username=u, password=p)
    if user:
        auth_login(request, user)  # 내부에서 request.session.cycle_key() 호출
        return redirect('/dashboard/')

# 커스텀 SSO/OAuth 흐름 — 명시적 호출 필수
def sso_callback(request):
    user = oauth_provider.get_user(request)
    if user:
        request.session.cycle_key()  # 핵심 — 새 세션 ID 발급
        request.session['user_id'] = user.id
        return redirect('/dashboard/')

# settings.py — 세션 쿠키 강화
SESSION_COOKIE_HTTPONLY = True
SESSION_COOKIE_SECURE = True
SESSION_COOKIE_SAMESITE = 'Lax'
SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'

핵심 4요소를 모두 충족해야 결함이 사라진다.
AI 도구는 동작 코드만 출력하므로 보안 분기는 별도로 강제해야 한다.
미들웨어/데코레이터로 모든 경로에 일괄 적용이 표준이다.

지금 1분만, CodeScan 무료 스캔으로 노출 패턴 자동 점검.

30초 자가진단

# 1. 로그인 전 쿠키 캡처
curl -c before.txt https://yourdomain.com/login/

# 2. 로그인
curl -b before.txt -c after.txt -X POST https://yourdomain.com/login/ -d "username=x&password=y"

# 3. sessionid 비교 — 동일하면 결함
diff <(grep sessionid before.txt) <(grep sessionid after.txt)

위 시그널이 발견되면 결함이다. OWASP: Session Fixation 참조.

24시간 패치 절차

순위조치
1로그인 직후 request.session.cycle_key() 호출
2SESSION_COOKIE_HTTPONLY/SECURE/SAMESITE 활성화
3로그아웃 시 request.session.flush() 호출
4커스텀 SSO/OAuth 콜백 핸들러 명시적 재발급

지금 해야 할 것

실무자: CodeScan 무료 스캔으로 30초 점검.
CISO·임원: 통합 보안 점검은 SENTRIX 보안 상담.
결함 발견 시 24시간 안에 패치 완료가 표준이다.

관련 글

{"@context":"https://schema.org","@type":"FAQPage","mainEntity":[{"@type":"Question","name":"로그인 후 세션 ID를 왜 새로 발급해야 하나요?","acceptedAnswer":{"@type":"Answer","text":"공격자가 사전에 발급된 세션 ID를 미리 알고 있다면 사용자가 로그인한 뒤에도 동일 ID로 인증 상태에 접근 가능합니다."}},{"@type":"Question","name":"Django는 자동으로 처리하나요?","acceptedAnswer":{"@type":"Answer","text":"django.contrib.auth.login()이 자동 세션 키 회전을 수행하지만 커스텀 인증 흐름은 직접 cycle_key() 호출이 필요합니다."}},{"@type":"Question","name":"HttpOnly·Secure 쿠키만으로 충분한가요?","acceptedAnswer":{"@type":"Answer","text":"충분하지 않습니다. XSS·MITM 차단은 하지만 사전 심기 공격은 세션 재발급으로만 막힙니다."}}]}

내 사이트도 점검해보세요

URL 입력, 결과 링크는 메일로 받는 무료 점검. 회원가입·카드 불필요.

AI 코딩 보안 체크리스트 받기

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

배포·설정을 바꾼 뒤에는 같은 주소를 다시 점검하세요. 수정 후 재점검 순서와 일정 저장 · 자동 점검이 필요하면 Continuous의 범위와 체험 조건을 확인하세요.
이런 글을 계속 받아보려면 뉴스레터 구독 · RSS 피드