브라우저에서 JWT를 어디에 저장합니까? CSRF로부터 보호하는 방법?


159

쿠키 기반 인증을 알고 있습니다. MITM 및 XSS로부터 쿠키 기반 인증을 보호하기 위해 SSL 및 HttpOnly 플래그를 적용 할 수 있습니다. 그러나 CSRF로부터 보호하기 위해서는보다 특별한 조치가 필요합니다. 그들은 조금 복잡합니다. ( 참고 )

최근에는 JSON 웹 토큰 (JWT)이 인증 솔루션으로 매우 뜨겁다는 것을 알게되었습니다. JWT 인코딩, 디코딩 및 확인에 대한 내용을 알고 있습니다. 그러나 JWT를 사용하는 경우 일부 웹 사이트 / 자습서에서 CSRF 보호가 필요하지 않은 이유를 이해하지 못합니다. 나는 꽤 많이 읽고 아래 문제를 요약하려고합니다. 나는 누군가 JWT의 큰 그림을 제공하고 JWT에 대해 오해 된 개념을 명확히하기를 원합니다.

  1. JWT가 쿠키에 저장되어 있으면 쿠키 / 토큰을 확인하기 위해 서버에 세션이 필요하지 않다는 점을 제외하면 쿠키 기반 인증과 동일하다고 생각합니다. 특별한 조치를 취하지 않으면 CSRF에 여전히 위험이 있습니다. JWT가 쿠키에 저장되어 있지 않습니까?

  2. JWT가 localStorage / sessionStorage에 저장된 경우 쿠키가 없으므로 CRSF로부터 보호 할 필요가 없습니다. 문제는 JWT를 서버로 보내는 방법입니다. 내가 발견 여기에 HTTP 헤더 아약스 요청에 의해 JWT를 보낼 jQuery를 사용하여 제안합니다. 그렇다면 아약스 요청 만 인증을 수행 할 수 있습니까?

  3. 또한 "Authorization header"와 "Bearer"를 사용하여 JWT를 보내는 블로그 쇼가 하나 더 있습니다. 블로그에서 말하는 방법을 이해하지 못합니다. "인증 헤더"및 "베어러"에 대해 더 설명해 주시겠습니까? JWT가 모든 요청의 HTTP 헤더로 전송됩니까? 그렇다면 CSRF는 어떻습니까?

답변:


70

JWT 토큰은 OAuth 2.0OpenID Connect 와 같은 새로운 인증 및 인증 프로토콜에서 기본 토큰 형식으로 사용되므로 널리 사용됩니다 .

토큰이 쿠키에 저장되면 브라우저는 자동으로 각 요청과 함께 동일한 도메인으로 토큰을 보내며 여전히 CSRF 공격에 취약합니다.

베어러 인증은 HTTP에 정의 된 인증 체계 중 하나입니다 . 기본적으로 YOU요청의 Authorization HTTP 헤더에 (JWT) 토큰 을 고정시키는 것을 의미합니다 . 브라우저가 NOT자동으로이를 수행하므로 웹 사이트를 보호하는 데 적합하지 않습니다. 브라우저가 요청에 헤더를 자동으로 추가하지 않기 때문에 CSRF 공격에 취약하지 않습니다. CSRF 공격은 인증 정보가 원본 도메인에 자동으로 제출되는 것에 따라 다릅니다.

베어러 방식은 종종 AJAX 호출 또는 모바일 클라이언트에서 사용되는 웹 API (REST 서비스)를 보호하는 데 사용됩니다.


1
@ Timespace7 아니요, JWT 토큰도 종종 기본 클라이언트에서 사용됩니다. OAuth 2.0에는 기본 (모바일) 클라이언트를 대상으로하는 흐름이 있습니다. 그들이하지 않는 것은 암시 적 브라우저 인증 (쿠키 또는 기본 인증 등)입니다.
MvdD

5
API가 Authorization 헤더에서 JWT 토큰 만 검색하는 경우 CSRF에 취약하지 않다고 말하고 있습니다. 쿠키에서 토큰을 얻는 사이트 또는 API에는 CSRF 완화가 필요합니다.
MvdD

