reactjs를 사용하여 jWT를 localStorage에 저장하는 것이 안전합니까?


147

현재 reactjs를 사용하여 단일 페이지 응용 프로그램을 작성 중입니다. localStorage를 사용하지 않는 많은 이유는 XSS 취약점 때문이라고 읽었습니다. React가 모든 사용자 입력을 이스케이프하므로 이제 localStorage를 사용하는 것이 안전합니까?


4
세션 저장 선호
Praneet Rohida


3
"민감한 정보는 로컬 저장소에 저장하지 않는 것이 좋습니다." -OWASP "지속성없이 메모리에 저장"-Auth0
avejidah

제공된 링크에서 위의 인용문을 찾을 수 없기 때문에 Auth0의 관점이 변경되었을 수 있습니다.
DauleDK

답변:


141

대부분의 최신 단일 페이지 응용 프로그램에서는 실제로 클라이언트 쪽 어딘가에 토큰을 저장해야합니다 (가장 일반적인 사용 사례-페이지를 새로 고친 후 사용자 로그인 상태 유지).

웹 스토리지 (세션 스토리지, 로컬 스토리지) 및 클라이언트 측 쿠키의 총 2 가지 옵션이 있습니다. 두 옵션 모두 널리 사용되지만 이것이 매우 안전하다는 의미는 아닙니다.

Tom Abbott는 JWT sessionStorage 및 localStorage 보안을 잘 요약합니다 .

웹 스토리지 (localStorage / sessionStorage)는 동일한 도메인에서 JavaScript를 통해 액세스 할 수 있습니다. 즉, 귀하의 사이트에서 실행되는 모든 JavaScript는 웹 저장소에 액세스 할 수 있으며 이로 인해 수 있으며 사이트 간 스크립팅 (XSS) 공격에 취약 할 수 있습니다 . 간단히 말해서 XSS는 공격자가 페이지에서 실행될 JavaScript를 주입 할 수있는 취약점 유형입니다. 기본 XSS 공격은 양식 입력을 통해 JavaScript를 주입하려고 시도합니다. 여기서 공격자 <script>alert('You are Hacked');</script>는 양식을 브라우저에서 실행하고 다른 사용자가 볼 수 있는지 확인하기 위해 양식에 넣 습니다.

XSS를 방지하기 위해 일반적인 응답은 신뢰할 수없는 모든 데이터를 이스케이프하고 인코딩하는 것입니다. 반응은 (대부분) 당신을 위해 그것을합니다! 다음 은 React가 XSS 취약점 보호에 얼마나 책임이 있는지에 대한 훌륭한 토론입니다 .

그러나 모든 가능한 취약점을 다루지는 않습니다! 또 다른 잠재적 인 위협은 CDN 또는 외부 인프라에서 호스팅되는 JavaScript의 사용입니다 .

여기 Tom이 다시 있습니다 :

최신 웹 앱에는 A / B 테스트, 퍼널 / 시장 분석 및 광고를위한 타사 JavaScript 라이브러리가 포함됩니다. Bower와 같은 패키지 관리자를 사용하여 다른 사람의 코드를 앱으로 가져옵니다.

사용하는 스크립트 중 하나만 손상되면 어떻게됩니까? 페이지에 악성 JavaScript가 포함되어 웹 저장소가 손상되었습니다. 이러한 유형의 XSS 공격은 사용자 모르게 사이트를 방문하는 모든 사람의 웹 스토리지를 얻을 수 있습니다. 이것이 많은 조직이 가치있는 것을 저장하거나 웹 스토리지의 정보를 신뢰하지 말 것을 권유하는 이유 일 것입니다. 여기에는 세션 식별자와 토큰이 포함됩니다.

따라서 필자의 결론은 스토리지 메커니즘으로서 Web Storage 가 전송 중에 보안 표준을 시행하지 않는다는 것 입니다. Web Storage를 읽고 사용하는 사람은 항상 HTTP를 통해 HTTPS를 통해 JWT를 보내지 않도록 실사를 수행해야합니다.


10
내가 정확하게 이해하고 있다면 쿠키를 추천하십니까? 그냥 확인하십시오. 감사!
SuperLemon

7
예. 추가 보안 기능과 최신 웹 프레임 워크로 CSRF를 간단하게 보호 할 수 있기 때문에 쿠키를 권장합니다. 웹 스토리지 (localStorage / sessionStorage)는 XSS에 취약하고 공격 노출 영역이 더 넓으며 모든 애플리케이션 사용자가 성공적인 공격에 영향을 줄 수 있습니다.
Kaloyan Kosev

