HTTP는 Stateless (상태 비저장) 프로토콜
HTTP는 상태를 저장하지 않는(stateless) 프로토콜이다. 즉, 클라이언트가 서버에 요청을 보낼 때마다 서버는 이전 요청에 대한 정보를 기억하지 않는다. 각 요청은 독립적으로 처리되며, 서버는 요청이 끝나면 클라이언트가 누구였는지에 대해 기억하지 않는다. 이를 stateless라 하며, 이는 웹 애플리케이션을 설계할 때 중요한 고려사항이 된다.
이러한 특성을 보완하기 위해 HTTP에서는 쿠키와 세션이 사용된다. 클라이언트의 상태를 유지하고, 클라이언트가 누구인지 확인하기 위해 두 가지 방법을 활용할 수 있습니다.
쿠키와 세션의 개념
쿠키 (Cookie)
- 정의: 클라이언트(브라우저)에 작은 데이터를 저장하는 방법. 서버는 클라이언트에게 쿠키를 보내고, 클라이언트는 이를 로컬에 저장한 뒤, 이후 요청 시 자동으로 서버에 전송한다.
- 특징:
- 저장 위치: 클라이언트(브라우저)에 저장.
- 도메인 제한: 쿠키는 특정 도메인에 대해서만 유효하며, 다른 도메인에서는 접근할 수 없음.
- 키-값 쌍: 쿠키는
key-value
형태로 데이터를 저장하며, 예를 들어 로그인 정보나 사용자 설정을 저장할 수 있음. Set-Cookie: auth_token=abcd1234xyz; Path=/; Expires=Thu, 01 Jan 2025 00:00:00 GMT; Secure; HttpOnly; SameSite=Lax
- 유효 시간: 쿠키의 유효 기간을 설정할 수 있어, 브라우저를 닫더라도 설정된 유효 기간 동안 인증 상태나 정보를 유지할 수 있음
- 자동 전송: 사용자가 웹사이트를 방문할 때 브라우저는 쿠키를 자동으로 서버에 전송함.
- 다양한 용도: 쿠키는 인증 외에도 여러 정보(언어 설정, 테마 설정 등)를 저장하는 데 유용함.
세션 (Session)
- 정의: 세션은 서버 측에서 클라이언트의 상태를 관리하는 방식. 서버는 클라이언트에게 세션 ID를 제공하고, 클라이언트는 이 ID를 쿠키에 저장하여 서버와의 연결을 유지.
- 특징:
- 저장 위치: 세션 정보는 서버 측에 저장되며, 클라이언트는 세션 ID만 관리함.
- 서버 관리: 세션 정보는 서버에서 관리되므로, 민감한 데이터를 클라이언트가 아닌 서버 측에 저장하여 보안을 강화할 수 있음.
- 유효 기간: 서버는 세션의 만료 시간을 설정할 수 있으며, 일정 시간이 지나면 세션이 자동으로 삭제됨.
브라우저를 닫으면 세션이 자동 삭제 된다?
→ 꼭 그렇지만은 않다 .
일반적으론 세션 쿠키를 사용하여 관리하면 브라우저가 닫히면 쿠키가 삭제 되어 서버측에서 설정된 세션 만료 시간동안 요청이 안가게 되고 만료가 되면 삭제가 된다.
하지만 세션 쿠키 방식이 아닌 다른 방식으로 세션ID를 관리한다면 브라우저가 닫혀도 세션을 유지시킬 수 있는 방법은 여러 가지가 있음.
쿠키와 세션 방식의 동작 시나리오
- 로그인: 사용자가 로그인하면, 서버는 세션 DB에 유저를 추가하고 세션 ID를 생성.
- 서버는 세션 ID를 클라이언트에게 쿠키로 전송.
- 이후 클라이언트는 요청 시마다 세션 ID를 쿠키를 통해 서버에 전달.
- 서버는 이 세션 ID를 통해 클라이언트가 누구인지 확인하고 인증 상태를 유지.
- 세션 ID만 서버로 보내지므로, 서버는 세션 ID를 기반으로 클라이언트 상태를 추적하고 사용자 정보를 관리할 수 있음.
이렇게, 쿠키는 세션 ID를 전달하기 위한 매개체로 사용되며, 서버는 세션을 통해 사용자의 인증을 유지한다.
- 그럼 브라우저를 열 때 세션 아이디를 무작위로 아무거나 넣어서 로그인 한 상태로 만들 수 있겠네?이러한 방식으로 세션 ID를 무작위로 시도해 로그인된 세션에 접근하려는 공격을 세션 예측 공격(Session Prediction Attack)이라고도 부를 수 있습니다. 만약 세션 ID가 예측 가능하거나 무작위로 생성된 값이 너무 짧거나 간단하다면, 공격자는 세션 ID를 무작위로 시도하여 로그인된 세션에 접근할 수 있을 가능성이 있습니다.
- 세션 ID의 무작위성 강화:
- 세션 ID는 충분히 길고 무작위적이어야 합니다. 세션 ID가 짧거나 예측 가능한 패턴을 따르지 않도록 만들어야 합니다.
- 예를 들어, 32자리 이상의 랜덤 문자열을 사용하여 세션 ID를 생성하고, 이를 충분히 복잡하게 만들어야 합니다.
- 공격자는 무작위로 가능한 세션 ID 값을 맞추려고 할 때, 세션 ID의 범위가 너무 넓으면 성공할 확률이 급격히 줄어듭니다.
- 세션 ID는 충분히 길고 무작위적이어야 합니다. 세션 ID가 짧거나 예측 가능한 패턴을 따르지 않도록 만들어야 합니다.
- 세션 ID 예측 방지:
- 세션 ID를 생성할 때 충분히 무작위적이고 복잡한 값을 사용해야 하며, 이를 위해서는 보안적인 난수 생성기를 사용해야 합니다.
- 예를 들어,
/dev/urandom
(유닉스 시스템의 보안 난수 생성기)나 암호학적으로 안전한 난수 생성 함수를 사용하여 세션 ID를 생성하는 것이 좋습니다.
- HTTPS 사용:
- HTTP를 통해 세션 ID가 전달되면 공격자가 중간자 공격(MITM)을 통해 세션 ID를 탈취할 수 있습니다. 이를 방지하기 위해 HTTPS를 통해 세션 ID를 안전하게 전송해야 합니다. HTTPS는 데이터 전송 중 암호화를 적용하여 세션 ID가 외부에서 탈취되는 것을 방지합니다.
- 세션 ID 주기적 갱신:
- 사용자가 로그인한 후 세션 ID를 주기적으로 갱신하는 방법도 효과적인 보안 조치입니다. 예를 들어, 사용자가 로그인을 한 후 세션 ID를 새로 생성하여 이전 세션 ID를 무효화하는 방식입니다.
- 이는 세션 고정 공격을 방지하는 데도 도움이 되며, 공격자가 세션 ID를 추측하더라도 실제 사용 중인 세션 ID는 항상 변경되므로, 공격이 어렵게 됩니다.
- 세션 ID를 URL 파라미터로 전달하지 않기:
- 세션 ID를 URL에 포함시키면 브라우저 히스토리, 웹 서버 로그, 리퍼러 등을 통해 세션 ID가 유출될 수 있습니다. 대신 쿠키에 세션 ID를 저장하고, HTTP 요청을 통해 자동으로 전달되도록 설정하는 것이 좋습니다.
- 세션 만료 시간 설정:
- 세션의 유효 시간을 설정하여 사용자가 일정 시간 동안 비활성 상태일 경우 자동으로 로그아웃되도록 합니다. 이렇게 하면 세션을 오랫동안 유지하는 것을 방지할 수 있습니다.
- 브루트포스 공격 방어:
- 세션 ID를 무작위로 추측하려는 공격은 브루트포스 공격으로 이어질 수 있습니다. 이를 방지하기 위해서는 세션 ID 생성 시 가능한 값의 범위가 매우 넓고 예측 불가능해야 합니다. 또한, 너무 많은 시도가 있을 경우 IP 차단이나 딜레이를 적용하여 공격을 방어할 수 있습니다.
- 세션 ID의 무작위성 강화:
- 이와 같은 공격을 막는 방법:
- GPT 답변
쿠키/세션 방식의 장단점
장점:
- 서버 측 관리: 세션 방식은 인증 정보를 서버에서 관리하므로, 보안이 강화된다. 중요한 데이터는 서버에 저장되기 때문에 클라이언트 측 공격에 강하다.
- 강제 로그아웃 가능: 서버는 세션을 관리하고 있으므로 사용자를 강제로 로그아웃시킬 수 있다. 예를 들어, 보안 사고가 발생하거나, 사용자가 로그아웃을 요청할 때, 서버에서 세션을 삭제하면 된다.
- 기타 제어 가능: 예를 들어, 넷플릭스의 계정 공유 제한처럼, 세션을 통해 여러 계정의 접근을 제어할 수 있다.
단점:
- 서버 리소스 부담: 서버는 세션 ID와 관련된 데이터를 저장해야 하므로 사용자가 많아질수록 서버의 DB 리소스가 증가한다. 서버의 저장소와 처리 능력이 증가해야 할 수 있다.
JWT와 쿠키/세션 비교: 언제 JWT 대신 세션을 써야 할까?
JWT의 특징
- JWT는 상태 비저장 방식으로, 클라이언트 측에서 토큰을 저장하고 서버는 이를 검증하여 인증을 처리한다.
- 서버는 세션 정보를 저장하지 않으며, 인증 정보를 토큰 자체에 포함시킨다.
왜 JWT 대신 세션을 사용하는가?
- 강제 로그아웃: 세션은 서버에서 관리되기 때문에 강제로 로그아웃 처리하거나, 사용자의 세션을 만료시킬 수 있습니다. 이는 보안 사고가 발생했을 때 빠르게 대응할 수 있는 장점이 있다.
- 계정 관리: 예를 들어, 넷플릭스와 같은 서비스에서는 세션 방식으로 여러 사용자의 동시 로그인 수를 제한하거나, 특정 세션을 종료할 수 있어 유연한 제어가 가능하다.
결론
HTTP의 stateless 특성을 보완하기 위한 방법으로 쿠키와 세션을 사용하는 것은 매우 중요하다. 쿠키와 세션은 클라이언트의 상태를 효율적으로 관리하고, 보안 및 사용자의 인증 상태를 유지할 수 있는 좋은 방법이다. 특히 강제 로그아웃, 리소스 관리, 유저 인증 상태 추적 (접속자 목록)에 있어서 세션 방식이 더 적합한 경우가 많다. 반면, JWT는 상태 비저장 방식으로서 분산 시스템에서 유리한 점이 있지만, 보안 측면에서 더 많은 신경을 써야 하며, 서버 측 제어가 제한적이다.
따라서, 세션 방식은 보안과 관리 측면에서 여전히 중요한 선택지이며, 클라이언트 측 보안과 서버 관리가 중요한 환경에서는 쿠키와 세션 방식을 사용하는 것이 바람직하다.
참고
https://www.youtube.com/watch?v=tosLBcAX1vk
https://btcd.tistory.com/40
https://f-lab.kr/insight/cookie-vs-session
'박치기 공룡' 카테고리의 다른 글
OAuth 2.0 카카오 로그인 구현하기 (Express) (0) | 2025.02.01 |
---|---|
k8s에서 데이터 영속성을 보장하는 방법 (0) | 2025.01.23 |
SSL/TLS/HTTPS (0) | 2025.01.21 |
네트워크 개념 한줄정리 (1) | 2024.12.03 |