쿠키 파서 (Cookie·Set-Cookie)
Cookie 헤더, Set-Cookie, cookies.txt를 붙여 넣으면 값을 디코딩하고, 브라우저가 각 쿠키를 저장할지 거부할지와 그 이유, 다음 요청에 실릴 Cookie 헤더를 보여 줍니다. 마스킹본도 복사할 수 있습니다.
- 브라우저에서 처리
- 데이터가 브라우저 밖으로 나가지 않습니다
- 무료 · 회원가입 불필요
WeChat으로 스캔하여 공유
예시·자세한 설명·자주 묻는 질문 실제 출력이 있는 예시, 다른 도구와의 차이, 자주 묻는 질문.
예: ‘오늘 하루 보지 않기’ 쿠키가 아침 9시에 풀리는 이유
팝업의 ‘오늘 하루 보지 않기’는 보통 한국 시간 자정까지 남는 쿠키로 만듭니다. 2026년 10월 2일 낮에 이 버튼을 누른다면 만료 시각은 10월 3일 0시(KST), 즉 10월 2일 15:00 GMT여야 합니다.
Set-Cookie: popup_notice=Y; Path=/; Expires=Fri, 02 Oct 2026 15:00:00 GMT
document.cookie = "popup_notice=Y; path=/; expires=Sat Oct 03 2026 00:00:00 GMT+0900 (한국 표준시)"
첫 줄은 toUTCString()으로 만든 날짜라 의도대로 2026-10-02 15:00 UTC에 만료됩니다. 둘째 줄은 Date를 그대로 문자열로 이어 붙여 toString() 결과가 들어간 경우입니다. 쿠키 날짜는 항상 GMT로 읽히므로 GMT+0900의 오프셋은 무시되고, 만료는 2026-10-03 00:00 UTC, 한국 시간으로 아침 9시가 됩니다. 그래서 팝업이 자정이 지나도 9시간 동안 다시 뜨지 않습니다. 2026-10-02에 Chromium 152의 document.cookie로 둘째 줄을 설정해 저장된 만료 시각이 이와 같음을 확인했습니다. 이 도구는 둘째 줄에 오프셋이 무시된다는 경고를 붙입니다.
예: EUC-KR로 인코딩된 닉네임과 두 개의 JSESSIONID
JSESSIONID=7F3A9C2E5B1D4F8A6C0E2B4D6F8A0C2E; nickname=%C8%AB%B1%E6%B5%BF; popup_notice=Y; JSESSIONID=guest
nickname=%C8%AB%B1%E6%B5%BF는 ‘홍길동’을 EUC-KR로 퍼센트 인코딩한 값입니다. UTF-8로 읽을 수 없어 원래 값 그대로 보여 주고 표시를 붙입니다. UTF-8이라면%ED%99%8D%EA%B8%B8%EB%8F%99입니다. 오래된 페이지와 새 페이지가 서로 다른 인코딩으로 같은 쿠키를 쓰면 이렇게 깨집니다.JSESSIONID가 두 번 있습니다. JSON 객체는 첫 번째 값을 가져, Express·PHP가 읽는 값과 같습니다.- ‘마스킹본 복사’를 ‘세션 ID와 토큰만’으로 두면 두
JSESSIONID값만[redacted]가 되고popup_notice는 그대로 남습니다.
속성별 브라우저 처리
| 속성 | 이 도구가 적용하는 규칙 |
|---|---|
Expires | RFC 6265bis §5.1.1의 날짜 알고리즘으로 읽습니다. 시간대 표기는 무시하고 GMT로 봅니다. 2026-10-21T07:28:00Z 같은 ISO 형식은 읽지 못해 세션 쿠키가 됩니다. |
Max-Age | Expires보다 우선. 0 이하는 삭제. 400일을 넘는 유효 기간은 400일로(Chrome 104부터). |
Domain | 앞의 점은 무시. 생략하면 설정한 호스트에만, 쓰면 모든 하위 도메인에 전송. Public Suffix List에 있는 공개 접미사는 거부: https://www.example.co.kr/에서 받은 sid=x; Domain=co.kr는 거부되고, 목록 PRIVATE 부분의 Domain=github.io도 같습니다. Domain이 응답 호스트와 같으면 host-only가 됩니다(RFC 6265bis §5.7 9단계). |
Path | 생략하거나 /로 시작하지 않으면 응답 URL의 디렉터리. |
SameSite | 생략 시 Chrome 80+, Edge 86+는 Lax, Firefox·Safari는 다릅니다(MDN 호환성 데이터). None은 Secure가 필요. |
Partitioned | Secure 필요(CHIPS). Chrome 114+, Firefox 141+, Safari 26.2+. |
| 이름 접두사 | __Secure-는 Secure, __Host-는 Secure·Path=/·Domain 없음, __Http-·__Host-Http-는 여기에 HttpOnly까지(Chrome 140+, Firefox 143+). 대소문자 구분 없음. |
| 크기 | 이름과 값이 UTF-8로 4096바이트를 넘으면 무시. 한글은 한 글자에 3바이트입니다. 속성 값이 1024바이트를 넘으면 그 속성만 무시. |
실측: Chrome이 사양과 다른 점
2026-10-02에 로컬 테스트 서버에서 각 줄을 Chromium 152로 보내고 실제로 저장된 쿠키를 읽었습니다. 날짜, 크기, 접두사, SameSite=None, Partitioned는 RFC 6265bis와 같았고 다음이 달랐습니다. 이 도구는 RFC대로 판정하고, 이런 줄에는 설명을 덧붙입니다.
Max-Age=+60: RFC는 무시, Chromium은 60초로 처리.- 값 중간의 탭: RFC는 허용, Chromium은 거부.
Domain=.: RFC는 빈 도메인(host-only), Chromium은 거부.- 기존 쿠키를 덮어쓰면 Chromium은 생성 시각을 새로 기록해 먼저 설정된 쿠키 뒤로 보냅니다. RFC는 원래 생성 시각을 유지합니다.
서버가 Cookie 헤더를 읽는 방식
| 읽는 쪽 | 같은 이름 | 큰따옴표로 감싼 값 | 값 안의 공백 |
|---|---|---|---|
Express 5의 req.cookies(cookie-parser 1.4.7, cookie 0.7.2) | 첫 번째 | 따옴표 제거 | 유지 |
| Python 3.12 http.cookies | 마지막 | 따옴표 제거 | 헤더 전체를 버림 |
PHP 8.4의 $_COOKIE | 첫 번째 | 따옴표 유지 | 유지 |
PHP는 이름의 점과 공백을 밑줄로 바꿔 connect.sid를 $_COOKIE['connect_sid']로 받습니다. 이 도구는 해당 행에 이런 내용을 적어 줍니다.
다른 쿠키 파서와의 차이
2026-10-02에 Bing에서 ‘쿠키 파서’ 1위였던 LiteDevTools를 비롯해 다섯 도구에 같은 입력을 넣었습니다. 모두 내용을 서버로 보내지 않았습니다. LiteDevTools는 Set-Cookie 모드에서 줄을 제대로 나누지만 속성을 표로 옮겨 적을 뿐이라, SameSite=None에 Secure가 없는 것, __Host- 쿠키에 Domain이 있는 것을 지적하지 않고 Max-Age=0도 플래그 칸에 그대로 둡니다. 기본인 Cookie 모드에서는 abc처럼 =가 없는 항목을 값이 빈 이름으로 보여 줍니다. 브라우저는 반대로 이름이 없고 값이 abc인 쿠키로 저장합니다. 나머지 네 도구도 거부될 쿠키를 지적하지 않았습니다.
제한
- 공개 접미사는 Public Suffix List의 고정 버전(2026-10-01, ICANN·PRIVATE 두 부분과 와일드카드·예외 규칙 포함)으로 판정합니다. 목록은 자주 바뀌므로 그 뒤에 추가된 접미사는 모릅니다. 브라우저도 내장 목록을 각자의 주기로 갱신합니다. 목록은 압축 후 약 45 KB이며, Set-Cookie나 cookies.txt를 처음 분석할 때 불러옵니다. 불러오기 전이나 실패했을 때는 Domain 속성이 있는 쿠키를 ‘확인 못 함’으로 표시하고, 요청 시뮬레이션에서 빼며, Domain을 판정하지 않습니다.
- 시뮬레이션은 각 Set-Cookie가 최상위 페이지의 응답에서 왔고, 그 전에는 쿠키가 없다고 가정합니다. SameSite를 쓰지 않은 새 쿠키를 Chrome이 2분 동안 크로스 사이트 POST에 싣는 예외는 다루지 않습니다.
- 유효 기간은 붙여 넣은 시점부터 셉니다.
- 브라우저 확장 프로그램이 내보내는 JSON은 읽지 않습니다. Cookie 헤더나 cookies.txt를 붙여 넣으세요.
FAQ
Cookie 헤더에 같은 이름이 두 번 나오는 이유는?
브라우저는 이름·도메인·경로 조합으로 쿠키를 구분합니다. Path=/로 설정한 JSESSIONID와 Path=/member로 설정한 JSESSIONID는 서로 다른 쿠키이고, /member 아래로 가는 요청에는 둘 다 실리며 경로가 긴 쪽이 먼저 옵니다. Express와 PHP는 첫 번째 값을, Python의 http.cookies는 마지막 값을 씁니다. 오래된 쪽을 지우려면 Domain과 Path를 똑같이 맞추고 Max-Age=0을 붙인 Set-Cookie를 보내세요.
Set-Cookie를 보냈는데 브라우저에 쿠키가 없습니다. 왜 그런가요?
흔한 원인은 SameSite=None인데 Secure가 없는 경우, __Host- 쿠키에 Domain이 있거나 Path가 /가 아닌 경우, Domain이 응답 호스트를 포함하지 않는 경우, http:// 페이지에서 Secure 쿠키를 설정한 경우, 이름과 값이 4096바이트를 넘는 경우입니다. 그 줄을 응답 URL과 함께 붙여 넣으면 카드에 ‘거부’와 이유가 나옵니다.
Expires와 Max-Age가 함께 있으면 무엇이 적용되나요?
Max-Age입니다. Expires는 무시됩니다. Max-Age=0이나 음수는 삭제를 뜻합니다. 브라우저는 400일을 넘는 유효 기간을 400일로 줄입니다.
SameSite를 쓰지 않으면 어떻게 되나요?
Chrome 80 이상과 Edge 86 이상은 SameSite=Lax로 처리해, 다른 사이트의 링크로 들어올 때는 보내지만 크로스 사이트 iframe, fetch, 폼 POST에는 싣지 않습니다. Firefox와 Safari는 크로스 사이트 요청에도 보냅니다. 브라우저마다 동작이 같도록 SameSite를 명시하세요.
붙여 넣은 쿠키가 어딘가로 전송되나요?
아니요. 파싱은 브라우저 안에서 하고, 페이지는 그 내용을 담은 요청을 보내지 않으며 저장하지도 않습니다. 쿠키에는 세션 ID가 들어 있는 경우가 많아 이 페이지는 Google 애널리틱스와 AdSense를 불러오지 않습니다. 문의 글에 붙일 때는 ‘마스킹본 복사’로 값을 [redacted]로 바꾸세요.