48
당신이 이것들을 섞은 것 같아요? 최신 웹 프레임 워크에는 XSS에 대한 강력한 방어 기능이 내장되어 있습니다. 그러나 xsrf에는 그리 많지 않습니다. xsrf에 대한 최선의 방어책은 쿠키를 완전히 사용하지 않는 것입니다. 로컬 스토리지는 특정 도메인으로 샌드 박스되어 있으므로 공격자 도메인이 액세스 할 수 없습니다. 웹 프레임 워크는 사용자 입력을 자동으로 인코딩하고 삭제하여 xss를 방어합니다. 참조 angular.io/guide/security
mikejones1477

47
"[대신] 쿠키를 추천하는 경우"라면 대답의 어딘가에 해당하는 것이 좋습니다. 의견이 아니라?
spechter

7
나는 여기에 조금 늦었고, 지금이 주제를 읽고 나는 한 가지에 대해 혼란스러워합니다. 많은 사람들이 Xss에 대해 비난을 받으면 http 전용 쿠키로 보호 받았지만 xss가 있다면 공격자는 당신을 아무것도 훔칠 필요가 없습니다. 그는 쿠키를 사용하여 자신을 도용하기 위해 페이지에서 간단하게 게시물을 작성하여 쿠키를 훔칠 수 있습니다. 뭔가 빠졌습니까 ???
Borja Alvarez

35

나는 이것이 오래된 질문이라는 것을 알고 있지만 @ mikejones1477이 말한 것처럼 현대 프론트 엔드 라이브러리 및 프레임 워크는 텍스트를 피하여 XSS로부터 보호합니다. 쿠키가 자격 증명을 사용하는 안전한 방법이 아닌 이유는 localStorage가 쿠키를 사용할 때 쿠키가 CSRF를 방해하지 않기 때문입니다 (또한 쿠키는 자바 스크립트로도 액세스 할 수 있으므로 XSS는 큰 문제가 아닙니다). 왜이 응답 이력서를 .

로컬 저장소에 인증 토큰을 저장하고 각 요청에 수동으로 추가하는 이유는 CSRF로부터 수동으로 보호하기 때문입니다. 브라우저가 자동으로 인증 토큰을 보내지 않기 때문에 evil.com을 방문하여 POST를 보내면 http://example.com/delete-my-account 수 없으므로 요청이 무시됩니다.

물론 httpOnly는 성배지만, reactjs 또는 js 프레임 워크에서 액세스 할 수 없습니다. 내 권장 사항은 로컬 스토리지이거나 쿠키를 사용하려면 django와 같은 CSRF 문제에 대한 솔루션을 구현해야합니다. .

CDN과 관련하여 Google 또는 부트 스트랩 제공과 같은 CDN이 커뮤니티에서 유지 관리하고 악성 코드가 포함되어 있지 않은 이상한 CDN을 사용하지 않는지 확인하십시오. 확실하지 않은 경우 자유롭게 검토 할 수 있습니다.


2
쿠키를 사용하는 동안 여전히 CSRF에 취약하다고 말할 이유가 확실하지 않습니다. 플래그와 쿠키를 사용 HttpOnly SameSite=strict하고 secure당신이 쿠키 안전에 설정된 정보를 유지합니다. 그런 다음 XSS에 대해 토큰 및 비밀번호와 같은 인증 관련 데이터를 JavaScript가 인식하지 못하도록합니다 (즉, 웹 저장소에 저장하지 않음). 악성 스크립트를 가져 오면 해당 스크립트에 액세스 할 수 없습니다 민감한 데이터에. 예, JS를 통해 토큰에 액세스 할 수는 없지만 실제로는 문제가되지 않습니다.
miphe

@miphe 그것이 내가 말한 것입니다. 그러나 OP는 자바 스크립트에서 액세스 할 수있는 방법을 요구하고 있습니다. 여기에서는 js에서 액세스 가능한 토큰을 저장하는 가장 좋은 방법이 무엇인지 설명하고 있습니다.
Mauricio Cortazar 1

21

기본적으로 JWT를 localStorage에 저장하는 것이 좋습니다.

그리고 이것이 좋은 방법이라고 생각합니다. CDN을 사용하는 XSS, XSS에 대해 이야기하는 경우 클라이언트의 로그인 / 패스를 얻을 수도 있습니다. 로컬 스토리지에 데이터를 저장하면 최소한 CSRF 공격이 방지됩니다.

둘 다 알고 있어야하며 원하는 것을 선택해야합니다. 두 가지 공격 모두 당신이 알고 있어야 할 필요는 없습니다. 기억하십시오. 모든 앱은 앱의 마지막 보안 지점에 대해서만 안전합니다.

