[Node.js] httpOnly, secure 등 cookie 속성

9_miin·2023년 5월 22일
0

Node.js

목록 보기
2/2
post-thumbnail

진행 중인 프로젝트를 배포하였는데 원래 클라이언트에 잘 전달되던 response의 헤더들이 전달되지 않았다. (Authorization, Set-Cookie)

cors문제 때문에 위와 같은 상황이 발생했는데, 이 문제를 해결하다가 쿠키 발급을 구현할 때 자세히 보지 않았던 옵션들이 보였다.


cookie는 보안 취약점이 있다. 자바스크립트로 쿠키에 접근할 수 있다는 점을 이용한 XSS 공격과 HTTP 패킷 자체를 하이재킹하여 쿠키를 탈취 당할 위험도 있다.
이러한 경우를 막기 위해 쿠키를 발급할 때 여러 옵션을 설정할 수 있다.

💡 httpOnly

httpOnly 옵션은 자바스크립트로 브라우저의 쿠키에 접근하는 것을 막기 위한 옵션이다.
자바스크립트로 document.cookie를 사용하면 손쉽게 쿠키에 접근하여 탈취하거나 악용할 수 있다. 그것을 방지하기 위해 쿠키 접근은 http통신으로만 할 수 있게하는 옵션이다

다만 클라이언트에서도 자바스크립트로 접근이 불가능한 점은 유의해야한다.

  • express httpOnly 설정 후 쿠키 발급
res.cookie("refreshToken", <refreshTokenValue>, {
    httpOnly: true,
    }
);

🔍️ secure

secure 옵션은 HTTP 패킷을 하이재킹 당해 쿠키를 탈취 당할 수 있는 경우를 막는 옵션이다.
해당 옵션을 설정해놓으면 HTTPS통신을 할 때만 쿠키를 사용할 수 있게 된다. 그렇기 때문에 HTTP 패킷을 하이재킹 당해도 암호화 되어있어 쿠키를 확인할 수 없다.

  • express secure 설정 후 쿠키 발급
res.cookie("refreshToken", <refreshTokenValue>, {
    secure: true,
    }
);

👥 sameSite

sameSite 옵션은 쿠키를 사용할 수 있는 범위를 제한하는 옵션이다.
쿠키를 발급한 도메인과 같은 도메인인지 여부를 확인해 쿠키 전송을 제한한다. 쿠키를 발급한 도메인이 아닌 외부의 도메인에서는 해당 쿠키에 접근할 수 없다. 옵션은 strict, lax, none가 있다.

크롬은 버전 80부터 sameSite의 default 옵션을 none에서 lax로 변경했다.

세부 옵션

  • sameSite=Strict -> strict옵션은 쿠키를 발급한 도메인으로만 쿠키 전송 가능. (도메인이 같아도 schema가 다르면 cross site로 간주)

  • sameSite=Lax -> lax옵션은 자사 도메인이 아니더라도 안전한 요청에는 쿠키 전송을 허용한다. (Get 요청 등)

  • sameSite=None -> none옵션은 쿠키를 발급한 도메인이 아닌 다른 곳으로도 전송할 수 있게 한다. 그러나 sameSite=none으로 설정할 경우 secure 속성을 필수적으로 적용해야 한다.

  • express sameSite 설정 후 쿠키 발급

res.cookie("refreshToken", <refreshTokenValue>, {
	sameSite: "none",
    secure: true,
    }
);

🗃️ 그 외

domain

domain 옵션은 토큰을 사용할 수 있는 도메인을 설정한다. 그렇기 때문에 해당 옵션에 설정된 도메인 이외의 다른 도메인에서는 토큰을 사용할 수 없다.

path

이 옵션을 설정해놓으면 해당 경로의 하위 경로에서만 쿠키에 접근할 수 있다.

maxAge/expires

쿠키의 만료 기간 옵션이다. 해당 옵션을 설정하지 않고 브라우저를 닫으면 쿠키는 삭제되지만 설정해놓으면 삭제되지 않는다.
maxAge는 현재부터 만료기간까지 초 단위로 설정한다. expires는 유효 일자를 GMT(Greenwich Mean Time) 포맷으로 설정해야 한다.

  • express 쿠키 발급
res.cookie("refreshToken", <refreshTokenValue>, {
	domain: "domain.com"
	path: "/"
    maxAge: 24 * 6 * 60 * 10000, // expires: new Date(Date.now() + 24 * 6 * 60 * 10000),
    }
);

💬 내 생각

진행 중인 프로젝트에서 cors문제를 해결하면서 클라이언트와 서버 간 여러가지를 설정했는데, 고생했던 부분이 도메인 간 쿠키에 접근할 수는 있지만 서브 도메인만 가능하다는 점을 몰랐기 때문에 많이 헤메면서 클라이언트, 서버, 쿠키, cors에 관한 여러 내용을 봤다.

cors 정책이 적용되지 않았을 때 쿠키가 많이 취약하기 때문에 여러 옵션이 있고 그렇기 때문에 헤더뿐만 아니라 쿠키에서도 cors 정책 관련해서 신경을 많이 써야겠다.


참고자료
https://ko.javascript.info/cookie
https://web.dev/samesite-cookies-explained/
https://velog.io/@ohzzi/Access-Token%EA%B3%BC-Refresh-Token%EC%9D%84-%EC%96%B4%EB%94%94%EC%97%90-%EC%A0%80%EC%9E%A5%ED%95%B4%EC%95%BC-%ED%95%A0%EA%B9%8C
https://itallinform.tistory.com/16

0개의 댓글