RESTful API에 대해 JWT를 사용하여 상태 비 저장 인증을 구현하려고합니다.
AFAIK, JWT는 기본적으로 REST 호출 중에 HTTP 헤더로 전달되는 암호화 된 문자열입니다.
그러나 요청을보고 토큰을 훔치는 도청자가 있다면 어떨까요? 그러면 내 신분으로 요청을 속일 수 있습니까?
실제로이 문제는 모든 토큰 기반 인증에 적용됩니다 .
그것을 막는 방법? HTTPS와 같은 보안 채널?
답변
필자는 상당히 깊이있는 express-stormpath 에서 인증을 처리하는 노드 라이브러리의 저자 이므로 여기에서 정보를 얻을 것입니다.
우선, JWT는 일반적으로 암호화 되지 않습니다 . 암호화 JWT를 할 수있는 방법이 있지만 (참조 : JWEs을 )이 여러 가지 이유로 실제로는 매우 일반적인 아닙니다.
다음으로, 모든 형태의 인증 (JWT 사용 여부에 관계없이)에는 MitM 공격 (man-in-the-middle) 공격이 적용됩니다. 이러한 공격은 인터넷을 통해 요청을 할 때 공격자가 네트워크 트래픽을 볼 수있을 때 발생합니다. 이것은 ISP가 볼 수있는 것, NSA 등입니다.
이것이 SSL을 막는 데 도움이되는 것입니다 : 컴퓨터에서 네트워크 트래픽을 암호화하여-> 인증 할 때 일부 서버, 네트워크 트래픽을 모니터링하는 제 3자는 토큰, 암호 등을 볼 수 없습니다. 서버의 개인 SSL 키 사본을 얻을 수 있습니다. 이것이 모든 형태의 인증에 SSL이 반드시 필요한 이유입니다.
그러나 누군가 SSL을 악용하고 토큰을 볼 수 있다고 가정 해 봅시다. 질문에 대한 대답은 예입니다 . 공격자 는 해당 토큰을 사용하여 귀하를 사칭하고 서버에 요청할 수 있습니다.
이제 프로토콜이 들어옵니다.
JWT는 인증 토큰에 대한 하나의 표준입니다. 그들은 거의 아무것도 사용할 수 있습니다. JWT가 멋진 이유는 추가 정보를 포함시킬 수 있고 아무도 정보를 엉망으로 만들지 않았기 때문에 서명 할 수 있기 때문입니다.
그러나 JWT 자체는 ‘보안’과 관련이 없습니다. 모든 의도와 목적을 위해, JWT는 API 키와 거의 동일합니다. 어딘가의 서버에 대해 인증하는 데 사용하는 임의의 문자열입니다.
질문을 더욱 흥미롭게 만드는 것은 사용중인 프로토콜 (대부분 OAuth2)입니다.
OAuth2가 작동하는 방식은 클라이언트에게 짧은 시간 동안 만 인증을 위해 임시 토큰 (예 : JWT!)을 제공하도록 설계되었습니다!
아이디어는 토큰을 도난당한 경우 공격자가 단기간 동안 만 토큰을 사용할 수 있다는 것입니다.
OAuth2를 사용하면 사용자 이름 / 암호 또는 API 자격 증명을 제공 한 다음 토큰을 교환하여 서버와 함께 자신을 다시 인증해야합니다.
이 프로세스는 때때로 발생하기 때문에 토큰이 자주 변경되어 공격자가 큰 어려움을 겪지 않고 지속적으로 당신을 사칭하기가 어렵습니다.
희망적으로 이것은 도움이됩니다 ^^
답변
나는 이것이 오래된 질문이라는 것을 알고 있지만 여기에 내 $ 0.50을 떨어 뜨릴 수 있다고 생각합니다. 아마도 누군가 내 접근 방식을 완전히 거부하기 위해 논쟁을 개선하거나 제공 할 수 있습니다. HTTPS (ofc)를 통한 RESTful API에서 JWT를 사용하고 있습니다.
이것이 작동하려면 항상 단기 토큰을 발행해야합니다 (대부분의 경우에 따라 내 응용 프로그램에서 실제로 exp
청구를 30 분, ttl
3 일로 설정하고 있으므로이 토큰 ttl
이 여전히 유효한 한 새로 고칠 수 있습니다 유효하고 토큰이 블랙리스트에 포함 되지 않았습니다 )
의 경우 authentication service
토큰을 무효화하기 위해 일부 기준에 따라 인 메모리 캐시 레이어 ( 내 경우에는 redis )를 JWT blacklist
/ ban-list
앞에 사용하고 싶습니다. (RESTful 철학을 위반한다는 것을 알고 있지만 저장된 문서는 남은 시간을 블랙리스트에 ttl
올리면 정말 짧습니다.
참고 : 블랙리스트에 올린 토큰은 자동으로 새로 고칠 수 없습니다
- 경우
user.password
또는user.email
(암호 확인 필요), 정식 서비스 이전 (들)을 상쾌 토큰 및 무효화 (차단)를 반환 업데이트되었습니다, 그래서 당신의 클라이언트 감지하여 사용자의 신원을 어떻게 든 손상되어, 당신은 암호를 변경하는 사용자를 요청할 수있는 경우 . 블랙리스트를 사용하지 않으려 는 경우 필드iat
에 대해 (발행 된) 클레임을 검증 할 수 있지만 권장하지는 않습니다user.updated_at
(jwt.iat < user.updated_at
JWT가 유효하지 않은 경우). - 사용자가 일부러 로그 아웃했습니다.
마지막으로 모든 사람과 마찬가지로 토큰의 유효성을 검사합니다.
참고 2 : 캐시 자체의 키로 토큰 자체를 사용하는 대신 jti
클레임에 UUID 토큰을 생성하고 사용하는 것이 좋습니다 . 어떤 좋은 나는 당신이 반환하여,뿐만 아니라 토큰에 CSRF로이 같은 UUID를 사용할 수 있습니다 (그냥 내 마음에 와서하지 않도록 때문에) 생각 secure
/ non-http-only
구현하는 제대로와 쿠키와 X-XSRF-TOKEN
JS를 사용하여 헤더를. 이렇게하면 CSRF 검사를위한 또 다른 토큰을 작성하는 컴퓨팅 작업을 피할 수 있습니다.
답변
조금 늦어서 미안하지만 비슷한 우려가 있었으며 이제는 같은 일에 기여하고 싶습니다.
1) rdegges 는 JWT가 “보안”과 아무 관련이 없으며 누군가 페이로드를 엉망으로 만들 었는지 여부를 단순히 검증한다는 훌륭한 지적을 덧붙였다. ssl은 위반을 방지하는 데 도움이됩니다.
2) 이제 ssl이 어떻게 든 손상되면 도청자가 우리의 베어러 토큰 (JWT)을 훔치고 진정한 사용자를 가장 할 수 있습니다. 다음 단계 는 클라이언트에서 JWT의 “소유 증명” 을 추구하는 것입니다. .
3) 이제,이 접근 방식으로, JWT의 발표자는 특정 POP (Proof-Of-Of-Possession) 키를 보유하며, 수신자는 요청이 동일한 실제 사용자로부터 온 것인지 아닌지를 암호로 확인할 수 있습니다 .
나는 이것에 대한 소유 증명 기사를 참조했고 apporach와 확신합니다.
무엇이든 기여할 수 있다면 기뻐할 것입니다.
건배 (y)
답변
클레임의 일부로이 JWT 토큰을 생성하도록 요청한 초기 호스트의 IP를 추가 할 수 없습니까? 이제 JWT를 도용하여 다른 머신에서 사용하는 경우 서버가이 토큰의 유효성을 검증하면 요청 된 머신 IP가 클레임의 일부로 설정된 머신 IP와 일치하는지 확인할 수 있습니다. 이는 일치하지 않으므로 토큰을 거부 할 수 있습니다. 또한 사용자가 자신의 IP를 토큰으로 설정하여 토큰을 조작하려고하면 토큰이 변경되면 토큰이 거부됩니다.