사전 세션
용어함정

세션

gabury1

세션은 한동안 이어지는 한 벌을 가리키는 말입니다. 무엇이 이어지는지는 쓰는 자리마다 다릅니다. 그래서 같은 말을 주고받으면서 서로 다른 것을 떠올린 채 이야기가 흘러가기도 합니다.

상세

여러 정의가 공유하는 뼈대는 하나입니다. 흩어진 낱개를 한동안 묶어 두는 상태입니다. 갈리는 자리는 묶이는 것이 무엇인가입니다.

HTTP 에서 묶이는 것은 요청입니다. RFC 6265 는 서버가 Cookie 와 Set-Cookie 헤더 필드로 사용자 에이전트에 상태를 저장해 둘 수 있다고 적습니다. 그렇게 해서 대체로 상태가 없는 HTTP 프로토콜 위에서 상태가 있는 세션을 유지한다고 적습니다.

데이터베이스에서 묶이는 것은 접속 하나입니다. PostgreSQL 용어집은 세션을 클라이언트와 백엔드가 연결로 통신하며 상호작용하게 해 주는 상태라고 적습니다.

운영체제에서 묶이는 것은 프로세스입니다. POSIX.1-2024 는 세션을 작업 제어를 목적으로 만들어진 프로세스 그룹들의 모임이라고 적습니다.

TLS 에서 묶이는 것은 협상 결과입니다. RFC 5246 은 세션을 클라이언트와 서버 사이의 연관이라고 적습니다. 세션은 여러 연결이 나눠 쓸 수 있는 암호 보안 파라미터 한 벌을 정의합니다.

끝나는 시점도 맥락이 정합니다. RFC 6265 는 쿠키가 현재 세션이 끝날 때 만료된다고 적습니다. 그러면서 그 끝이 언제인가는 사용자 에이전트가 정한다고 곧바로 덧붙입니다. POSIX 는 세션 수명을 따로 정의합니다. 세션이 만들어진 때부터 그 세션에 남아 있는 모든 프로세스 그룹의 수명이 끝날 때까지의 기간입니다.

어느 뜻이 원래 뜻인지는 이 문서들이 적지 않습니다. 그래서 세션이라는 말만으로는 무엇이 이어지는지가 정해지지 않습니다. 맥락 이름을 먼저 대야 뜻이 섭니다.

맥락별 뜻

맥락 뜻 출처
HTTP 대체로 상태가 없는 프로토콜 위에서 요청들을 하나로 묶어 두는 상태 RFC 6265 Abstract · 3.1 · 8.4
데이터베이스 클라이언트와 백엔드가 연결로 통신하며 상호작용하게 해 주는 상태 PostgreSQL Documentation, Glossary
운영체제 — 작업 제어 작업 제어를 목적으로 만들어진 프로세스 그룹들의 모임 POSIX.1-2024 3.329 · credentials(7) · setsid(2)
운영체제 — 로그인 관리 로그인 한 벌. 사용자의 동시 접속마다 하나 systemd-logind.service(8)
TLS 여러 연결이 나눠 쓰는 암호 보안 파라미터 한 벌. 다시 붙을 때 협상을 건너뛰는 근거 RFC 5246 Appendix · RFC 8446 2.2 · 4.6.1

HTTP

RFC 6265 는 서버가 Set-Cookie 헤더로 짧은 문자열을 사용자 에이전트에 보낼 수 있다고 적습니다. 사용자 에이전트는 쿠키의 범위 안에 드는 이후 요청에서 그 문자열을 돌려줍니다. 문서가 든 예가 SID 라는 이름의 세션 식별자입니다.

sequenceDiagram
    participant 사용자에이전트
    participant 서버
    서버-->>사용자에이전트: Set-Cookie 로 SID 를 보냄
    Note over 서버: 세션 상태는 서버가 들고 있다
    사용자에이전트->>서버: 이후 요청마다 SID 를 돌려줌
    서버->>서버: SID 를 키로 상태를 찾음

세션이 언제 끝나는지는 이 문서가 정하지 않습니다. 쿠키에 Max-Age 도 Expires 도 없으면 사용자 에이전트는 현재 세션이 끝날 때까지 쿠키를 들고 있습니다. 현재 세션이 끝났다는 판정 자체가 사용자 에이전트의 몫입니다. 그때 사용자 에이전트는 persistent-flag 가 false 인 쿠키를 저장소에서 모두 지워야 합니다.

데이터베이스

