ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Web] 로그인을 안전하게 처리하기 ( JWT, refresh Token, access Token )
    CS/Web 2023. 1. 31. 19:34

    참고: velog@yaymato

     

    JWT를 통한 로그인 처리 방식

    1. JWT를 쓴다.
    2. refresh Token은 secure httpOnly 쿠키로, access Token은 JSON payload로 전달받는다. 
    3. Web Application이 mount 될 때마다 refresh Token을 이용해 새로운 access Token을 받아와 Web 내 지역 변수에 저장하고 사용한다. (access Token이 만료될때마다) 
    4. 이러한 로그인 처리 방식은 다른 선택지들보다 XSS공격에 안전함. (완전 무결한건 X) 

    JWT 용도

    Authorization(권한부여)

    • JSON Web Token을 사용하는 가장 일반적인 시나리오로, 사용자가 로그인하면 이후의 각 요청에서는 JWT가 포함되어 사용자가 해당 토큰으로 허용되는 패스, 서비스 및 리소스에 액세스할 수 있다. Single Sign On은 오버헤드가 적고 여러 도메인에서 쉽게 사용할 수 있기 때문에 오늘날 JWT를 널리 사용하는 기능이다.

    Information Exchange(정보교환)

    • JSON 웹 토큰은 당사자 간에 정보를 안전하게 전송할 수 있는 좋은 방법이다. 예를 들어 공용/개인 키 쌍을 사용하여 JWT에 서명할 수 있기 때문에 발신인이 자신이 말하는 사용자임을 확인할 수 있다. 또한 서명이 헤더와 페이로드를 사용하여 계산되므로 콘텐츠가 변조되지 않았는지(무결성) 확인할 수도 있다.

    컨텐츠 순서

    1. 로그인 인증 방식 
    2. 보안은 어떻게 뚫리나?
    3. 브라우저 저장소 종류와 보안 이슈
    4. 해커 대처법은? 

    1. 로그인 인증 방식 (어떻게 이루어지나)

    • 세션 id를 이용하는 방식 (서버가 특정 유저의 정보를 담은 세션을 생성함)
      • 유저가 로그인 시도
      • (유저 정보 확인되면) 서버는 세션을 생성
      • 해당 세션의 id를 유저에게 보내줌
      • 유저는 이 id를 저장해놨다가 이 후 서버와의 접촉시 요청과 함께 id 값을 보내줌
      • 서버는 해당 id를 통해 세션을 불러와 유효한지 확인하는 방식으로 인증

    • JWT를 이용하는 방식( refresh Token, access Token) 
      • {세션 id 이용하는 방식과 큰 틀은 비슷함}
      • 유저가 로그인을 시도
      • 서버가 암호화나 시그니처 추가가 가능한 데이터 패키지 안에 인증 정보를 보내줌 (이 패키지가 JWT)
      • 담긴 정보 에는 access Token과 refresh Token이 존재 (이후 유저 인증시 필요)
      • 실질적인 정보는 access Token, 로그인을 지속적으로 유지할 지 결정하는 refresh Token
      • JWT 의 구조
    // {header BASE64エンコード}.{JSON Claim set BASE64エンコード}.{signature BASE64エンコード}
    
    {"alg":"RS256","typ":"JWT"} //header 알고리즘과 타입
    
    { //payload 유저정보 
      "iss":"ZbsOq6zjt0IhtZZnrc", //앱 클라이언트 id
      "sub":"1wagx.serviceaccount@example.com", //서비스 계정 id
      "iat":1634711358, // JWT 생성 일시, 유닉스 타입 (sec 단위)
      "exp":1634714958  // JWT 만료 일시
    } 
    //위의 payload를 BASE 64로 인코딩 하면 아래와 같음
    // eyJpc3MiOiJhYmNkIiwic3ViIjoiNDZjNGYyODFmODExNDhjOWI4NDZjNTkyNjJhZTU4ODhAZXhhbXBsZS5jb20iLCJpYXQiOjE2MzQ3MTEzNTgsImV4cCI6MTYzNDcxNDk1OH0
    
    //signature (JWS 약관에 준수해 JWT 헤더와body의 byte array를 RSASHA-256알고리즘으로 암호화 하고 BASE64로 인코딩 )
    // RqOaErJWZc_ZGijL5r0a892NnQL_zbkgchThW3j4pzG_qMqtOgex2odEs8JFsPfQ2c8_2BkaUMckNIN3C27t2RsbppJYl3nQr9w2Jb6x9LJR1Ym3pJVlpRvarracRwa00OgVc0mZ5dkn3B4I55GpKjZ3oOLfW7Xw0OAj8fEYCmWJmma3xQQrScJAUqN-jTZ7T3C6-ieVo3IhTRopzS5cru3ilQWekQ6-fRTPr8W4EV9B0u8wXhCxT90mlAYtebPvyovpPTNhi8Oq8rO_gVnpSMNkDtZ6p6OpC7_XG7ZcjUo7KRCxyPLe2-TmeWtV0jL5vqsjnlAznKtw5mPGOwpjVQ

    2. 보안은 어떻게 꿇리나? ( XSS, CSRF) 

    • XSS 공격 
      • 해커가 유저 브라우저에 JS를 삽입해 실행하는 공격
        • <input> 태그를 서버에 전송해 스크립트를 실행하거나
        • URL에 js를 적어 클라이언트에서 스크립트 실행이 가능하면 해커가 사이트에 스크립트 삽입해 공격
        • 이때 해커는 js를 통해 사이트의 전역 변수 값을 가져오거나 그 값으로 사이트인척 API콜을 요청함
    • CSRF 공격
      • 해커가 다른 사이트에서 우리 사이트의 API 콜을 요청해 실행하는 공격
      • API 콜을 요청할 수 있는 클라이언트 도메인이 누구인지 통제하지 않는다면 맞게 되는 공격
      • eg) CSRF 공격에 취약한 은행 사이트가 있다면 로그인한 척 계좌 비번을 바꾸거나 송금 가능하게 함
    • 위에서 언급한 로그인 처리 방식들은 session ID와 access Token같은 인증 정보를 보통 localStorage나 쿠키에 저장함. 이것은 페이지 새로고침이나 재접속시에도 로그인 정보 유지를 위한 브라우저에 저장하는 방식인데 이것은 보안에 취약 (XSS, CSRF공격에 노출)

    3. 브라우저 저장소 종류와 보안 이슈

    • localStorage 저장 방식, 쿠키 저장 방식, secure httpOnly 쿠키

    1. localStorage 저장 방식

    • 브라우저 저장소에 저장하는 방식
    • JS내 전역 변수로 reading / writing 접근 가능
    • localStorage 안에 세션 id, refreshToken 또는 accessToken을 저장해두면 XSS 취약점을 통해 그 안에 담긴 값을 불러오거나, 불러온 값을 이용해 API 콜을 위조할 수 있다.

    2. 쿠키 저장 방식

    • 브라우저에 쿠키로 저장하는 방식
    • 유저가 HTTP 요청을 보낼 때마다 자동으로 쿠키가 서버에 같이 전송됨
    • JS 내 전역 변수로 reading / writing 접근 가능
    • 쿠키 저장 방식 역시 안에 세션 id, refreshToken, accessToken을 저장해두면 XSS 취약점이 있을 때 담긴 값들을 불러오거나, API 콜을 보내면 쿠키에 담긴 값들이 함께 전송되어 로그인한 척 공격을 수행할 수 있다.
    • 쿠키에 세션 id나 accessToken을 저장해 인증에 이용하는 구조에 CSRF 취약점이 있다면 인증 정보가 쿠키에 담겨 서버로 보내진다. 공격자는 유저 권한으로 정보를 가져오거나 액션을 수행할 수 있다.
    • (취약점 보완) 쿠키에 refreshToken만 저장하고 새로운 accessToken을 받아와 인증에 이용하는 구조에서는 CSRF 취약점 공격을 방어할 수 있다. refreshToken으로 accessToken을 받아도 accessToken을 스크립트에 삽입할 수 없다면 accessToken을 사용해 유저 정보를 가져올 수 없기 때문이다.

    3. secure httpOnly 쿠키 저장 방식

    • 브라우저에 쿠키로 저장되는 것 같지만, JS 내에서 접근이 불가능.
    • secure를 적용하면 https 접속에서만 동작함. 
    • httpOnly 쿠키 방식으로 저장된 정보는 XSS 취약점 공격으로 담긴 값을 불러올 수 없다.
    • httpOnly 쿠키 역시 refreshToken만 저장하고 accessToken을 받아와 인증에 이용하는 구조로 CSRF 공격 방어가 가능하다.
    • 쿠키 저장 방식과 같은 이유로 세션 id, accessToken은 저장하면 안 된다.
    • httpOnly 쿠키에 담긴 값에 접근할 수는 없지만 XSS 취약점을 노려 API 콜을 요청하면 httpOnly 쿠키에 담긴 값들도 함께 보내져 유저인 척 정보를 빼오거나 액션을 수행할 수 있다.

    ==>> 어떤 방식을 택해도 XSS 취약점이 있다면 보안 이슈가 존재함. 유저 정보 저장 방식만으로는 방어력을 키울순 없어서, 클라이언트와 서버에서 추가적으로 XSS 방어 처리가 필수

     

    4. 그래서?

    종합해보면 세션 id를 브라우저에 저장하는 방식은 어떤 방식이던지 보안 위험요소가 있으므로 JWT 이용한 인증 방식을 사용할 것이다. 

    refreshToken만을 secure httpOnly 쿠키에 저장해 CSRF 공격을 방어할 것이다. 

    accessToken은 웹 어플리케이션 내 로컬 변수에 저장해 사용하며, API를 요청할 때 Authorization 헤더에 넣어 보내준다.

    XSS 취약점을 이용한 API 요청 공격은 클라이언트와 서버에서 추가적으로 방어 해야 한다.

     

    'CS > Web' 카테고리의 다른 글

    [Web] HTTP 상태 코드 정리  (0) 2023.02.11
    [Web] JWT와 OAuth에 대한건 여기로!  (0) 2023.02.01
    [Web] 로그인 인증 4가지 방법  (0) 2023.01.30
    [Web] OAuth 리다이렉션 URI란?  (0) 2023.01.26
    [Web] 웹 서비스 구성 요소  (0) 2023.01.09
Designed by Tistory.