programing

JWT를 ReactJs와 함께 localStorage에 저장해도 안전합니까?

nicescript 2022. 9. 21. 22:19
반응형

JWT를 ReactJs와 함께 localStorage에 저장해도 안전합니까?

저는 현재 ReactJs를 사용하여 한 페이지 어플리케이션을 만들고 있습니다.

제가 읽은 바로는 이 제품을 사용하지 않는 이유 중 하나는localStorageXSS의 취약성 때문입니다.

React는 모든 사용자 입력을 무시하므로 이제 사용해도 안전할까요?localStorage?

현대의 대부분의 단일 페이지 애플리케이션에서는 토큰을 클라이언트 측 어딘가에 저장해야 합니다(가장 일반적인 사용 사례 - 페이지를 새로 고친 후에도 사용자가 로그인한 상태로 유지).

총 2가지 옵션을 사용할 수 있습니다.웹 스토리지(세션 스토리지, 로컬 스토리지) 및 클라이언트 측 쿠키.두 옵션 모두 널리 사용되지만, 그렇다고 해서 매우 안전한 것은 아닙니다.

Tom Abbott은 JWT sessionStoragelocalStorage 보안을 잘 요약합니다.

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

XSS를 방지하기 위해 일반적인 응답은 모든 신뢰할 수 없는 데이터를 이스케이프하여 부호화하는 것입니다.(대부분의) 리액션으로 해 주세요!다음은 XSS 취약성 보호의 책임 정도에 대한 훌륭한 설명입니다.

그렇다고 모든 취약성을 커버하는 것은 아닙니다.또 다른 잠재적인 위협으로는 CDN 또는 외부 인프라스트럭처에서 호스트되는 JavaScript를 사용하는 것입니다.

톰이 또 왔다.

최신 웹 앱에는 A/B 테스트용 서드파티 JavaScript 라이브러리, 깔때기/시장 분석 및 광고가 포함됩니다.Bower와 같은 패키지 매니저를 사용하여 다른 사람의 코드를 앱에 Import합니다.

사용하는 스크립트 중 하나만 손상된 경우에는 어떻게 해야 합니까?페이지에 악의적인 JavaScript가 포함되어 웹 스토리지가 손상될 수 있습니다.이러한 유형의 XSS 공격은 사용자 사이트를 방문하는 모든 사용자의 웹 스토리지를 자신도 모르게 손상시킬 수 있습니다.이러한 이유로 많은 조직이 웹 스토리지에 가치 있는 정보를 저장하거나 신뢰하지 않도록 권장하고 있습니다.여기에는 세션 ID 및 토큰이 포함됩니다.

따라서 스토리지 메커니즘으로서 Web Storage는 전송 중에 보안 표준을 적용하지 않습니다.Web Storage를 읽고 사용하는 사용자는 항상 HTTP를 사용하지 않고 HTTPS를 통해 JWT를 전송하기 위해 충분한 조사를 수행해야 합니다.

기본적으로 JWT를 localStorage에 저장할 수 있습니다.

그리고 나는 이것이 좋은 방법이라고 생각한다.XSS, CDN을 사용하는 XSS에 대해 이야기하면 고객의 로그인/패스 취득 위험도 있습니다.로컬 스토리지에 데이터를 저장하면 CSRF 공격을 최소한 방지할 수 있습니다.

둘 다 잘 알고 원하는 것을 골라야 합니다.두 공격 모두 알아야 하는 것은 아닙니다. 앱 전체의 보안은 앱의 가장 낮은 보안 지점에서만 가능합니다.

다시 한 번 저장해도 문제가 없습니다.XSS, CSRF 등에 취약해집니다.

오래된 질문인 것은 알지만 @mikejones1477의 말에 따르면 현대의 프런트 엔드 라이브러리와 프레임워크는 텍스트에서 벗어나 XSS로부터 보호합니다.cookie가 credential을 사용하는 안전한 방법이 아닌 이유는 cookie가 localStorage를 사용할 때 CSRF를 차단하지 않기 때문입니다(또한 JavaScript에서도 쿠키에 액세스할 수 있으므로 XSS는 큰 문제가 되지 않습니다). 이 답변이 재개됩니다.