PostgreSQL 용어집은 세션과 그 이웃을 함께 정의합니다. 클라이언트는 인스턴스에 접속해 세션을 여는 프로세스입니다. 백엔드는 클라이언트 세션을 대신해 그 요청을 처리하는 인스턴스의 프로세스입니다. 연결은 그 세션을 떠받치는 통신 선로입니다.

세션은 설정값이 사는 자리이기도 합니다. SET 명령은 현재 세션에서 쓰이는 값만 바꿉니다. 감싼 트랜잭션이 커밋되면 그 효과는 세션이 끝날 때까지 남습니다. 임시 테이블도 세션 또는 트랜잭션 중 무엇의 수명을 따를지를 만들 때 정합니다.

운영체제 — 작업 제어

POSIX.1-2024 는 프로세스 그룹이 저마다 어느 세션의 구성원이라고 적습니다. 새로 만들어진 프로세스는 자기를 만든 쪽의 세션에 들어갑니다. 한 세션에 프로세스 그룹이 여럿 있을 수 있습니다. credentials(7) 은 세션과 프로세스 그룹을 셸 작업 제어를 떠받치려고 고안된 추상이라고 적습니다. 한 프로세스 그룹의 구성원은 모두 같은 세션 ID 를 가지므로, 세션과 프로세스 그룹은 프로세스의 엄격한 두 단계 계층을 이룹니다.

flowchart TD
    S["세션 · 세션 ID 하나"] --> G1["프로세스 그룹"]
    S --> G2["프로세스 그룹"]
    G1 --> P1["프로세스"]
    G1 --> P2["프로세스"]
    G2 --> P3["프로세스"]

세션은 setsid(2) 로 만들어집니다. 호출한 프로세스가 프로세스 그룹 리더가 아니면 새 세션이 만들어집니다. 그 프로세스의 세션 ID 는 자기 PID 와 같아지고, 그 프로세스가 새 세션의 리더가 됩니다. 갓 만들어진 세션에는 제어 터미널이 없습니다. 제어 터미널은 세션 리더가 터미널을 처음 열 때 정해집니다. 한 터미널은 많아야 한 세션의 제어 터미널이 됩니다.

운영체제 — 로그인 관리

systemd-logind 는 사용자 로그인을 관리하는 시스템 서비스입니다. 사용자와 세션, 그 프로세스들과 유휴 상태를 추적합니다. 사용자마다 user.slice 아래에 슬라이스 유닛을 하나 두고, 그 아래에 사용자의 동시 세션마다 스코프 유닛을 하나 둡니다. 세션 ID 도 이 서비스가 만들고 관리합니다. 감사 기능이 있고 그 세션에 감사 세션 ID 가 이미 잡혀 있으면 그 값을 세션 ID 로 다시 씁니다. 아니면 별도의 세션 카운터를 씁니다.

TLS

RFC 5246 은 TLS 세션을 클라이언트와 서버 사이의 연관이라고 적습니다. 세션은 핸드셰이크 프로토콜이 만듭니다. 세션이 정하는 암호 보안 파라미터 한 벌은 여러 연결이 나눠 쓸 수 있습니다. 세션을 쓰는 목적을 이 문서는 연결마다 새 보안 파라미터를 협상하는 비용을 피하는 것이라고 적습니다. 세션 식별자는 특정 세션을 가리키려고 서버가 만들어 내는 값입니다.

RFC 8446 이 RFC 5246 을 대체했습니다. TLS 1.3 에서 세션 재개는 사전 공유 키와 하나로 합쳐졌습니다. 핸드셰이크가 끝난 뒤 서버는 클라이언트에 PSK 신원을 보낼 수 있습니다. 그 신원은 처음 핸드셰이크에서 파생된 고유한 키에 대응합니다. 클라이언트는 이후 핸드셰이크에서 그 PSK 신원을 써서 연결된 PSK 를 쓰자고 협상할 수 있습니다.

sequenceDiagram
    participant 클라이언트
    participant 서버
    클라이언트->>서버: 핸드셰이크
    서버-->>클라이언트: NewSessionTicket 으로 티켓을 보냄
    Note over 클라이언트,서버: 티켓 값은 재개용 PSK 와 짝지어진다
    클라이언트->>서버: 다음 핸드셰이크에 티켓 값을 실어 보냄

서버는 클라이언트 Finished 를 받은 뒤라면 언제든 NewSessionTicket 메시지를 보낼 수 있습니다. 한 연결에서 티켓을 여럿 보낼 수도 있습니다. 옛 이름은 필드로 남았습니다. TLS 1.3 이전 서버가 잡아 준 세션 ID 를 캐시해 둔 클라이언트는 ClientHello 의 legacy_session_id 에 그 값을 넣는 것이 좋습니다.