다시 한 번 저장하면 OK, XSS, CSRF에 취약합니다.


2
이것이 다음을 수행하는 것이 안전한 이유입니다.-XWT에서 검색 할 수 없도록 JWT를 쿠키에 저장-CSRF에서 검색 할 수 없도록 localStorage에 CSRF 토큰을 저장하십시오.
Alejandro Cavazos

33
사이트가 악성 스크립트를 실행하는 경우 어쨌든 게임입니다. 키 다운 이벤트를 비밀번호 유형의 입력에 바인딩하고 사용자의 인증 정보를 도용 할 수 있습니다 (JWT 인증 토큰을 도용하는 것보다 훨씬 나쁩니다). localStorage에 JWT를 저장하면 XSS로 인한 엄청난 피해가 거의 증가하지 않습니다.
Carl Leth

8

CDN을 사용하면 안전하지 않습니다.

페이지에 악성 JavaScript가 포함되어 웹 저장소가 손상되었습니다. 이러한 유형의 XSS 공격은 사용자 모르게 사이트를 방문하는 모든 사람의 웹 스토리지를 얻을 수 있습니다. 이것이 많은 조직이 가치있는 것을 저장하거나 웹 스토리지의 정보를 신뢰하지 말 것을 권유하는 이유 일 것입니다. 여기에는 세션 식별자와 토큰이 포함됩니다.

폭풍 경로 를 통해

외부에서 필요한 스크립트는 잠재적으로 손상 될 수 있으며 클라이언트 스토리지에서 JWTS를 가져 와서 개인 데이터를 공격자의 서버로 다시 보낼 수 있습니다.


6
cdns를 사용할 계획이 없다면 안전할까요?

1
이 기사의 저자는 CDN을 통해 또는 중앙 서버에서 직접 제공되는 사이트에서 XSS를 구분하지 않았습니다. CDN뿐만 아니라 여기에 대한 설명도 일반적으로 적용되지 않습니까?
Vlad

5

로컬 저장소는 자바 스크립트로 액세스 할 수 있도록 설계되었으므로 XSS 보호 기능을 제공하지 않습니다. 다른 답변에서 언급했듯이 로컬 저장소가 기본적으로 보호되지 않는 XSS 공격을 수행하는 방법에는 여러 가지가 있습니다.

그러나 쿠키에는 XSS 및 CSRF 공격으로부터 보호하는 보안 플래그가 있습니다. HttpOnly 플래그는 클라이언트 측 자바 스크립트가 쿠키에 액세스하는 것을 방지하고, Secure 플래그는 브라우저가 ssl을 통해 쿠키를 전송할 수 있도록하며, SameSite 플래그는 쿠키가 원본으로 만 전송되도록합니다. 방금 확인했지만 SameSite는 현재 Opera와 Chrome에서만 지원되므로 CSRF로부터 보호하려면 다른 전략을 사용하는 것이 좋습니다. 예를 들어, 일부 공용 사용자 데이터와 함께 다른 쿠키에 암호화 된 토큰을 보냅니다.

따라서 쿠키는 인증 데이터를 저장하기위한보다 안전한 선택입니다.


얻을 수 : 어떻게 HttpOnly가 CSRF로부터 당신을 보호 할 수 있습니까?
Alex Lyalka

@AlexLyalka HttpOnly가 모든 쿠키 플래그를 함께 XSS 및 CSRF로부터 보호 할 수있는 것보다 CSRF를 막는 것은 아닙니다. SameSite는 쿠키가 출처가 아닌 다른 사이트로 전송되지 않도록 보호합니다. 방금 확인했지만 해당 플래그에 대한 지원이 매우 낮습니다. 서버에서 확인되는 일부 사용자 식별 기능이있는 별도의 암호화 된 토큰으로 CSRF를 피할 수도 있습니다.
Ivan

1
글쎄, 누군가 웹에서 코드를 실행할 수 있다면, 단순히 사용자 이름으로 웹에 글을 올릴 수 없습니까? 좋아, 그는 당신의 http 전용 쿠키를 얻을 수 없지만, 그는 그 쿠키를 사용하여 전화를 걸 수 있습니다, 그래서 나는 여전히 요점을 볼 수 없습니다
Borja Alvarez