인증 토큰을 로컬스토리지에 저장하고 각 요구에 수동으로 추가하여 CSRF로부터 보호하는 이유는 키워드: manual입니다.브라우저가 자동으로 인증 토큰을 전송하지 않기 때문에evil.examplePOST를 송신할 수 있습니다.http://example.com/delete-my-accountauthn 토큰을 전송할 수 없기 때문에 요청은 무시됩니다.

물론 httpOnly는 성배이지만 reactjs 또는 옆에 있는 js 프레임워크에서 액세스할 수 없습니다.여전히 CSRF 취약성이 있습니다.권장되는 것은 로컬 스토리지입니다.또한 쿠키를 사용하는 경우에는 반드시 Django와 같이 CSRF 문제에 대한 해결책을 제시해 주십시오.

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

XSS 공격이나 악의적인 라이브러리의 영향을 받기 쉽기 때문에 로컬 스토리지에 저장하지 않는 것이 좋습니다.이 중 일부는 장황한 논의에 들어가기도 합니다. 답은 매우 작습니다. 잠시 후에 설명하겠습니다.

그것은 "어느 날 밤 술에 취해 튀기기로 결심하면 결국 자신과 집을 태울 것이기 때문에 프라이팬을 사용하여 음식을 요리하지 말라"는 것과 같다.XSS 공격 또는 악성 라이브러리로 인해 jwt가 유출되면 사이트 소유자는 더 큰 문제를 겪게 됩니다.즉, 사이트가 XSS 공격에 취약하거나 악성 라이브러리를 사용하고 있다는 것입니다.

정답: 사이트에는 이러한 취약성이 없다고 확신하는 경우 시도해 보십시오.

참고 자료: https://auth0.com/docs/security/data-security/token-storage#browser-local-storage-scenarios

이를 보는 한 가지 방법은 위험이나 위해의 정도를 고려하는 것입니다.

사용자가 없는 앱을 만들고 있습니까, POC/MVP? 시장에 진출하여 앱을 빠르게 테스트해야 하는 스타트업입니까?만약 그렇다면, 저는 가장 단순한 솔루션을 구현하고 제품 시장에 적합한 제품을 찾는 데 주력할 것입니다.localStorage를 구현하기 쉬운 경우가 많습니다.

일일 활성 사용자가 많은 앱의 v2를 구축하고 있습니까? 아니면 개인/비즈니스 의존도가 높은 앱을 구축하고 있습니까?해킹을 당한다는 것은 회복의 여지가 적거나 전혀 없다는 것을 의미합니까?그렇다면 귀사의 의존관계를 자세히 살펴보고 토큰 정보를 http 전용 쿠키에 저장하는 것을 검토하겠습니다.

local Storage와 cookie/session 스토리지 모두 사용 시 장단점이 있습니다.

첫 번째 답변에 따르면:응용 프로그램에 XSS 취약성이 있는 경우 둘 다 사용자를 보호하지 않습니다.이후로 대부분의 현대 응용 프로그램 수십개의 더 다양한 종속 관계가 있는 것이 점점 더 한 사람이 응용 프로그램의 의존성의 교차 사이트 스크립팅 취약하지는 않다 보장하기 힘들어 진다.

만약 당신의 애플리케이션과 해커가 그것을 이용할 수 있어 온 사이트 간 스크립팅 취약점을 가지고 있나, 해커가 당신의 사용자를 대신하여 작업을 수행할 수 있을 것이다.해커 localStorage에서 토큰을 검색하여 또는 토큰은http-only 쿠키에 저장됩니다 POST 요청을 수행할 수 있GET/POST 요청을 수행할 수 있다

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

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

