JWT를 도난 당하면 어떻게됩니까?


201

RESTful API에 대해 JWT를 사용하여 상태 비 저장 인증을 구현하려고합니다.

AFAIK, JWT는 기본적으로 REST 호출 중에 HTTP 헤더로 전달되는 암호화 된 문자열입니다.

그러나 요청을보고 토큰을 훔치는 도청자가 있다면 어떨까요? 그러면 내 신분으로 요청을 속일 수 있습니까?

실제로이 문제는 모든 토큰 기반 인증에 적용됩니다 .

그것을 막는 방법? HTTPS와 같은 보안 채널?


1
이것이 바로 토큰이 짧은 기간 동안 만 유효한 이유입니다. 데이터의 기밀성이 염려되면 HTTPS를 사용해야합니다.
Jonathon Reinhart

4
@JonathonReinhart 그러나 토큰이 곧 만료되면 클라이언트는 때때로 자신을 재 인증하여 새로운 토큰을 가져와야합니다. 지루하지 않습니까?
smwikipedia

@JonathonReinhart 토큰이 수명이 짧은 이유를 알 것 같습니다. 그렇게하면 서버는 토큰 만료를 추적 할 필요가 없으므로 확장 성을 확보 할 수 있습니다. 그것은 현물의의 trade-off사이 having finer control of token expirationhaving better scalability.
smwikipedia

2
이것도 도움이 될 수 있습니까? - "토큰 도난을 탐지하는 일반적인 보안 메커니즘은 요청 IP 주소 출처를 추적하는 것입니다." -마지막 섹션에 자세히 설명되어 있습니다 -firebase.google.com/docs/auth/admin/manage-sessions
Ula

3
이론적으로 토큰 도난을 방지하는 것은 불가능합니다. 우리가 할 수있는 최선의 일은 그것이 일어난 것을 감지 한 다음 최대한 빨리 세션을 취소하는 것입니다. 감지하는 가장 좋은 방법은 RFC 6819에서 제안한대로 회전 새로 고침 토큰을 사용하는 것입니다. 다음은이 자세히 설명하는 블로그 : supertokens.io/blog/...은
Rishabh 인스 포 다르

답변:


284

필자는 상당히 깊이있는 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 자격 증명을 제공 한 다음 토큰을 교환하여 서버와 함께 자신을 다시 인증해야합니다.

이 프로세스는 때때로 발생하기 때문에 토큰이 자주 변경되어 공격자가 큰 어려움을 겪지 않고 지속적으로 당신을 사칭하기가 어렵습니다.

희망적으로 이것은 도움이됩니다 ^^


3
다음 기사의 저자는 JWT의 단점은 도난당한 JWT를 복구하는 유일한 방법은 새로운 키 쌍을 생성하고 모든 사용자를 효과적으로 로그 아웃하는 것 뿐이라고 주장합니다. DB에 저장된 세션 ID를 사용하는 경우 웹 사이트는 영향을받는 사용자의 세션 만 삭제하고 모든 장치에서 로그 아웃 할 수 있습니다. 여기에 OAuth2가 어떻게 적용되는지 또는 제시된 단점을 완화시키는 데 도움이되는지 확실하지 않습니다. medium.com/@rahulgolwalkar/…
Marcel

4
저자가 잘못되었습니다. 토큰을 무효화하는 데 사용할 수있는 다양한 디자인 패턴이 있습니다. 그러나 일반적으로 모든 종류의 인증 목적으로 JWT를 사용하는 것은 좋지 않습니다. 암호로 서명 된 세션 아이디어가 포함 된 세션 쿠키를 사용하는 것이 훨씬 더 효율적입니다.
rdegges

1
@rdegges JWT가 인증에 어떻게 나쁜 아이디어인지 알려주세요. 위의 의견에서 언급 한 세션 쿠키를 어떻게 사용할 수 있습니까?
noman tufail

6
단일 응답을 입력하기에는 너무 길다. 더 배우고 싶다면 주제에 대해 자세히 이야기했습니다. 내 슬라이드를 온라인으로 확인할 수 있습니다 : speakerdeck.com/rdegges/jwts-suck-and-are-stupid
rdegges

2
이론적으로 토큰 도난을 방지하는 것은 불가능합니다. 우리가 할 수있는 최선의 일은 그것이 일어난 것을 감지 한 다음 최대한 빨리 세션을 취소하는 것입니다. 감지하는 가장 좋은 방법은 RFC 6819에서 제안한대로 회전 새로 고침 토큰을 사용하는 것입니다. 다음은이 자세히 설명하는 블로그 : supertokens.io/blog/...은
Rishabh 인스 포 다르

31

나는 이것이 오래된 질문이라는 것을 알고 있지만 여기에 내 $ 0.50을 떨어 뜨릴 수 있다고 생각합니다. 아마도 누군가 내 접근 방식을 완전히 거부하기 위해 논쟁을 개선하거나 제공 할 수 있습니다. HTTPS (ofc)를 통한 RESTful API에서 JWT를 사용하고 있습니다.

이것이 작동하려면 항상 단기 토큰을 발행해야합니다 (대부분의 경우에 따라 내 응용 프로그램에서 실제로 exp청구를 30 분, ttl3 일로 설정하고 있으므로이 토큰 ttl이 여전히 유효한 한 새로 고칠 수 있습니다 유효하고 토큰이 블랙리스트에 포함 되지 않았습니다 )

