개발/프로젝트

[세션 / 토큰 로그인 프로젝트] 고도화(1) 네이버의 로그인 관련 세션쿠키 파헤치기

prpn97 2023. 7. 15. 23:26

계기

 

세션로그인의 장점을 생각해보면, 사용자의 인증정보인 세션ID를 클라이언트가 아닌

서버에서 보관하기 때문에 비교적 인증정보를 탈취당할 위험이 줄어든다는 것인데,

세션로그인을 구현하면서 한 가지 의문이 있었다.

 

결국 클라이언트와 서버가 인증정보를 주고받으며 해당 사용자임을 입증하는데,

서버는 세션 데이터를 db에 보관하지만 그 값을 쿠키에 담아서 클라이언트에 보내준다면..

아무리 httpOnly, secure 등 쿠키에 여러 설정을 한다고 해도 당장 개발자도구만 열어봐도

쿠키에 세션id를 넣어서 주고받기 때문에 세션하이재킹을 피할 수가 없다고 생각했다.

express-session의 설정 중 secret으로 긴 문자열을 환경변수에 저장하여 쓰지만,

복호화를 하든지 말든지 그 값 그대로 데이터를 주고받으면 하는 의미가 없지 않나 싶다. 

 

 

그래서.. 대기업에서는 어떤 데이터를 어떻게 주고받는지 내부적으로는 파악할 수 없지만,

보이는대로만이라도 파악해보고, 이해되는대로 적용해보고자 한다.

 

구상

먼저 개발자도구를 열어 네이버에서 확인할 수 있는 쿠키를 각각 최대한 파악하고,

조건을 살펴 유추해보고자 한다. 각 쿠키의 약자는 gpt의 힘을 빌려 유추해보겠다.

 

로그인 과정 쿠키 파악하기

1. 메인페이지

접속하면 로그인하지 않아도 NNB, PM_CK_loc를 확인할 수 있다. 

네이버에서 다른 여러 서비스를 이용할 때 여러 쿠키가 전송되는데,

다른 쿠키는 삭제하고 메인페이지에 접속하면 더 등장하지 않지만, 저 둘은 삭제해도 메인페이지를 접속하면 계속해서 등장한다. 

 

그 중 NNB는 삭제 후 다시 접속하면 새로 생성, PM_CK_loc는 동일한 쿠키값이 확인되었다. 

 

NNB는 1년간 보존되고,, PM_CK_loc는 하루동안 보존되는데,

NNB는 네이버의 어떤 서비스를 들어가더라도 다 확인되는 쿠키였고,

loc는 메인페이지에서만 확인할 수 있었다. 

 

유추를 해도 확실한 것은 아니니 일단 넘어가보자. 

 

2. 로그인페이지
nid_buk, nid_slevel 를 확인할 수 있다. gpt는 이렇게 알려주는데, 맞는 것 같다.

nid_buk : Browsing User Key의 약자로, 사용자를 식별하는 고유한 키(Key)를 나타냅니다.

nid_slevel: Secure Level의 약자로, 보안 수준을 나타내는 쿠키입니다.

 

그런데, 로그인하기 전에 사용자를 식별하는 고유 키값이 로그인페이지에서 보인다?

이 nid_buk값은 local storage에서도 확인할 수 있었다. 

nid_slevel은 로그인할 때 ip보안을 체크하면 1, 체크하지 않으면 -1이 확인된다.

로그인하고 나니 둘 다 값이 그대로 보였다. 

 

 

 

3. 로그인 후 메인페이지

로그인하면 만료기간이 없는 session쿠키만 4개가 더 들어온다. 

NID_AUT, NID_SES, NID_JKL, nid_inf 인데, jkl빼고는 어느정도 바로 유추가 되었다. 

gpt의 힘을 다시 빌려보자. 

 

NID_AUT: 인증(Authentication)을 나타내는 쿠키

NID_SES: 세션(Session)을 나타내는 쿠키

nid_inf: Information의 약자로, 사용자의 정보를 나타내는 쿠키

NID_JKL: 사용자가 언어(Language) 설정을 유지하는 데 사용되는 쿠키

 

jkl 빼고는 gpt와 의견이 같았고, jkl은 맞는지 모르겠지만 

이제 각각 쿠키를 파악해보면, 인증관련된 쿠키답게 aut, ses는 쿠키를 지우면 로그아웃 되었다. 

그 중에서도 ses는 페이지를 새로고침할때마다 새로 생성되어 값이 바뀌었다.

또한 로그인 후 메일, 카페, 블로그, 페이라는 로그인한 사용자 정보 아래의 메뉴를 클릭하면

JSESSIONID 라는 httpOnly가 설정된 쿠키가 클릭할때마다 생성되는데,

그 중 블로그, 페이는 secure도 같이 체크가 되어있었다. 

 

확실하지는 않지만, 그동안 배운 것들을 토대로 생각해보면,

aut에는 httpOnly에 체크되어있고, ses는 아무것도 체크되어있지 않았다. 

내가 설정했던 것처럼 세션(ses)은 전역으로 설정해서 뭘 하든 계속 리로드되어 새로 생성되고,

aut는 새로 로그인할 때마다 생성되는 쿠키다. 

클라이언트에서 접근할 수 없는.. 실질적으로 서버에서 만들어서 인증하는 쿠키인 것 같다.

 

 

이해한 점

 

딱 여기서 내가 고민하고 있는 부분이 보였다.

로그인을 했을 때 세션id를 그대로 쿠키에 담으면 다 보이기 때문에 

그대로 주면 안된다고 생각을 했다. 

 

일단 ses는 계속 바뀌는 값인데 왜 없으면 로그아웃되는지, 

로그아웃하지 않는 이상 계속 같은 값을 가지고 있는 aut는 보안에 취약하지 않은지,

확실하게 이해가 된건 아니지만, 어느정도 정리는 된 것 같다. 

 

db에 보관하고 있는 세션데이터는 aut이고, 그대로 쿠키에 담지만

그러나 그대로 탈취하게 되서 이용할 수 있기 때문에 세션하이재킹을 방지하기 위해

계속 바뀌는 ses값을 제시해야 해당 사용자라고 파악할 수 있는게 아닌가 싶다. 

 

나의 프로젝트에 적용한다면, express-session을 통해

req.sessionID의 값은 계속해서 생성된다. 

그리고 쿠키에 넣은 세션값은 로그인할 동시에 쿠키에 넣은 req.cookies.sessionID가 되겠다. 

 

이제 이 둘을 정확히 파악하고 구분해서 내 프로젝트에 적용해보고, 또 포스팅해야겠다. 

728x90