development

JWT 정리 (Best practices for JWT tokens)

여름싼타 2023. 2. 25. 09:11
반응형

JWT는 JSON 객체로서 백엔드와 프론트엔드 간에 안전하게 정보를 전송하기 위해 사용되는 기술입니다. 프론트엔드 용으로 리액트나 다른 SPA 또는 SSR 앱을 사용하는 동안에는 백엔드와의 데이터 전송을 사용할 가능성이 높다.

데이터를 훔칠 가능성이 있는 악의적 해커로부터의 콜을 보호하는 방법이 필요하다. 이를 위한 가장 좋은 방법 중 하나는 JWT를 사용하는 것이다.

 

1. JWT 토큰의 사용시기와 장소

얼핏 보면 JWT를 이용해 플랫폼 간에 데이터를 보내는 게 좋을 것 같다. JWT 토큰에는 데이터가 포함되며, 그 데이터는 전면과 백엔드 간에 전송된다.

정보는 JWT 내부에 인코딩 된 형식으로 저장되기 때문에 관련 데이터를 인코딩하여 백엔드에서 프론트엔드로 보낼 수 있다. 이것은 간단하고 효율적인 데이터 전송 방법처럼 보이지만 두 가지 문제가 있다.

개발자가 데이터 전송에 JWT를 사용하기 때문에 통합 앱이 새로운 포맷을 지원할 수 없기 때문에 JWT 구조를 변경하는 즉시 문제가 발생한다.

토큰의 내용을 누구나 읽을 수 있다면 보안은 큰 우려 사항이 될 것이다. 토큰을 통해 기밀 데이터가 전송되고 있는 경우 누구나 읽을 수 있다. 그리고 공격자는 API에 대한 모든 정보를 사용할 수도 있다. 따라서 액세스 토큰으로서의 JWT는 Bearer 토큰으로 사용되며 API에 의해 디코딩되고 응답을 전송하기 전에 검증된다.

 

2. 올바른 알고리즘 선택

JWT는 수많은 서명 알고리즘으로 서명할 수 있다. 헤더 내 alg 클레임은 서명 또는 암호화에 사용된 알고리즘, 토큰이 서명(JWS)인지 암호화(JWE)인지를 나타낸다.

가장 일반적인 서명 알고리즘 유형은 RS256, SHA-256 및 P-256이다.

alg 클레임에는 JWS가 서명되지 않았음을 의미하는 값이 없을 수 있다. 이 옵션은 일반적으로 권장되지 않는다. 서명되지 않은 JWT를 활성화하려면 무엇을 하고 있는지 확인해야 한다. 이는 일반적으로 토큰 발행자와 토큰을 사용하는 클라이언트 모두의 정체성에 대해 상당히 확실하며, 어느 당사자도 토큰을 조작할 수 없다는 것을 확신한다는 것을 의미한다.

 

3. 프런트엔드 JWT 보관장소

많은 사람들은 프론트 엔드에 JWT 토큰을 저장할 필요가 전혀 없다고 주장하겠지만 세션과 쿠키가 당신에게 도움이 된다. 단, JWT를 보유해야 하는 경우에는 다음 옵션이 있다.

 

  • Local Storage
  • React State
  • HttpOnlyCookie

 

현재 JWT를 로컬 스토리지에 저장하는 것은 애플리케이션에서 가장 안전성이 낮은 방법이다. 이는 크로스 사이트 스크립팅(XSS) 공격에 의해 침해될 가능성이 있기 때문이다.

또한 토큰을 반응 상태로 저장하는 것이 가장 안전한 방법으로 보이지만 실제 사용 사례는 되지 않는다. 반응 상태에 저장된 데이터는 페이지를 업데이트하면 상태가 손실된다.

더 좋고 더 안전한 방법은 HttpOnlycookie에 JWT를 저장하는 것이다. 자바스크립트로 쿠키에 액세스 하는 것은 불가능하므로 변조가 이루어지지 않는다.

 

4. 세션 관리에 사용하지 마십시오.

점점 더 많은 프론트 엔드 개발자들이 JWT가 세션 쿠키와 집중 세션 대신 세션 유지 메커니즘으로서의 이점을 가지고 있다고 주장하고 있다.

언뜻 보기에 세션 토큰에 JWT를 사용하는 것은 현명한 생각처럼 보일 수 있지만 실제로는 JWT가 세션 처리를 위한 좋은 선택지로 여겨져서는 안 된다. JWT는 세션에서 사용하기 위한 것이 아니다. 이러한 방법으로 사용하면 애플리케이션 보안이 저하될 수 있다.

JWT의 복잡한 표준은 공격자가 JWT를 복제하고 다른 사람인 척하는 것을 용이하게 한다.

마지막으로 JWT는 광범위하기 때문에 쿠키에서 그것들을 사용하는 것은 JWT 토큰을 필수 데이터와 함께 저장하기 위해 많은 공간이 필요하기 때문에 하나의 요청당 비용이 매우 높다. 따라서 세션 토큰으로 사용하지 않는 것이 좋다.

 

5. 토큰 서명

JWT 시그니처는 토큰 내 데이터(페이로드)가 변경되지 않았음을 보증하는 기본 보안 기능이다. 여기서 주의해야 할 중요한 점은 시그니처가 토큰과 헤더의 페이로드에 서명하는 데 사용된다는 것이다.

이 서명은 개인 키를 사용하여 서버에 의해 개발된다. 이 개인 키는 JWT 시그니처에 필수적인 부분이다.

또한 클레임에는 랜덤한 id가 부가되며 동일한 서명으로 서명된 두 토큰을 구별한다. 이를 통해 두 토큰이 유사하지 않음을 확인한다. JWT의 보안은 다음 두 가지 요인에 의해 결정된다.

개인 키는 비밀로 해둬야 한다.

최소 키 길이는 HMAC 알고리즘과 함께 사용되는 해시함수의 비트 크기와 같아야 한다.

토큰에 서명하는 것의 중요성에 대해 논의했듯이 여기서 한 가지 주의해야 할 것은 대칭 서명을 사용하지 않는 것이다. 대칭 키를 사용하는 경우에는 비밀을 모든 당사자 간에 공유해야 한다.

이 때문에 당사자가 늘어나면서 비밀의 안전을 지키고 비밀이 밝혀지면 대신하기가 점점 어려워지고 있다.

심볼릭 서명의 또 다른 문제는 누가 키에 서명했는지 증명하는 것이다. 비대칭 키를 사용하는 경우 JWT는 개인 키를 소유한 누구에 의해서나 서명된 것이 된다. 대칭 서명의 경우 비밀에 접근할 수 있는 모든 당사자가 토큰에 서명할 수도 있다.

어떤 이유로 대칭 서명을 사용해야 하는 경우, ephemeral secret을 사용해라. 이것은 보안을 강화하는 데 도움이 된다.

 

- 참고 : https://mojoauth.com/blog/best-practices-for-jwt-tokens/

반응형