의 경우 authentication service토큰을 무효화하기 위해 일부 기준에 따라 인 메모리 캐시 레이어 ( 내 경우에는 redis )를 JWT blacklist/ ban-list앞에 사용하고 싶습니다. (RESTful 철학을 위반한다는 것을 알고 있지만 저장된 문서는 남은 시간을 블랙리스트에 ttl올리면 정말 짧습니다.

참고 : 블랙리스트에 올린 토큰은 자동으로 새로 고칠 수 없습니다

  • 경우 user.password또는 user.email(암호 확인 필요), 정식 서비스 이전 (들)을 상쾌 토큰 및 무효화 (차단)를 반환 업데이트되었습니다, 그래서 당신의 클라이언트 감지하여 사용자의 신원을 어떻게 든 손상되어, 당신은 암호를 변경하는 사용자를 요청할 수있는 경우 . 블랙리스트를 사용하지 않으려 는 경우 필드 iat에 대해 (발행 된) 클레임을 검증 할 수 있지만 권장하지는 않습니다 user.updated_at( jwt.iat < user.updated_atJWT가 유효하지 않은 경우).
  • 사용자가 일부러 로그 아웃했습니다.

마지막으로 모든 사람과 마찬가지로 토큰의 유효성을 검사합니다.

참고 2 : 캐시 자체의 키로 토큰 자체를 사용하는 대신 jti클레임에 UUID 토큰을 생성하고 사용하는 것이 좋습니다 . 어떤 좋은 나는 당신이 반환하여,뿐만 아니라 토큰에 CSRF로이 같은 UUID를 사용할 수 있습니다 (그냥 내 마음에 와서하지 않도록 때문에) 생각 secure/ non-http-only구현하는 제대로와 쿠키와 X-XSRF-TOKENJS를 사용하여 헤더를. 이렇게하면 CSRF 검사를위한 또 다른 토큰을 작성하는 컴퓨팅 작업을 피할 수 있습니다.


9
아이디어를 기르기에 너무 늦지 않았습니다. 답장을 보내 주셔서 감사합니다.
smwikipedia

2
모든 요청에 ​​대해 확인해야하는 블랙리스트를 서버에 저장하는 경우 단순히 일반 세션을 사용하지 않는 이유는 무엇입니까?
Franklin Yu

@FranklinYu 블랙리스트는 전체 세션 저장소보다 "저렴한"방법입니다. 수명이 짧은 키-값 객체 (잔여 시간에 따라 매우 짧아야 함)를 저장하고 있기 때문에 로그 아웃 조치 및 토큰을 무효화하는 조치에만 발생하므로 모든 토큰이 그렇지는 않습니다. ofc. 저장
Frondor

2
얼마나 저렴한가요? 우선, 서버 측에 어떤 것도 저장하고 있다면, JWT가 주장하는 "확장 성"혜택을 누릴 수 없습니다. 왜냐하면 모든 애플리케이션 서버가 어떤 작업을하기 전에 대화해야하는 중앙 블랙리스트 서버가 여전히 있기 때문입니다. 빠른 만료로 인해 1k 블랙리스트 만 저장해야하는 경우 세션에 대해 동일한 작업을 수행 할 수 있으므로 1k 세션 만 저장하면됩니다.
Franklin Yu

3
나는이 접근법을 좋아한다. 실제로 각 요청에서 블랙리스트를 확인할 필요는 없으며 JWT가 만료 된 후 (토큰 자체에서 읽을 수있는) 요청 후 TTL 기간까지만 발생합니다. "표준"사용 사례에서는 주어진 토큰의 수명 동안 최대 한 번 발생해야합니다. 새로 고친 후에는 향후 새로 고침 요청을 거부 할 수 있습니다. 감사합니다 @Frondor
John Ackerman

7

조금 늦어서 미안하지만 비슷한 우려가 있었으며 이제는 같은 일에 기여하고 싶습니다.

1) rdegges 는 JWT가 "보안"과 아무 관련이 없으며 누군가 페이로드를 엉망으로 만들 었는지 여부를 단순히 검증한다는 훌륭한 지적을 덧붙였다. ssl은 위반을 방지하는 데 도움이됩니다.

2) 이제 ssl이 어떻게 든 손상되면 도청자가 우리의 베어러 토큰 (JWT)을 훔치고 진정한 사용자를 가장 할 수 있습니다. 다음 단계 는 클라이언트에서 JWT의 "소유 증명" 을 추구하는 것입니다. .

3) 이제,이 접근 방식으로, JWT의 발표자는 특정 POP (Proof-Of-Of-Possession) 키를 보유하며, 수신자는 요청이 동일한 실제 사용자로부터 온 것인지 아닌지를 암호로 확인할 수 있습니다 .

나는 이것에 대한 소유 증명 기사를 참조했고 apporach와 확신합니다.

무엇이든 기여할 수 있다면 기뻐할 것입니다.

건배 (y)


0

클레임의 일부로이 JWT 토큰을 생성하도록 요청한 초기 호스트의 IP를 추가 할 수 없습니까? 이제 JWT를 도용하여 다른 머신에서 사용하는 경우 서버가이 토큰의 유효성을 검증하면 요청 된 머신 IP가 클레임의 일부로 설정된 머신 IP와 일치하는지 확인할 수 있습니다. 이는 일치하지 않으므로 토큰을 거부 할 수 있습니다. 또한 사용자가 자신의 IP를 토큰으로 설정하여 토큰을 조작하려고하면 토큰이 변경되면 토큰이 거부됩니다.


이는 하나의 가능한 솔루션이지만 방화벽 뒤의 클라이언트에게는 IP 주소가 주소 풀에서 선택되고 언제든지 변경 될 수있는 것이 일반적입니다.
SpeedOfSpin
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.