페이지에 악의적인 JavaScript가 포함되어 웹 스토리지가 손상될 수 있습니다.이러한 유형의 XSS 공격은 사용자 사이트를 방문하는 모든 사용자의 웹 스토리지를 자신도 모르게 손상시킬 수 있습니다.이러한 이유로 많은 조직이 웹 스토리지에 가치 있는 정보를 저장하거나 신뢰하지 않도록 권장하고 있습니다.여기에는 세션 ID 및 토큰이 포함됩니다.

스톰 패스를 경유하여

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

로컬 스토리지는 javascript로 접근할 수 있도록 설계되어 있기 때문에 XSS 보호를 제공하지 않습니다.다른 답변에서 언급했듯이 XSS 공격을 수행할 수 있는 방법은 여러 가지가 있습니다.이 공격으로부터 로컬 스토리지는 기본적으로 보호되지 않습니다.

단, 쿠키에는 XSS 및 CSRF 공격으로부터 보호하는 보안 플래그가 있습니다.Http Only 플래그는 클라이언트 측 javascript의 쿠키 접근을 차단하고 Secure 플래그는 브라우저가 ssl을 통한 쿠키 전송만 허용하며 SameSite 플래그는 쿠키가 오리진에만 전송되도록 합니다.확인해보니 Same Site는 현재 Opera와 Chrome에서만 지원되므로 CSRF로부터 보호하기 위해서는 다른 전략을 사용하는 것이 좋습니다.예를 들어, 일부 공용 사용자 데이터와 함께 다른 쿠키에 암호화된 토큰을 보내는 것입니다.

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

주의할 점은 JWT가 다음 중 어느 쪽인지 여부입니다.

  • 퍼스트 파티(즉, 단순히 자신의 서버 명령에 액세스하기 위한 것)
  • 서드파티(Google, Facebook, Twitter 등용 JWT)

JWT가 퍼스트 파티인 경우:

그러면 JWT를 로컬 스토리지에 저장하든 보안 쿠키(즉, 보안 쿠키)에 저장하든 크게 문제가 되지 않습니다. HttpOnly,SameSite=strict,그리고.secure) [사이트가 이미 HTTPS를 사용하고 있는 것을 전제로 하고 있습니다.이것이 필수입니다.

이는 XSS 공격이 성공했다고 가정할 때(즉, 공격자가 현재 모든 방문자 브라우저에서 실행되고 있는 JS 종속성을 통해 Javascript 코드를 삽입할 수 있었다고 가정할 때) 어쨌든 "게임 오버"이기 때문입니다. "JWT 토큰 검증"에 의해 보호되는 모든 명령어는 이제 스크립트가 있는 것만으로 공격자가 실행할 수 있습니다.프런트 엔드 JS 콜에 접속되어 있습니다.JWT 토큰 자체는 읽을 수 없지만(쿠키의 http 전용 플래그 때문에), 필요한 명령어를 모두 전송할 수 있기 때문에 브라우저는 JWT 토큰을 해당 명령어와 함께 즐겁게 보낼 수 있습니다.

XSS 공격 상황은 (로컬 스토리지든 시큐어 쿠키든) 어느 쪽이든 거의 "게임 오버"이지만 공격자가 공격을 실행할 수 있는 것은 사용자가 브라우저에서 웹 사이트를 열었을 때뿐이기 때문에 쿠키는 여전히 조금 더 낫습니다.

이것에 의해, 공격자에게 다음과 같은 「어노이언스」가 발생합니다.

  1. XSS 주입은 성공했습니다.좋아, 내 상사에 대한 사적인 정보를 수집해서 공갈 협박으로 사용할 시간이야.젠장!그는 내가 여기 일하러 있을 때만 로그인을 한다.모든 코드를 미리 준비해서 3분 안에 실행해야 합니다.플랫폼의 데이터를 천천히 탐색하는 것이 아니라."
  2. XSS 주입은 성공했습니다.이제 코드를 변경하여 모든 Bitcoin 송금을 대신 보낼 수 있습니다!특별히 염두에 둔 대상이 없기 때문에 누군가를 기다릴 필요는 없습니다.그래도 JWT 토큰 자체에 접근할 수 있으면 좋겠어요.그렇게 하면 묵묵히 모든 사람의 지갑을 한꺼번에 비울 수 있어요.쿠키로 보호되는 JWT를 사용하면 개발자들이 전송을 중단하기 전에 수십 명의 방문자만 납치할 수 있습니다.."
  3. XSS 주입은 성공했습니다.이렇게 하면 관리자만 볼 수 있는 데이터에도 액세스할 수 있습니다.음, 아쉽게도 사용자 브라우저를 통해 모든 작업을 수행해야 합니다.이 3GB 파일을 다운로드 할 수 있는 현실적인 방법이 있는지 잘 모르겠습니다.다운로드를 시작했는데 메모리 문제가 있어서 사용자는 항상 완료 전에 사이트를 닫습니다.또, 이 사이즈의 클라이언트측의 재발송신도 누군가에게 검출되지 않을까 염려됩니다.

JWT가 서드파티인 경우:

이 경우 제3자 JWT가 보유자에게 무엇을 허용하느냐에 따라 달라집니다.

각 사용자의 '기본 프로파일 정보'에 대한 접근만 허용하면 공격자가 접근할 수 있는 경우에도 문제가 되지 않습니다.일부 이메일은 유출될 수 있습니다.그러나 공격자는 사용자의 '계정 페이지'로 이동하여 해당 데이터가 UI에 표시되므로 해당 정보를 얻을 수 있습니다(JWT 토큰을 사용하면 T에 기재된 '유예'를 피할 수 있습니다).이전 섹션)