13
이것은 jwt를 쿠키에 효과적으로 저장할 수 있고 Authorization 헤더에 요청을 보내면 안전하다는 것을 의미합니까?
cameronroe

10
@cameronjroe 쿠키에 쿠키를 저장할 수 있지만 인증을 위해 쿠키를 사용하지 않는 경우에만 (이 경우 헤더를 사용)
Jaakko

1
AJAX 호출도 브라우저에서 시작됩니다. JWT 토큰은 주로 웹 API (데이터 제공)와 웹 앱 (마크 업, 이미지, CSS 및 JavaScript 제공)을 인증하는 데 사용되는 쿠키를 인증하는 데 사용됩니다.
MvdD

144

클라이언트 컴퓨터에 JWT를 저장해야합니다. LocalStorage / SessionStorage에 저장하면 XSS 공격으로 쉽게 잡을 수 있습니다. 쿠키에 쿠키를 저장하면 해커가 CSRF 공격에서 쿠키를 읽고 (읽지 않고) 사용자를 가장하고 API에 연락하여 조치를 취하거나 사용자 대신 정보를 얻기위한 요청을 보낼 수 있습니다.

그러나 쿠키에서 JWT를 안전하게 도난 당하지 않도록 보호하는 방법에는 여러 가지가 있습니다 (그러나 여전히 도용하는 고급 기술이 있습니다). 그러나 LocalStorage / SessionStorage에 의존하고 싶다면 간단한 XSS 공격으로 액세스 할 수 있습니다.

CSRF 문제를 해결하기 위해 신청서에 이중 제출 쿠키를 사용합니다.

이중 제출 쿠키 방법

  1. JWT를 HttpOnly 쿠키에 저장하고 보안 모드에서 사용하여 HTTPS를 통해 전송하십시오.

  2. 대부분의 CSRF 공격에는 요청시 원래 호스트와 다른 원본 또는 참조 헤더가 있습니다. 헤더에 포함되어 있는지 확인하십시오. 도메인에서 오는지 여부입니다! 거부하지 않으면. 요청에서 출발지와 리퍼러를 모두 사용할 수없는 경우 걱정할 필요가 없습니다. 다음 단계에서 설명하는 X-XSRF-TOKEN 헤더 유효성 검사 결과에 의존 할 수 있습니다.

  3. 브라우저가 요청 도메인에 쿠키를 자동으로 제공하지만 한 가지 유용한 제한이 있습니다. 웹 사이트에서 실행되는 JavaScript 코드는 다른 웹 사이트의 쿠키를 읽을 수 없습니다. 이를 활용하여 CSRF 솔루션을 만들 수 있습니다. CSRF 공격을 방지하려면 XSRF-TOKEN이라는 추가 Javascript 판독 가능 쿠키를 작성해야합니다. 이 쿠키는 사용자가 로그인 할 때 생성되어야하며 추측 할 수없는 임의의 문자열을 포함해야합니다. 또한이 번호를 JWT 자체에 개인 클레임으로 저장합니다. JavaScript 응용 프로그램은 요청을 할 때마다이 토큰을 읽고 사용자 지정 HTTP 헤더로 보내야합니다. 이러한 작업 (쿠키 읽기, 헤더 설정)은 JavaScript 애플리케이션의 동일한 도메인에서만 수행 할 수 있으므로,

Angular JS는 당신의 인생을 쉽게 만듭니다

다행히도 플랫폼에서 Angular JS를 사용하고 CSRF 토큰 방식으로 Angular 패키지를 사용하여 구현하기가 더 간단 해졌습니다. Angular 애플리케이션이 서버를 만드는 모든 요청에 ​​대해 Angular $http서비스는 다음 작업을 자동으로 수행합니다.

  • 현재 도메인에서 XSRF-TOKEN이라는 쿠키를 찾으십시오.
  • 해당 쿠키가 발견되면 값을 읽고 X-XSRF-TOKEN 헤더로 요청에 추가합니다.

