이번 기업과제를하면서 토큰 값을 localStorage에 저장할지, cookie에 저장하면 좋을지 알아보다 각각의 장단점을 적어보려고한다.
이번 프로젝트의 경우엔 제 3자의 API를 받아 구현하는부분이라 cookie에 관한 직접적인 설정을 할 수 없어 localStorage에 저장하였지만 보안관련하여 데이터를 보관하는 방법에 대해 알아두면 좋을것 같다.
XSS는 공격자가 악의적인 js코드를 피해자의 웹 브라우저에서 실행시키는 것이다. 이러한 방법으로 피해자 브라우저에 저장된 중요 정보들을 탈취가 가능해지게 되는데, 공격자는 이러한 취약점이 존재하는 페이지를 미리 탐색한 후 XSS공격을 위한 스크립트가 포함된 URL을 피해자에게 노출시키는 방법으로 공격을 수행할 수 있다.
이러한 과정에서 쿠키 정보나 세션ID를 획득할 수 있게되는 등 주요 정보다 탈취될 수 있는 것이다.
정상적인 request를 가로채 백엔드 서버에 변조된 request를 보내 악의적인 동작(데이터의 수정, 삭제, 등록 등)을 수행하는 공격을 의미한다.
공격자는 유저가 이미지를 보거나 링크를 클릭하도록 유도하고, 사용자는 의도와는 관계없이 http request를 보내게 된다. 유저가 로그인이 되어있는 상태라면 이 request는 정상적으로 서버에 동작을 수행하게 된다.
토큰은 사용자의 개인정보나 다름없다. 보안 관련없이 아무데나 토큰을 저장한다는 것은 고객의 정보를 가져가도 상관이 없다는것과 다름 없는것이다.
그렇다고 react의 state로 저장하자니 새로고침하면 데이터가 사라지게 되어버리므로 사용자입장에서 페이지가 이동되거나 새로고침되면 다시 로그인을 해야하는 상황에 놓이게 된다. 그렇다면 어디에 저장하는 것이 좋을까?
👍 장점
CSRF 공격에는 안전하다. 왜냐하면 request에 담기는 자동적으로 담기게 되는 cookie와는 다르게 Js코드에 의해 헤더에 담기게 되므로 XSS로 공격하지 않는 이상 공격자가 사용자인척 request를 보내기가 어렵기 때문이다.
👎 단점
XSS 공격에 취약하다. localStorage에 접근하는 JS코드만 주입하게 되면 localStrage를 공격자가 쉽게 접근할 수 있게 되는 것이다.
👍 장점
localStorage에 비해 XSS공격에 안전하다는 장점이 있다. 쿠키의 httpOnly 옵션을 사용하면 JS에ㅓ서 쿠키의 접근 자체가 불가능하다. 그래서 XSS공격으로 쿠키 정보를 탈취할 수 없게 된다.
하지만 XSS공격으로부터 완전히 안전한 것은 아니다. httpOnly옵션으로 쿠키의 내용을 볼 수 없다고 해도, js로 request를 보낼 수 있으므로 자동으로 request에 실리는 쿠키의 특성상 사용자의 컴퓨터에서 요청을 위조할 수 있기 때문이다.
👎 단점
CSRF 공격에 취약하다.
자동으로 http request에 담아 보내기 때문에 공격자가 request url만 알게 된다면 사용자가 관련 link를 클릭하도록 유도하여 request를 위조하기 쉽다.
가장 좋은 방법으로는 Refresh Token을 사용하는 방법이다.refresh token을 httpOnly 쿠키로 설정하고 url이 새로고침 될 때마다 refresh token을 request에 담아 새로운 accessToken을 발급 받는다. 발급 받은 accessToken은 state로 저장한다.
이런 방식을 사용하는 경우 refresh token이 CSRF에 의해 사용된다 하더라도
공격자는 accessToken을 알 수 없다. CSRF는 요청을 위조하여 피해자가 의도하지 않은 서버 동작을 일으키는 공격방법이기 때문에 refresh token을 통해 받아온 response(accessToken)는 공격자가 확인할 수 없다.
따라서 쿠키를 사용하여 XSS를 막고 refresh token 방식을 이용하여 CSRF를 막을 수 있게 되는 것이다.
🙋♂️ localStorage를 지지하는 입장
cookie의 httpOnly 옵션도 XSS 공격을 완벽히 막을 수 없다.
어차피 XSS 방어는 필수적이므로 cookie의 장점이 매력적이게 보이지 않는다.
cookie를 사용한다면 백엔드 api에 내가 사용하는 cookie를 위한
설정을 요구해야한다.
백엔드와 조율이 잘 되는 상태면 cookie를 사용해도 문제 없지만 서드파티 api의 경우 거의 불가능하므로 localStorage가 더 좋을 것 같다.
mdn은 저장소로 쿠키를 추천하지 않는다. 대신ModernStorage(localStorage와 sessionStorage)를 추천한다.
🙋♂️ cookie를 지지하는 입장
CSRF 공격은 다루기 쉬운 반면 프론트엔드 크기가 크면 클수록 XSS 공격을 막기위한 작업은 많아지므로 쿠키 사용을 추천한다고 한다.
쿠키는 별도로 헤더에 담지 않아도 요청을 보낼 때 자동으로 담아서 보내지기 때문에 매번 서버로의 요청에 담아야하는 토큰이라는 성격에 잘 맞고 코드도 더 간결하게 작성이 가능하다.