ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • jwt에 대한 고찰..
    개발/개발지식 2023. 1. 18. 20:40

    1.일반적인 로그인 프로세스

    일단 로그인 프로세스를 알아야 이해할 수 있다.

     

    일반적인 로그인 프로세스는 클라이언트에서 아이디와 비밀번호를 입력 받으면

    그에 대해서 인증(Authentication) 과정을 거친다.

    말하자면 DB에 저장되어있는 정보와 일치하는가 대조해서 ok 사인을 받는다.

     

    클라이언트는 Ok 사인을 받으면 id를 세션구역(서버측 쿠키)에 저장하고

    이후에 로그인이 필요한 서비스를 이용할 때마다

    세션에 저장해둔 id 를 기준으로 데이터를 찾는다.

     

    즉, 세션의 id 정보를 토대로 기능의 사용을 인가(Authorization) 한다.

     

    그러나, 세션에 id 정보를 저장하는 것이 문제가 되는 경우가 존재하는데,

    만약에 서버가 여러개라면? 세션이 저장되어있는 서버를 한번씩 들러야 하는 번거로움이 생긴다.


    2.JWT

     

    클라이언트에 id 정보를 local Storage 나 cookie 에 저장할 수도 있으나

    이건 해커에게 정보를 털어가 달라고 사정하는 수준의 위험도를 지닌다.

    그래서 이에 대응해서 만들어진 또 다른 로그인 방식이 바로 JWT다.

     

    이 방법에선 인증(Authentication) 과정의 후처리로 아이디와 비밀번호의 조회가 끝난 뒤

    서버는 정보를 암호화한 토큰(입장권)을 클라이언트에게 발급한다.

     

    클라이언트는 특정 기능을 실행할 때마다 이 토큰을 서버에게 전달해주며

    이때 암호화된 토큰을 서버에서 복호화에 성공하면 인가(Authorization),

    실패하면 변조된 데이터로 보고 비인가 한다.

     

    이 과정을 통해서 복호화한 토큰속에 유저의 아이디 정보가 들어있다면,

    이 아이디 정보를 토대로 유저에게 맞는 정보를 DB에서 가져올 수 있다.


    3.위험성

     

    인터넷을 뒤져보면 잘못된 형태로 쓰고 설명하는 글들도 엄청나게 많다.

    작자는 매우 엄중하게 경고한다.

    !!!!!jwt를 제대로 이해 못했다면 절대로 쓰지 말것!!!!!

    생각없이 쓰면 코딩 인생이 끝날만큼 엄청나게 위험하다.

    이 토큰을 사용할때 별도의 데이터 대조와 인증 과정을 거치지 않는다는 점을 주목할 필요가 있다.

     

    JWT는 아이디와 비밀번호의 인증이 끝난뒤에 발급된 허가권이다.

    즉, 이 허가권만 탈취하면 아이디와 비밀번호없이 데이터를 해킹할 수 있다.

     

    이에 대응하기 위해서 토큰의 토큰의 토큰의 토큰으로 사용할 것인가?

    JWT를 사용하는 이유를 생각해보자.

    추가적인 인증 과정을 만들어 버린다면 그 시점에서 JWT를 사용할 장점과 이유가 완전히 없다.

     

    더불어서 토큰을 '안전한 장소에 보관' 하는 방법은 전혀 존재하지 않는다.

    이는 절대로 빈말이 아니다.

     

    local Storage 는 js로 바로바로 털어낼 수 있고

    session에 저장한다면 jwt의 개념 자체가 박살나며

    cookie 에 저장해서 http only로 저장하라는 의견도 있는데 rest로 보내면 그만이다.

    +이게 무슨소리냐면 http only로 저장한 토큰은 사용을 위해서 이리되고 저리됬든

    결국 rest 코드가 반드시 들어갈 수 밖에 없기 때문에 입출력에서 허점이 존재한다는 뜻이다.

    차이점이 있다면 조금 더 귀찮은 정도 뿐이다.

    js 변수에 저장하라는 말도 있었다. 사용자가 브라우저로 새로고침하면 토큰이 날라간다.

    그 새로고침에 대응하기 위해서 결국 local Storage , cookie를 쓰게되니 번거로움만 남는다.


    4.리프레시 토큰

     

    이러한 취약점을 지니고 있으나 현재시점에서 jwt가 쓰일 수 있는 유일한 이유는 리프레시 토큰이다.

    리프레시 토큰을 알아보기 전에 준비과정인 인증(Authentication)부분을 살펴보자.

     

    이번엔 아이디와 비밀번호 검증이 끝난 뒤, 이번엔 토큰을 두개 지급한다.

    토큰 A는 사용을 허가할때 쓰는 Access token, 또 다른 하나는  Refresh token.

     

    Access token 에는 DB에서 정보를 꺼내기 위해서 존재하는 유저 정보와 토큰의 제한 시간이 적혀있다.

    Refresh token 에는 refresh token의 제한시간과 +alpha가 들어있다.

     

    리프레시 토큰은 access token의 제한 시간이 끝나면

    다음 access token을 이어서 받을때에 서버에 접속하기 위한 인가(Authorization) 에 사용된다.

    인가가 끝난뒤, 어떤 유저의 토큰을 제작해야 하는가를 판단할 데이터가 추가로 필요한데

    이 부분을 +alpha 로 처리한다.

     

    이렇게 처리 함으로써 access token가 탈취 되었더라도 이미 기한이 종료된 토큰이므로 공격을 어느정도 예방한다.

     

    이 방법은 완벽하지 않지만 현재 대중적으로 사용되고 있는 방법이다.

    완벽하지 않은이유는 아래와 같다.

     

    1.access token 의 기한은 짧아야 한다. 즉, 서버에 계속해서 신호를 보낸다.

    2.기한이 짧다고 완벽한 것이 아니다. 결국 탈취한뒤에 사용할 수 있는 여백의 시간은 존재한다.

     

    이 두가지 문제가 서로 충돌하는 점 또한 고려해야 한다.

    때문에 적절한 제한시간의 조율이 필요하다.


    4.오해

    흔히들 사용하는 jwt의 사용원칙은 아래와 같다.

    access token은 짧게, refresh token은 길게.

    토큰은 안전한 장소에 보관.

     

    글을 쭉 읽고 따라왔다면 이해할 것이다. 프론트 엔드에서 토큰을 안전하게 보관할 장소는 존재할 수 없다.

    안전하게 보관이 가능하다면 그 시점에서 이미 개발자 또한 토큰을 사용할 방법이 없다.

     

    여기서 주목할 부분은 refresh token은 길게라는 개념의 부분인데,

    refresh token은 access token을 지급 받는 용도 외에 사용되지 않으므로

    유저의 정보를 해킹하는 것과 거리가 먼 비교적 안전한 탈취라는 의미로 쓰이는 말이다.

    즉, 토큰을 방어하는것은 불가능하니 털린다는 것을 전제로 구현하라는 것이 진짜 뜻이다.


    5.리프레시 코튼이 탈취되면?

    그렇다면, refresh token을 탈취 당하는 것이 정말 안전한가?

    안전하다고 하는 이들이 많지만 작자는 아니라고 생각한다.

     

    rsa 암호화를 사용하기 때문에 상대적으로 토큰의 해시코드가 털릴 가능성은 낮으나

    리프레시 토큰에서도 결국 사용자를 식별할 수 있는 정보가 포함되어 있기 때문이다.

    이를 활용한 해킹 공격의 (ex.SQL injection) 의 표적으로 삼을 수 있고

    자신의 계정에서 refresh token을 추출한 뒤, 유저 식별 정보를 위조해서

    다른 계정의 access token을 획득할 수도 있을 것이다.

    복호화 없이 토큰 자체를 바로 적용한뒤 access token을 획득할 가능성도 있다.

     

    그러므로 토큰을 구현 하겠다면 핵심적으로 방어해야하는 부분이 refresh token이다.

    토큰의 변조여부(sha의 비밀키가 털렸을 가능성), 토큰의 탈취여부에 대응해야만 한다.

    그것이 jwt를 구현할 수 있는 최소한의 자격이라고 생각한다.

     


    Final. JWT에 대한 정리

     

    1.jwt는 보안적으로 상당히 위험한 허점이 있다. 그러므로 제대로 그 구조를 알고 사용하자.

    2.jwt를 쓰면 대조를 위한 DB와의 통신을 줄일 수 있다. 그러나 서버와의 통신이 그 이상으로 늘어난다.

    3.jwt를 안전하게 보관할 방법은 없다. cookie 와 localStorage는 각각 csrf, xss 공격에 취약점이있다.

    4.그러므로 고민하지 말고 보관은 자유롭게 하되, 서버측에서 토큰의 변조, 탈취 검사를 제대로 할것.

     

     

     

    '개발 > 개발지식' 카테고리의 다른 글

    웹 보안에 대한 정리. (1)  (0) 2023.02.01
    Spring MVC 과 Spring boot  (0) 2021.10.31

    댓글

개발에 관심을 가지는 블로그