따라서 클라이언트 측 구현이 자동으로 처리됩니다! 우리 XSRF-TOKEN는 서버 측의 현재 도메인에 쿠키를 설정해야하며 API가 클라이언트에서 호출을 받으면 X-XSRF-TOKEN헤더 를 확인하고 쿠키 를 비교해야합니다.XSRF-TOKEN 하고 JWT에서 . 일치하면 사용자는 실제입니다. 그렇지 않으면 위조 된 요청이므로 무시해도됩니다. 이 방법은 "이중 제출 쿠키"방법에서 영감을 얻었습니다.

주의

실제로, 당신은 여전히 ​​XSS에 취약합니다. 공격자가 나중에 사용하기 위해 JWT 토큰을 훔칠 수는 없지만 XSS를 사용하여 사용자 대신 요청을 할 수 있습니다.

JWT를 저장하든 localStorageXSRF 토큰을 HttpOnly 쿠키가 아닌 곳에 저장하든 XSS를 통해 두 가지 모두 쉽게 잡을 수 있습니다. HttpOnly 쿠키의 JWT조차도 XST 방법 과 같은 고급 XSS 공격으로 잡을 수 있습니다 .

따라서 Double Submit Cookies 방법 외에도 이스케이프 컨텐츠를 포함하여 XSS에 대한 모범 사례를 항상 따라야합니다. 이것은 브라우저가 원하지 않는 일을하게하는 실행 코드를 제거하는 것을 의미합니다. 일반적으로 이는 // <![CDATA[JavaScript를 평가하게 하는 태그 및 HTML 속성을 제거하는 것을 의미 합니다.

더 많은 것을 읽으십시오 :


1
@AranDehkharghani 예, 특히 JWT를 변경하고 API에서 사용할 때마다 이전 JWT를 만료하면 재생 공격이 방지됩니다. 이는 JWT가 일회용 비밀번호 (OTP)와 같이된다는 것을 의미합니다. JWT는 플랫폼의 보안에 얼마나 관심이 있는지에 따라 다른 방식으로 사용할 수 있습니다.
Iman Sedighi

7
앞에서 언급했듯이 웹 사이트가 XSS에 취약한 경우 사용자가 악용되기까지는 시간 문제입니다. 아주 작은 보안 증가를 위해 상당한 복잡성을 거래하는 것 같습니다.
shusson

3
@shusson JWT를 보호하려면 XSS 및 XSRF 공격을 처리해야합니다. 나는 당신이 아주 작은 보안 증가를 위해 상당한 복잡성을 거래하고 있다는 것에 동의하지 않습니다. 보안이 중요한 경우 XSS 취약점이 발생하지 않도록 모든 노력을 기울여야합니다. 이 방법은 XSRF 공격으로부터 토큰을 보호하도록 설계되었습니다. 그러나 XSS 취약점을 무시할 수 있다는 의미는 아닙니다.
Iman Sedighi

5
@ImanSedighi 나는 jwt를 쿠키에 저장함으로써 복잡성을 추가하고 XSRF로부터 보호해야한다는 것이 확실하지 않았습니다. 그렇다면 수명이 짧은 토큰과 함께 로컬 스토리지를 사용하고 XSS 방지에 집중해야하는 이유는 무엇입니까?
shusson

2
@Royi Namir : $ 10 SSL 인증서를 사용하는 경우 Wireshark의 스푸핑은 문제가되지 않습니다! 웹 사이트의 보안이 중요한 경우 데이터를 암호화하고 HTTPS 프로토콜을 사용해야합니다.
Iman Sedighi

2

JWT를 저장하는 전체 문제에 대한 또 다른 각도 :

  1. JWT는 절대로 localStorage에 저장해서는 안됩니다
  2. 사실, 그들은 심지어 쿠키에 저장되지해야합니다 , 당신은 매우 엄격한 CSRF 보호를 구현할 수 있습니다하지 않는 한

동기 부여를 위해 이것을 확인하십시오

  • id_token으로서의 JWT는 사용자 자격 증명과 같습니다
  • access_token으로서의 JWT는 세션 토큰과 같습니다.

가장 안전한 옵션은 메모리 내 입니다. 심해 다이빙을 위해 이것을 확인하십시오

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.