JWT 토큰을 어디에 저장해야 하는가?

mokyoungg·2021년 2월 4일
7

store token

목록 보기
4/7

이 글은 출처의 내용을 번역한 글입니다.
How to securely store JWT tokens.

모든 출처는 다음과 같습니다.
https://dev.to/gkoniaris/how-to-securely-store-jwt-tokens-51cf


이 글을 쓴 사람은

XSS라는 공격에 노출되기 때문에 JWT 토큰을 스토리지가 아닌 쿠키에 저장하는 것이 맞다고 주장한다.

그리고 쿠키는 XSS라는 공격을 막을 수는 있지만 CSRF 공격에 취약하다고 인정한다.

이와 함께 CSRF를 막기 위한 대안을 몇가지를 제시한다.(Lax 또는 Strice Same SIte 정책의 설정)

개발지식과 영어가 부족하여 완벽하게 번역하지 못했습니다.


지난 몇년간 JWT 토큰은 웹 어플리케이션의 인증 및 인가 방법으로 널리 사용되고 있다.
백엔드 개발자는 데이터 베이스 서버 또는 다른 유형의 스토리지에 대한 단일 쿼리 없이 사용자를 인증할 수 있다.
이는 매우 사용하기 쉬우며 또한 현재 인터넷 상의 데이터에 사용되는 가장 일반적인 포맷인 JSON을 사용한다.
이러한 사실때문에, 사용자가 JWT 토큰을 잘못된 방식으로 저장하여 웹 어플리케이션이 다양한 방식의 공격에 노출되는 사례가 증가하고 있다.

JWT 토큰이란 무엇인가?

JWT는 JSON Web Token의 약자로 JSON 객체의 암호로 작성된 기본 64 표현에 지나지 않는다.(?)
토큰에 서명함으로써(By sigining the toekn) 우리는 토큰의 내용이 어떤식으로든 변경되지 않았는지 확인한다.
이는 수신된 토큰을 처음 서명하는데 사용된 것과 동일한 키로 확인함으로써 달성된다.
생성 된 서명이 토큰의 서명과 일치하지 않을 경우, 토큰이 유효하지 않은 것으로 간주된다.


local storage에 JWT를 저장해도 될까?

대부분의 사람들은 웹 브라우저의 로컬 스토리지에 JWT를 저장하는 경향이 있다.

이는 XSS라는 공격에 대해 취약하다.

이러한 종류의 공격에서, 공격자는 웹 어플리케이션이 호스팅하는 동일한 도메인에서 실행되는

모든 JavaScript 코드를 통해 로컬 스토리지에 액세스(접근)할수 있다는 사실을 이용한다.

따라서, 공격자가 어플리케이션내에 악의적인 JS 코드를 주입하는 방법을 찾을 수 있는 경우
(사용자가 알지 못한 상태에서 사용하는 노드 모듈에 코드를 주입함)

JWT 토큰을 즉시 사용할 수 있다.

이 질문에 답은 '아니오, 로컬 스토리지에 JWT를 저장하지 마시오'이다.

그렇다면 세션 스토리지는 어떨까?

토컬 스토리지와 마찬가지로 세션 스토리지는 웹 어플리케이션이 호스팅되는

동일한 도메인에서 실행되는 모든 JavaScript 코드를 통해 엑세스할 수 있다.

한가지 다른 점은, 사용자가 브라우저를 닫으면 JWT 사라지고 다음 웹 어플리케이션 방문시 사용자가 로그인해야 한다는 점이다.

답은 같다. JWT를 세션 저장소에 저장하지 마시오.


이것들을 사용할 수 없다면.. 쿠키?

쿠키에 대한 비판을 멈춰야한다.
쿠키는 수년간 사용해 왔으며 모든 브라우저에 자동으로 전송되며 매우 안전하다.

하지만 쿠키도 JS를 통해 접근할 수 있다.

이는 서버에서 HttpOnly플래그를 설정하지 않은 경우에만 그렇다.
인증 또는 인가를 부여한느 쿠키에 대해 항상 설정해야 한다.(?)

That’s true, but only if the server doesn’t set the HttpOnly flag,
something you should always set for authentication or authorization cookies.

보안되지 않은 HTTP 요청을 통해 보낸 경우 어떻게 되는가?

요즘은 일반 HTTP를 사용해서는 안 되지만,
쿠키를 만들 때 보안 플래그(Secure flag)를 설정할 수 있기 때문에
보안되자 않은 연결을 통해 절대 전송되지 않는다.

First of all, nobody should use plain HTTP these days,
but even this way, we can set the Secure flag when creating the cookie,
so it will be never sent through a non-secure connection. I think we can move on…

CSRF에 대해선 어떤가?

CSRF에 대해 잊고 있었다.(갑자기 이런다고?) I forgot CSRF attacks.

CSRF란 무엇인가?

CSRF 공격은 공격자가 브라우저의 기본 동작을 이용하여 도메인 간 요청에서도 모든 쿠키를 보낼 때 수행된다.
이로 인해 보안이 매우 취약해질 수 있다. 이 공격의 예는 다음과 같습니다.

  • 공격자는 멋진 제안과 함께 이메일을 보내고 끝에 'Get a 50% Discount!'라는 CTA 버튼을 추가한다.
  • 사용자는 이 제안에 기뻐하고 버튼을 클릭한다.
  • 버튼은 웹 어플리케이션, 특히 사용자의 비밀번호를 새 비밀번호로 변경하는 엔드 포인트에 POST 양식을 제출한다.
  • 쿠키는 모든 요청(교차 도메인 요청 포함)에서 전송되기 때문에 사용자가 로근인 한 경우 엔드포인트는 웹 어플리케이션의
    이전 단계에서 예상대로 작동한다.
  • 이제 사용자가 로그아웃되어 더이상 웹 어플리케이션에 로그인할 수 없게 된다.

그래서 CSRF에 대해 무엇을 할 수 있는가.

서버에 수행하는 모든 요청(일반적으로 POST, PUT, DELETE 요청)에서 백엔드 생성 토큰을 사용할 수 있다.
사용자가 요청을 수행할 때 일부 캐시에서 토큰을 가져오거나 데이터베이스에서 직접 가져와 토큰이 유효한지 확인한다.
그러나 사용자가 새 페이지로 리디렉션할 때마다 새 토큰을 만들어야 한다. 다른 대안은 없을까?

아쉽게도 수년 동안, 유일한 방법은 쿠키 기반 인증을 사용할 때 CSRF 토큰을 사용하는 것이다.
2016년부터, 현대의 브라우저들은 SameSite라고 불리는 쿠키 정책을 시행하기 시작했다.
...


이하 생략...
이 글에 대해서 반대하는 의견들도 많았는데
확실한 답이 없는가 보다.

profile
생경하다.

0개의 댓글