2
@BorjaAlverez 큰 차이가 있습니다. 예, XSS를 통해 누군가 로그인 한 사용자 대신 요청을 할 수 있지만 토큰을 손상시키는 것은 더 나쁩니다. 예를 들어, 토큰은 클라이언트 애플리케이션이 사용하지 않는 API에 대한 액세스를 제공 할 수 있습니다. 토큰은 사용자에 대한 다른 정보 (이메일 주소, 프로필 및 보조금)를 가질 수 있습니다. 토큰은 애플리케이션에 대한 재생 공격에 사용될 수 있습니다. 토큰은 id_token_hintOIDC 인증 서버 로 전달 될 수 있습니다 . 토큰은 공격자에게 서명에 사용 된 암호에 대한 정보를 제공합니다. 등
avejidah

3

이것을 보는 방법은 위험 수준이나 위험 수준을 고려하는 것입니다.

POC / MVP 사용자가없는 앱을 만들고 있습니까? 앱을 빠르게 출시하고 테스트해야하는 스타트 업입니까? 그렇다면 아마도 가장 간단한 솔루션을 구현하고 제품 시장 적합성을 찾는 데 집중할 것입니다. localStorage를 구현하기 더 쉬운 것으로 사용하십시오.

많은 일일 활성 사용자 또는 사람 / 비즈니스가 크게 의존하는 앱으로 v2 앱을 빌드하고 있습니까? 해킹당하는 것이 회복의 여지가 거의 없습니까? 그렇다면 귀하의 종속성을 오랫동안 열심히 살펴보고 토큰 정보를 http 전용 쿠키에 저장하는 것을 고려하십시오.

localStorage와 쿠키 / 세션 저장소를 모두 사용하면 장단점이 있습니다.

첫 번째 답변에서 언급했듯이 : 응용 프로그램에 XSS 취약점이있는 경우 사용자를 보호하지 못합니다. 대부분의 최신 응용 프로그램에는 수십 가지 이상의 다른 종속성이 있으므로 응용 프로그램의 종속성 중 하나가 XSS에 취약하지 않다는 것을 보장하기가 점점 어려워집니다.

응용 프로그램에 XSS 취약점이 있고 해커가이를 악용 할 수있는 경우 해커는 사용자를 대신하여 작업을 수행 할 수 있습니다. 해커는 localStorage에서 토큰을 검색하여 GET / POST 요청을 수행하거나 토큰이 http 전용 쿠키에 저장된 경우 POST 요청을 수행 할 수 있습니다.

로컬 저장소에 토큰을 저장하는 유일한 단점은 해커가 토큰을 읽을 수 있다는 것입니다.


1

localStorage 또는 httpOnly 쿠키가 허용되지 않습니까? 손상된 타사 라이브러리와 관련하여 중요한 정보의 도난을 줄이거 나 방지 할 수있는 유일한 솔루션은 Subresource Integrity 입니다.

SRI (Subresource Integrity)는 브라우저가 가져 오는 리소스 (예 : CDN에서)가 예기치 않은 조작없이 제공되는지 확인할 수있는 보안 기능입니다. 가져온 리소스가 일치해야하는 암호화 해시를 제공 할 수 있습니다.

손상된 제 3 자 라이브러리가 웹 사이트에서 활성화되어 있으면 키 로거는 사용자 이름, 비밀번호 및 사이트에 입력 한 다른 정보를 수집하기 시작할 수 있습니다.

httpOnly 쿠키는 다른 컴퓨터의 액세스를 차단하지만 해커가 사용자의 컴퓨터를 조작하는 것을 막기위한 조치는 없습니다.


-10

암호화하는 한 토큰을 localStorage에 저장하는 것이 안전합니다. 다음은 여러 가지 방법 중 하나를 보여주는 압축 된 코드 스 니펫입니다.

    import SimpleCrypto from 'simple-crypto-js';

    const saveToken = (token = '') => {
          const encryptInit = new SimpleCrypto('PRIVATE_KEY_STORED_IN_ENV_FILE');
          const encryptedToken = encryptInit.encrypt(token);

          localStorage.setItem('token', encryptedToken);
     }

그런 다음 토큰을 사용하기 전에 PRIVATE_KEY_STORED_IN_ENV_FILE


@HassanAlthaf 당신이 여기서 요점을 놓치면 100 % 안전한 증거 앱이 절대 없을 것입니다. 단지, 공격 표면을 줄이고 적어도 env 파일은 github에 직접 게시되지 않습니다. 또한 번들로 제공되는 코드는 난독 처리되고 엉망이되어 공격자가 찾기가 어렵습니다.
Kidali Kevin

개인 키는 노출되지 않아야합니다. 전체 API를 손상시킵니다.
Hassan Althaf 12''2012-12-03

내 경험에서 지능적이고 올바르게 작업을 수행하면 프로덕션 키에 개인 키가 노출되지 않으며이 경우 URL을 지원하는 스크린 샷이 표시됩니다.
Kidali Kevin
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.