daniel7481의 개발일지

Cookie & Session 본문

Web hacking/Dreamhack

Cookie & Session

daniel7481 2024. 3. 24. 00:59
반응형

쿠키

클라이언트와 서버는 HTTP 프로토콜을 사용해 Request와 Response로 통신한다.

 

하지만 이러한 통신 기법에는 단점이 존재하는데, 

1) Connectionless: 하나의 요청에 하나의 응답을 한 후 연결을 종료하는 것

2) Stateless: 통신이 끝난 후 상태 정보를 저장하지 않는 것

 

이러한 단점을 극복하기 위해 Key - Value로 이루어진 Cookie가 탄생했다. 쿠키는 서버가 클라이언트에게 한 번 발급하면 그 이후 클라에서 Request를 보낼 때마다 같이 전송한다.

우리가 흔히 보는 로그인 상태 유지나(상태 정보), 광고에서 1일간 보지 않기 등(정보 기록)이 쿠키 덕분에 쓸 수 있는 기능이라고 이해하면 편할 것 같다

 

세션

이러한 쿠키에서도 단점이 존재하는데, 악이적인 클라이언트는 쿠키 정보를 변조할 수 있다는 점이다. 이러한 단점을 보안하기 위해 세션이 등장했다.

세션은 유추 할 수 없는 문자열로, 인증 정보를 서버에 저장하고 해당 데이터에 접속할 수 있는 키(Session id)를 만들어 브라우저는 해당 키를 저장하고 HTTP 요청을 보낼 때 사용한다. 서버는 요청에 포함된 키에 해당하는 데이터를 가져와 인증 상태를 확인한다.

둘 사이 핵심 차이점은 쿠키는 데이터 자체를 이용자가 저장하고, 세션은 서버가 저장한다.

개발자 도구를 사용하여 콘솔에서 document.cookie 혹은 Application 칸에서 Cookies 목록 안을 확인하여 쿠키를 확인하고, Application 칸에서 Session Storage 안의 Sessionid를 통해 세션을 확인할 수 있다.

 

SOP

이러한 정보를 토대로 이해해 보았을 때 쿠키와 세션은 굉장히 중요하다. 사용자의 인증 정보를 탈취하여 이용자의 계정을 마음대로 사용하는 일이 발생할 수도 있는 것이다. 이러한 문제를 방지하기 위해 동일출처 정책(SOP:Same origin policy)가 등장했다

 

브라우저는 쿠키를 브라우저 내부에 보관한다. 또한 브라우저는 웹 서비스에서 쿠키를 HTTP 요청에 포함시켜 전달한다. 여기서 그치지 않고 브라우저는 타 사이트에 접속할 때도 쿠키를 함꼐 전송하는 특징을 가지고 있다. 이런 특성 때문에 악의적인 페이지는 클라이언트의 권한을 이용해 대상 사이트에 HTTP 요청을 보내고, 응답 정보를 획득하는 코드를 실행 할 수 있다. 따라서 클라 입장에서는 가져온 데이터를 악의적인 페이지에서 읽을 수 없도록 해야 한다.

 

URL에서 프로토콜, 포트, 호스트가 전부 같아야 SOP로 인정된다. 나누어서 이해해보자

https://www.example.com이라는 는 오리진과 비교해보자

http://www.example.com은  https인 오리진과 비교해서 http인 프로토콜을 사용했으므로 Cross origin이다

https://cross.example.com은 www 가 host인 오리진과 비교해서 cross라는 host를 사용했으므로 Cross origin이다

https://www.example.com:1234/는  포트   번호가 1234이므로 Cross origin이다

 

CORS

SOP는 웹 보안에서 굉장히 중요한 요소지만, 이미지, css, js 등은 SOP의 영향을 받지 않는다. 또한 SOP 정책을 완화하여 다른 출처의 데이터를 처리해야 하는 경우도 있다. 예로 들어 특정 사이트가 여러 개의 서비스를 다른 host로 이용하고 있다고 생각해보자. 

https://example.com이 메인이고, https://mail.example.com, https://cafe.example.com 등 메인에서 로그인한 유저의 쿠키를 다른 서비스에서도 사용해야 할 경우가 있다. 이러한 상황에서 CORS와 관련된 HTTP 헤더를 추가하여 전송하는 방법을 사용한다. 

/*XMLHttpRequest 객체는 웹 브라우저와 웹 서버 간 데이터 전송을 도와주는 객체이고, 이를 선언해준다*/
xhr = new XMLHttpRequest();
/*'https://theori.io/whoami'에 POST 요청을 보내도록 한다*/
xhr.open('POST', 'https://theori.io/whoami');
/* HTTP 요청을 보낼 때 쿠키 정보를 사용하게 해준다 */
xhr.withCredentials = true;
/*HTTP BODY를 통해 json 형태로 보낼 것이라고 알려준다 */
xhr.setRequestHeader('Content-Type', 'application/json');
/* HTTP 요청 실행 */
xhr.send("{'data':'WhoAmI'}");

위 코드를 통해 요청을 보내면, 발신측의 HTTP header에서 메소드가 POST여야 할 것 같지만, OPTIONS 메소드로 요청이 전달된다. 이를 CORS preflight이라고 하며, 수신 측에 웹 리소스를 요청해도 되는지 질의하는 과정이다.

OPTIONS /whoami HTTP/1.1
Host: theori.io
Connection: keep-alive
Access-Control-Request-Method: POST /*어떤 메소드를 추가적으로 사용할 수 있는지 */
Access-Control-Request-Headers: content-type /* 어떤 헤더들을 사용 할 수 있는지 */
Origin: https://dreamhack.io
Accept: */*
Referer: https://dreamhack.io/

이에 대해 다음과 같은 응답 결과가 나온다

HTTP/1.1 200 OK /* 응답 성공 */
Access-Control-Allow-Origin: https://dreamhack.io /*해당하는 Origin에서 들어오는 요청만 처리한다 */
Access-Control-Allow-Methods: POST, GET, OPTIONS /* 해당되는 메소드 요청만 처리한다 */
Access-Control-Allow-Credentials: true /* 쿠키 사용 여부 */
Access-Control-Allow-Headers: Content-Type /* 헤더의 사용 가능 여부 */
반응형

'Web hacking > Dreamhack' 카테고리의 다른 글

Cross Site Scripting(XSS)  (0) 2024.03.24