경계

쿠키에 담긴 세션 식별자

쿠키에 실려 오가는 세션 식별자도 세션인가. 아닙니다. 세션을 가리키는 표입니다.

근거는 RFC 6265 8.4 에 있습니다. 서버는 세션 정보를 쿠키에 직접 담는 대신 nonce 를 쿠키에 담는 일이 흔합니다. nonce 가 담긴 요청을 받으면 서버는 그 nonce 를 키로 삼아 쿠키에 딸린 상태 정보를 찾습니다. 상태는 서버 쪽에 있고 쿠키에는 그 상태를 찾는 키만 있습니다. 문서는 세션 정보를 쿠키에 직접 담으면 공격자에게 노출되거나 재생될 수 있다는 점을 그 이유로 적습니다.

같은 대목이 대가도 적습니다. 세션 식별자 쿠키를 쓰는 데에도 위험이 따릅니다. 서버는 세션 고정 취약점을 피하도록 주의해야 합니다. 세션 고정 공격은 세 단계로 진행됩니다. 공격자가 자기 사용자 에이전트의 세션 식별자를 피해자의 사용자 에이전트로 옮겨 심습니다. 피해자가 그 식별자로 서버와 상호작용하면서 자격증명이나 기밀 정보를 그 식별자에 실어 넣습니다. 그다음 공격자가 그 식별자로 서버와 직접 상호작용합니다.

세션에 안 들어가는 것

연결은 세션이 아닙니다. RFC 9110 은 HTTP 가 신뢰할 수 있는 전송 계층 또는 세션 계층 연결 위에서 도는 클라이언트 서버 프로토콜이라고 적습니다. 그러면서 HTTP 는 상태가 없는 프로토콜이라고 못 박습니다. 서버는 같은 연결 위의 두 요청이 같은 사용자 에이전트에서 왔다고 가정해서는 안 됩니다. 그 연결이 보안되어 있고 그 에이전트 전용일 때만 예외입니다. TLS 쪽도 둘을 가릅니다. 연결은 일시적이고, 모든 연결은 하나의 세션에 딸립니다. 다만 PostgreSQL 용어집은 연결이라는 말이 세션의 동의어로 쓰이기도 한다고 적습니다.

트랜잭션은 세션이 아닙니다. PostgreSQL 에서 SET 과 SET SESSION 의 효과는 감싼 트랜잭션이 커밋되면 세션이 끝날 때까지 이어집니다. SET LOCAL 의 효과는 현재 트랜잭션이 끝날 때까지만 갑니다. 커밋이든 롤백이든 마찬가지입니다. 트랜잭션이 세션 안에서 열리고 닫히는 더 짧은 단위라는 뜻입니다.

액세스 토큰은 세션이 아닙니다. RFC 6749 는 액세스 토큰을 보호된 자원에 접근하는 데 쓰는 자격증명이라고 적습니다. 토큰은 클라이언트에 발급된 인가를 나타내는 문자열입니다. 토큰 자신이 특정한 범위와 접근 기간을 나타냅니다. 세션 식별자는 서버가 상태를 찾는 키인 반면, 토큰은 인가를 나타내는 문자열입니다.

관련 항목

세션이 속하는 프로토콜·표준

HTTP · TLS · POSIX · PostgreSQL

HTTP 세션을 이루는 구성 요소

쿠키 · Set-Cookie · 세션 식별자 · nonce · 사용자 에이전트 · Max-Age · Expires

HTTP 세션 식별자에서 자주 나는 취약점

세션 고정 · 크로스 사이트 요청 위조 · 앰비언트 권한

데이터베이스 세션을 이루는 구성 요소

백엔드 · 인스턴스 · 격리 수준 · 임시 테이블 · SET LOCAL · 런타임 설정 파라미터 · 커넥션 풀

작업 제어 세션을 이루는 구성 요소

프로세스 그룹 · 세션 리더 · 세션 ID · 세션 수명 · 제어 터미널

작업 제어 세션을 만드는 명령과 목적

setsid · credentials · 작업 제어

로그인 세션을 관리하는 서비스와 단위

systemd-logind · 로그인 · 슬라이스 유닛 · 스코프 유닛

TLS 세션을 이루는 구성 요소

핸드셰이크 · 세션 재개 · 사전 공유 키 · NewSessionTicket · 세션 티켓 · legacy_session_id · 재개 마스터 시크릿

세션과 맞세워지는 대립 개념

연결 · 트랜잭션 · 액세스 토큰 · 상태 없음

다른 이름: session