취약: 세션 ID가 일정한 패턴으로 발급되거나 세션 종료 시간이 설정되지 않아 세션 재사용이 가능한 경우
경계 케이스 (Edge Case) 처리 방법
세션 만료 시간은 서비스 특성에 맞게 설정 (10~60분 권장)
너무 짧은 만료 시간은 사용자 경험 저하
로그아웃 시 반드시 세션 무효화
권장 설정값
세션 ID 최소 128비트 이상
세션 만료: 10~60분 (서비스 특성에 따라)
JWT 알고리즘: HS256 이상
JWT 비밀 키: 최소 256비트
2. 점검 방법
세션(Session) 점검
Step 1: 세션 ID 패턴 확인
1
로그인 과정에서 발급받은 세션 ID를 확인하고 로그아웃 후 재 로그인 시 각각 발급받은 세션 ID에 대해 일정한 패턴이 존재하는지 검증
Step 2: 세션 만료 확인
1
로그인 후 웹 페이지 사용을 중지한 상태로 일정 시간이 경과하였을 때 세션이 유지되는지 확인
JWT(JSON Web Token) 점검
Step 1: JWT 사용 확인
1
사용자 인증 및 상태 유지를 위해 JWT가 사용되는지 확인
Step 2: JWT 디코딩
1
JWT의 헤더와 페이로드 부분을 Base64 디코딩하여 내용을 확인
Step 3: 페이로드 변조 시도
1
페이로드 변조 후 서명을 삭제하거나 None 알고리즘으로 변조하였을 때 토큰이 유효한지 확인
3. 조치 방법
1. 세션 고정 및 예측 방지
Java Spring Security:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 세션 고정 방지@Overrideprotectedvoidconfigure(HttpSecurityhttp)throwsException{http.sessionManagement().sessionFixation().migrateSession()// 로그인 시 새 세션 ID 발급.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED).maximumSessions(1)// 동시 세션 1개로 제한.maxSessionsPreventsLogin(false).expiredUrl("/login?expired");}// 로그인 시 세션 ID 변경@RequestMapping("/login")publicStringlogin(HttpServletRequestrequest){request.changeSessionId();// 신규 세션 ID 발급return"redirect:/home";}
ASP.NET web.config:
1
2
3
4
5
6
7
8
9
10
11
<system.web><!-- 세션 고정 방지 --><sessionStateregenerateExpiredSessionId="true"/><!-- 세션 예측 방지 --><machineKeyvalidationKey="AutoGenerate,IsolateApps"decryptionKey="AutoGenerate,IsolateApps"validation="HMACSHA512"decryption="AES"/></system.web>
PHP:
1
2
3
4
5
6
7
// 기존 세션 삭제 후 새 세션 ID 생성
session_start();session_regenerate_id(true);// 예측 불가능한 세션 ID 생성
ini_set('session.entropy_length','256');ini_set('session.entropy_file','/dev/urandom');
// 안전한 알고리즘 사용
constjwt=require('jsonwebtoken');consttoken=jwt.sign({userId:user.id,role:user.role},process.env.JWT_SECRET,// 강력하고 랜덤한 비밀 키
{algorithm:'HS256',// 안전한 알고리즘 명시
expiresIn:'1h'// 짧은 만료 시간
});// 검증 시 알고리즘 명시
jwt.verify(token,process.env.JWT_SECRET,{algorithms:['HS256']// none 알고리즘 차단
});
안전한 JWT 서명 알고리즘:
HS256, HS384, HS512 (HMAC-SHA)
RS256, RS384, RS512 (RSA)
ES256, ES384, ES512 (Elliptic Curve)
취약한 알고리즘:
HS1, RS1 (SHA-1 기반)
none (서명 없음)
plaintext (평문 서명)
4. 동시 세션 제어
1
2
3
4
5
6
7
8
// 동시 접속 세션 제한@Overrideprotectedvoidconfigure(HttpSecurityhttp)throwsException{http.sessionManagement().maximumSessions(1)// 최대 1개 세션.maxSessionsPreventsLogin(false)// 이전 세션 만료.expiredUrl("/login?expired");}