페이로드와 서명간에 JWT 분할
컨텍스트 : 단일 페이지 애플리케이션에서 JWT 토큰에 대한 스토리지 솔루션을 찾고 있습니다.
- JWT를 로컬 스토리지에 저장하는 것은 안전하지 않으며 XSS 공격을 받기 쉽습니다.
- 보안 / HTTP 전용 쿠키에 JWT를 저장하는 것이 더 안전하지만 CSRF 공격을 받기 쉽습니다.
다음 시나리오를 연구하고 있습니다.
인증시 새로 고침 토큰은 http 전용 보안 쿠키에 저장됩니다. 액세스 토큰을 얻는 데만 사용할 수 있습니다.
권한이 부여되면 백엔드는 JWT 액세스 토큰으로 응답합니다. JWT의 헤더 및 페이로드 부분은 응답 본문 안에 있습니다. 토큰 서명은 전송되지 않고 http 전용 보안 쿠키에 설정됩니다 (가능한 경우 동일한 사이트가 엄격하지만 그렇지 않다고 가정). 헤더 + 페이로드는 메모리에 저장됩니다.
JWT에는 다음 클레임이 포함됩니다.
- iat, nbf, exp (추측 가능한 IMO)
- 사용자 ID 및 권한과 관련된 클레임 (사용자 ID가 알려진 경우 추측 가능)
- 암호화로 안전한 난수를 포함하는 jti (제 경우에는 python secrets로 생성됨 )
요청을 할 때 헤더 + 페이로드는 인증 헤더의 SPA에 의해 XHR / fetch를 통해 전송됩니다. 서명은 쿠키와 함께 전송됩니다. 백엔드는 둘 모두를 연결하고 서명을 확인합니다.
- 이 메커니즘은 CSRF 공격에 대해 안전합니까? jti 클레임으로 인해 Authorization token + signature 쿠키가 유효한 CSRF 완화 기술이됩니까?
- 이 메커니즘은 로컬 저장소 내부에 JWT를 저장하는 것보다 XSS 공격에 대해 실제로 더 안전합니까? (XSS를 사용하는 공격은 TRACE 익스플로잇 과 같이 쉽게 서명을 훔칠 수 있습니까? )
참고 : 이 질문 은 비슷하지만 지나치게 광범위하므로 더 정확한 답변을 얻기 위해이 질문 을 게시하고 있습니다.
답변
이 메커니즘은 CSRF 공격에 대해 안전합니까?
JWT를 분할하고 서명을 쿠키에 저장하고 브라우저 저장소의 나머지 토큰을 저장하는이 방법은 전체 JWT가 로컬 또는 세션 저장소에 저장된 경우보다 CSRF 공격에 대한 추가 보호를 제공하지 않습니다. 예, CSRF 공격을 완화하지만 서버에서 JWT를 분할하고 연결하는 불필요한 오버 헤드를 추가 할 필요는 없습니다. JWT를 로컬 저장소에 저장하고 Authorization 헤더에서만 수락하면 CSRF 공격으로부터 애플리케이션을 보호하기에 충분합니다.
이 메커니즘은 로컬 저장소에 JWT를 저장하는 것보다 XSS 공격에 대해 실제로 더 안전합니까? (XSS를 사용하는 공격은 TRACE 익스플로잇과 같이 쉽게 서명을 훔칠 수 있습니까?)
공격자가 JWT를 훔칠 수있는 것에 만 초점을 맞추고 있다면이 접근 방식은 올바르게 언급했듯이 서버에서 TRACE를 활성화하지 않는 한 안전합니다.
그러나 이것이 XSS 공격으로부터 애플리케이션을 더 안전하게 만들지는 않습니다. 예를 들어 애플리케이션에서 임의의 자바 스크립트를 실행할 수있는 경우 로컬 저장소에서 JWT 헤더 + 페이로드를 가져 와서 withCredentials를 True로 설정 한 상태로 민감한 엔드 포인트에 XHR을 보낼 수 있습니다. 예를 들어이 엔드 포인트는 계정 이메일 주소를 변경하도록 설계되었을 수 있습니다. 그 즉시 계정 탈취로 이어집니다. 쿠키 나 JWT를 훔칠 필요가 없습니다.
요약 : 이 접근 방식은 서명을 나머지 토큰과 분리하여 세션 토큰에 대한 보호를 제공합니다. 그러나 XSS와 관련하여 세션 토큰을 훔치는 것이 유일한 위험은 아닙니다.