대신 타사 JWT를 통해 클라우드 스토리지 데이터에 대한 전체 액세스, 타사 플랫폼에서의 메시지 전송, 타사 플랫폼에서의 개인 메시지 읽기 등 보다 실질적인 작업을 수행할 수 있다면 JWT에 대한 접근은 단순히 "인증된 명령어 전송"보다 훨씬 더 어렵습니다.

이는 공격자가 실제 JWT에 액세스할 수 없는 경우 모든 명령을 타사 서버를 통해 라우팅해야 하기 때문입니다.여기에는 다음과 같은 이점이 있습니다.

  1. 제한된 명령어:모든 명령어가 서버를 통과하기 때문에 공격자는 서버가 처리하도록 작성된 명령어 서브셋만 실행할 수 있습니다.예를 들어, 서버가 사용자의 클라우드 스토리지에 있는 특정 폴더에서만 읽기/쓰기하는 경우, 공격자 역시 동일한 제한이 있습니다.

  2. 검출의 용이성:모든 명령어가 서버를 통과하기 때문에 (로그, 명령어 급상승 등을 통해) 누군가가 XSS 공격을 하고 있음을 알 수 있습니다.이를 통해 패치를 더 빠르게 적용할 수 있습니다.(JWT가 있는 경우 서버에 연락할 필요 없이 서드파티 플랫폼에 사일런트 콜을 발신할 수 있습니다.)

  3. 공격자를 식별하는 더 많은 방법: 명령어는 서버를 통과하기 때문에 명령어가 작성되는 시기와 작성에 사용되는 ip-address를 정확하게 알 수 있습니다.경우에 따라서는 누가 공격을 하고 있는지를 식별하는 데 도움이 될 수 있습니다.IP 주소가 가장 확실한 방법이지만 XSS 공격을 할 수 있는 대부분의 공격자는 프록시를 사용할 수 있습니다.

    보다 고도의 식별 접근방식은 예를 들어 공격자가 (자신의 계정에서 웹 사이트를 로드할 때) 해당 메시지를 보고 이를 기반으로 새 명령을 실행하도록 각 사용자에 대해 고유한(또는 적어도 버킷으로 분할된) 특별한 메시지를 팝업하는 것입니다.예를 들어 소개한 '새로운 API'에 대해 말하는 '가짜 개발자 블로그 게시물'에 링크할 수 있습니다.사용자가 블로그 게시물을 볼 때 해당 '새로운 API'의 URL이 사용자별로 다르기 때문에 (피해자에게) API를 사용하려고 하면 exac를 알 수 있습니다.누가 그랬는지 알아?물론 이는 공격자가 피해자와 함께 사이트에 "실제 계정"을 가지고 있다는 생각에 의존하며, 이러한 접근법에 의해 유혹되거나 속아넘어갈 수 있다는 생각(예: 공격자가 자신을 추적하고 있다는 것을 알고 있으면 효과가 없습니다)에 의존하지만 인증된 모든 명령을 가로챌 수 있을 때 수행할 수 있는 작업의 예입니다.

  4. More flexible controlling: Lets say that you've just discovered that someone deployed an XSS attack on your site.

    If the attackers have the 3rd-party JWTs themselves, your options are limited: you have to globally disable/reset your OAuth/JWT configuration for all 3rd-party platforms. This causes serious disruption while you try to figure out the source of the XSS attack, as no one is able to access anything from those 3rd-party platforms. (including your own server, since the JWT tokens it may have stored are now invalid)

    If the JWT tokens are instead protected in http-only cookies, you have more options: You can simply modify your server to "filter out" any reads/writes that are potentially dangerous. In some cases added this "filtering" is a quick and easy process, allowing your site to continue in "read-only"/"limited" mode without disrupting everything; in other cases, things may be complex enough that it's not worth trusting the filter code for security. The point though is that you have more options.

    For example, maybe you don't know for sure that someone has deployed an XSS attack, but you suspect it. In this case, you may not want to invalidate the JWT tokens of every user (including those your server is using in the background) simply on the suspicion of an XSS attack (it depends on your suspicion level). Instead, you can just "make things read-only for a while" while you look into the issue more closely. If it turns out nothing is wrong, you can just flip a switch and re-enable writes, without everyone having to log back in and such.

