- Published on
Secure Coding 4 - Session Management
개요
여기서 말하는 세션은 일반적인 HTTP 세션에서 설명한 것과 같은 HTTP Session을 말하는 것이 아니라 HTTP 등의 상태 비저장 프로토콜의 애플리케이션층에서 실시하는 세션 관리 메커니즘을 말합니다.
이 항에서는 세션 관리의 방법이나 필요한 보안 대책을 어느 정도 상세히 설명하지만, 개발자가 실제로 안전하게 구현하는 데 있어 필요한 것은 충분히 테스트되고 잘 유지되고 있는 메이저 프레임워크에서 제공된 세션 관리 기능을 이용하는 것입니다.
Session ID
전체적으로 보면 사용자 세션 확립은 매우 알기 쉬우며 아래 같이 진행됩니다.
- 클라이언트는 요청 발송
- 서버는 세션 ID를 생성하여 응답에 부여하여 반환
- 클라이언트는 응답의 세션 ID를 읽고 저장
- 클라이언트는 저장된 세션 ID와 함께 다음 요청을 발송
- 서버는 세션 ID를 검사하고 단계 2에 이어서 요청 처리
이 일련의 흐름에서 알 수 있듯 세션 ID는 세션 관리에서 가장 중요한 요소 중 하나이기 때문에
- 항상 신뢰할 수 있는 시스템에서 생성되어야 함
- 애플리케이션은 신뢰할 수 있는 시스템에서 생성된 올바른 세션 ID만을 인식해야 함
또한 세션 ID는 오류 메시지나 URL, 로그에 노출되어서는 안 됩니다. 과거에는 일부 웹 프레임워크나 애플리케이션에서 세션 ID를 GET 매개변수(예: jsessionid, PHPSESSID)로 전달한 적이 있었습니다.
이는 세션 고정 공격과 같은 문제가 발생하거나 URL 공유로 세션 ID가 유출될 가능성이 있습니다.
세션 ID만을 살펴보면 다른 시스템에서 세션 ID를 예측할 수 없도록 임의성을 충분히 보장하는 완벽히 검사된 알고리즘이 이용되어야 합니다.
구체적으로는 아래와 같은 점에 주의해야 합니다.
- 길이: 128비트(16바이트) 이상
- 엔트로피: 암호학적으로 안전한 난수 생성기 사용
- 내용: 의미있는 정보는 포함하지 말아야 하며 반드시 임의이어야 함
Cookie
응답에 세션 ID를 포함하려면 서버에서 Set-Cookie HTTP 응답 헤더를 이용해야 합니다. 이때 아래와 같이 몇 가지 속성을 부여합니다.
Set-Cookie: <cookie-name>=<cookie-value>; Domain=<domain-value>; Secure; HttpOnly
Secure Attribute
Secure 속성은 SSL/TLS로 암호화된 HTTP 통신인 경우에만 웹 브라우저에 쿠키를 전송하도록 하는 속성입니다.
웹 애플리케이션이 암호화되지 않은 HTTP를 지원하지 않더라도(웹 서버에서 TCP/80 포트가 닫혀 있는 경우도) Secure 속성이 없는 쿠키는 암호화되어 있지 않은 통신에 송신할 수 있는 경우가 있으니 기본적으로 Secure 속성이 부여되어야 합니다.
HttpOnly Attribute
HttpOnly 속성은 JavaScript 등 스크립트의 document.cookie 객체를 통해 쿠키 액세스를 금지합니다.
이를 통해 XSS 공격으로 세션 ID가 절도되는 것을 방지할 수 있습니다. 단, XSS로 CSRF 공격을 실행할 경우 송신하는 요청에 쿠키가 포함됩니다.
SameSite Attribute
SameSite 속성은 SameSite 속성이 붙은 쿠키가 교차 사이트 요청에 부여되지 않게 됩니다.
이 속성의 주요 효과는 교차 원본 정보 유출의 위험을 줄이고 CSRF 공격을 막는 것입니다.
Domain and Path Attribute
Domain 속성은 웹 브라우저에 특정 도메인과 그에 상응하는 서브 도메인에만 쿠키를 전송하도록 하기 위한 속성입니다. Domain 속성이 부여되지 않은 경우 기본적으로 쿠키가 부여된 원본(프로토콜, 도메인, 포트 번호가 모두 일치하는 경우 동일한 원본으로 간주됨)에만 전송됩니다.
Path 속성은 웹 브라우저에 특정 디렉토리와 그에 상응하는 서브 디렉토리에만 쿠키를 전송하도록 하기 위한 속성입니다. Path 속성이 부여되지 않은 경우 기본적으로 Set-Cookie 헤더에서 쿠키를 가져오거나 저장된 경로에만 전송됩니다.
이 두 속성은 좁거나 엄격한 범위를 설정하는 것이 좋습니다. 즉, Domain 속성을 설정하지 않고(원본 서버에만 쿠키가 전송됨) Path 속성은 세션 ID를 이용하는 경로로 제한하는 것이 좋습니다.
Domain 속성에 example.com 과 같은 넓은 범위 값을 설정한 경우 같은 도메인에 속하는 다른 웹 애플리케이션에 대한 공격의 영향을 받을 수 있습니다.
예를 들어 www.example.com 에 XSS와 같은 세션 ID가 절도에 취약한 경우 secure.example.com 의 세션 ID 에도 액세스할 수 있을 가능성이 있습니다.
Expire and MaxAge Attribute
쿠키 기반 세션 관리에는 두 가지의 쿠키를 이용할 수 있습니다.
- Persistent Cookie
- Non-Persistent(Session) Cookie
쿠키에 Max-Age 속성이나 Expires 속성이 있는 경우 이는 지속 쿠키로 간주되며 유효 기간까지 디스크에 저장됩니다.
지속 쿠키가 아닌 것은 메모리에 저장되며 현재 웹 브라우저 인스턴스가 종료되면 클라이언트 측에서 삭제됩니다.
세션 관리에서는 세션 ID가 오래 클라이언트 캐시 등에 남지 않도록 지속 쿠키가 아닌 것을 이용하는 것이 가장 좋습니다.