accessToken을 localStorage에 저장하면 안 좋은 이유

seongjin·2023년 3월 10일
0

이 글을 쓰게 된 계기는 개발관련 검색을 하다가 로컬스토리지에 토큰을 담아주고 쓰는것이 보안상 안 좋다는 글을 보게된 이후 호기심이 생겨 현재 프로젝트에 적용해보고자 공부를 시작하였다. 결론적으로 말하자면 내 프로젝트에는 베스트 한 방법을 적용하기 힘들었다. 그래도 공부하는 과정에서 얻어간 것이 있어 정리차 글을 적어보겠다.

문제점

럭킷 프로젝트에서는 로그인시 응답 토큰을 받아 바로 로컬스토리지에 담아 필요 요청시 꺼내쓰는 방식으로 쓰고 있었다. 이 파트는 팀원이 작성한 부분이였는데 작성 당시 보안을 신경쓰지 않고 처리해주었는데 그때 당시엔 나도 잘 몰라서 그냥 넘어갔던 것 같다😅 이것은 XSS 공격에 취약하다.

기본 지식

XSS란(Cross Site Scripting)

다양한 공격방식이 있지만 간단하게 설명하자면 악성 사용자가 웹 애플리케이션의 취약점을 이용하여, 악성 스크립트를 삽입하여 다른 사용자의 브라우저에서 실행되는 공격 기법이다. 예를들어 URL 매개변수나 폼등에서 script를 포함시켜 보내게 되면 해당 브라우저가 악성 코드를 실행하게 된다.

자세한 내용 XSS

CSRF란(Cross Site Request Forgery)

사용자가 의도하지 않은 요청을 악의적인 공격자가 대신 보내는 것을 말한다. 이러한 취약점은 사용자가 인증된 상태에서 악의적인 공격자의 요청을 실수로 실행하거나, 실행시킬 수 있다.

간단한 예시를 들어보자면, 사용자 A가 인증된 상태에서 은행 애플리케이션에 로그인한 상태에서 악의적인 공격자 B가 A의 계좌 이체를 위한 요청을 포함한 페이지를 생성하고, 이 페이지를 A에게 이메일 등으로 전송하는 경우다. A가 이메일에서 악의적인 페이지 링크를 클릭하면, 자신의 의지와는 무관하게 계좌 이체 요청이 전송되어 수행될 수 있다.

자세한 내용 CSRF

고려해 본 해결방안

httpOnly: 이 옵션은 자바스크립트 같은 클라이언트 측 스크립트가 쿠키를 사용할 수 없게 합니다. document.cookie를 통해 쿠키를 볼 수도 없고 조작할 수도 없습니다.
secure: 이 옵션을 설정하면 HTTPS로 통신하는 경우에만 쿠키가 전송됩니다.
httpOnly, secure 자료1
httpOnly, secure 자료2

로컬스토리지에 토큰을 담아 쓰게되면 XSS 공격시 로컬스토리지에 접근하는 js코드가 존재한다면 토큰이 탈취될 수 있기 때문에 httpOnly쿠키방식과 secure 설정을 통한 쿠키에 저장하는 것을 고려하였다. 하지만 이 방식은 쿠키가 자동으로 http reques에 담겨 보내지기 때문에 공격자가 request url만 안다면 CSRF 공격에 취약하다. 때문에 가장 좋은 방법을 찾아보았는데 refresh token을 사용하는 방법이다. refresh token을 httpOnly 쿠키로 설정하고 url이 새로고침 될 때마다 refresh token을 request에 담아 새로운 accessToken을 발급 받는다. 발급 받은 accessToken은 js private variable에 저장한다. private 변수로 저장된 Access Token은 XSS 공격으로 탈취할 수 없고, 당연히 CSRF 공격을 당할 가능성도 없다.

하지만 내 프로젝트에서는 백엔드랑 따로 소통을 하지 않는 서드파티 api를 사용하기 때문에... httpOnly 쿠키설정을 해줄 수 없다. 심지어 refresh 토큰도 응답받지 못한다..

결론

때문에 다른 방법이 없을까 찾아보다가 sameSite라는 속성에 대해 알게되었다.

쿠키의 samesite 옵션을 이용하면 “XSRF 보호 토큰” 없이도 (이론상으로) 크로스 사이트 요청 위조를 막을 수 있습니다.

이 속성과 더불어 리액트 react-cookie에 대해 알게 되었다. 현재 내 프로젝트에서는 refresh토큰이나 httpOnly 속성을 적용할 수 없기 때문에 XSS나 CSRF 공격으로부터 그나마 안정성이 있는 쿠키에 secure, sameSite 속성을 고려하였다. 다만 sameSite 속성은 오래된 브라우저(2017년 이전 버전)에선 지원하지 않는다고 한다. 한계점이 있긴 하지만 현 상황에서는 최대한 좋은 방법이라고 생각해서 채택하였다. 프론트단에서 웹보안에 관련해 관심을 갖고 공부해 볼 수 있는 좋은 계기가 되었다. 백엔드 내용은 잘 몰라 검색하고 이해하면서 어려움이 있었는데 그래도 어느정도는 느낌이 오고 다음에 기회가 된다면 백엔드와 소통하면서 이번에 공부했던 내용을 적용해보고 싶다는 생각과 기회가 될때 백엔드 지식도 쌓아 나가야겠다는 생각이 들었다.

이전코드

현재코드



출처:
https://ko.javascript.info/cookie#ref-1845
https://tansfil.tistory.com/59 refresh 토큰
Access Token과 Refresh Token을 어디에 저장해야 할까?
JWT는 어디에 저장해야할까? - localStorage vs cookie
HTTP Only와 Secure Cookie 이해하기
프론트에서 안전하게 로그인 처리하기

profile
나만의 오답노트

0개의 댓글