Anyway, because of these four benefits, I've decided to always store third-party JWTs in "secured cookies" rather than local storage. While currently the third-party JWTs have very limited scopes (such that it's not so big a deal if they are stolen), it's good future-proofing to do this, in case I'd like my app to request access to more privileged functionalities in the future (eg. access to the user's cloud storage).

Note: The four benefits above (for storing third-party JWTs in secured cookies) may also partially apply for first-party JWTs, if the JWTs are used as authentication by multiple backend services, and the domains/ip-addresses of these other servers/services are public knowledge. In this case, they are "equivalent to third-party platforms", in the sense that "http-only cookies" restrict the XSS attacker from sending direct commands to those other servers, bringing part of the benefits of the four points above. (it's not exactly the same, since you do at least control those other servers, so you can activate read-only mode for them and such -- but it'll still generally be more work than making those changes in just one place)

localStorage와 httpOnly cookie 모두 허용되지 않습니까?침해된 서드파티 라이브러리의 경우 중요한 정보의 도난을 줄이거나 방지할 수 있는 유일한 솔루션은 강제적인 서브리소스 무결성입니다.

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

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

httpOnly 쿠키는 다른 컴퓨터로부터의 액세스를 금지하지만 해커가 사용자의 컴퓨터를 조작하는 것을 막지는 않습니다.

TLDR;

둘 다 가능하지만 쿠키를 httpOnly와 함께 사용하는 것이 로컬 스토리지를 사용하는 것보다 훨씬 안전합니다. XSS에 의해 도입된 악성 자바스크립트 코드는 로컬 스토리지를 읽을 수 있기 때문입니다.

토큰을 암호화하는 한 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

언급URL : https://stackoverflow.com/questions/44133536/is-it-safe-to-store-a-jwt-in-localstorage-with-reactjs

반응형