[보안] 자동로그인(Remember me)의 원리
자동로그인을 구현하는데 가장 널리 쓰이는 디자인은 Charles Miller의 “Persistent Login Cookie Best Practice”이라고 본다.
어떤 건데?
밀러의 디자인을 요약하면 다음과 같다.
사용자가 자동로그인을 체크하고 로그인하면 표준 세션 관리 쿠키( 브라우저가 종료되면 만료되는 세션쿠키 )와 함께 로그인 쿠키가 발행된다.
로그인 쿠키는 사용자 이름과 적절한 토큰을 가지고 있다. 토큰은 충분히 큰 난수이다(암호화). 이 정보는 데이터베이스에 쌍으로 저장된다.
로그인하지 않은 사용자가 사이트를 방문하여 로그인 쿠키를 제공하면 사용자 이름과 토큰이 DB에서 조회된다.
조회 된 쌍이 있는 경우 사용자는 인증 된 것으로 간주하고, 사용 된 토큰은 데이터베이스에서 제거된다. 동시에 새 토큰이 생성되어 사용자 이름과 함께 쌍으로 DB에 저장되고, 새 로그인 쿠키가 사용자에게 발급된다.
쌍이 없으면 로그인 쿠키는 무시된다.
자동로그인 메커니즘만으로 인증된 사용자는 암호 변경, 돈 지출과 같은 특수 서비스에는 접근할 수 없다. 이런 작업을 수행하려면 로그인 양식을 제출해야한다.
이 메커니즘은 여러 브라우저 또는 컴퓨터에서 여러 번의 저장 된 로그인을 가질 수 있게 된다. 그러므로 한 번의 작업으로 모든 자동로그인을 폐기 할 수 있는 방식을 제공해야한다.
문제점
이 방식의 설계는 수많은 장점을 가지고 있지만, 문제점도 하나 가지고 있다.
해킹
바로 쿠키가 도난 당했을 경우이다. 공격자는 피해자의 로그인 쿠키를 훔쳐서 자동로그인을 하게된다. 이럴경우 공격자에게 항상 새로운 로그인 토큰이 발급된다. 공격자는 기억 된 로그인 세션이 만료 될 때까지 피해자로 사이트에 계속 접근할 수 있다.
물론 피해자가 다시 사이트에 접근할 경우 피해자의 로그인 데이터 쌍은 이미 공격자의 로그인에 의해 변경 되어있기 때문에, 자동로그인이 실패하게 된다.
하지만, 피해자는 보통 ‘음? 뭐지? 왜풀렸지? 다시 로그인하지 뭐.’의 반응이 대부분이고 그냥 자연스럽게, 재로그인을 하게 된다.
‘마지막 로그인 시간’ 같은 것을 표시해준다면 사용자가 문제를 인식하는데 도움이 되겠지만, 더 좋은 방법은 사용자가 명백한 판단을 할 수 있도록 도와주는 것이다.
해결방법
이 문제에 대한 해결책은 자동로그인 데이터를 { 사용자이름, 식별자, 토큰 }의 쌍을 갖게 하는것이다. 기존의 문제점은 공격자가 토큰0을 도용하여 사용하면 토큰1이 발부되지만 피해자는 토큰0을 계속 가지고있게 된다.
하지만 데이터베이스는 토큰0에 대한 정보를 더이상 가지고 있지 않으므로 토큰이 그냥 누가 만들어낸 유효하지 않은 쓰레기 값인지 아닌지 마저도 구별할 수가 없다.
이 때 현재 토큰과 식별자를 함께 제시해야한다면 시스템은 피해자가 유효하지 않은 토큰과 유효한 식별자를 가지고 있는 것을 알 수 있다. 식별자가 충분히 일반적으로 만들어내기 어려운 정보라고 한다면(암호화). 사용자가 유효하지 않은 토큰과 유효한 식별자를 함께 제시 할 수 있는 유일한 방법은 다른 사용자가 이전에 같은정보를 제시 한 경우뿐이다.
즉, 두명의 서로 다른 사용자가 동일한 식별자와 동일한 토큰의 쌍을 동시에 보유했다는 것이므로 도난이 발생했다는 게 명백해진다.
발전된 방법의 디자인
이 설계는 밀러의 설계에서 2번과 3번만 바뀌었다고 봐도 된다.
사용자가 자동로그인을 체크하고 로그인하면 표준 세션 관리 쿠키와 함께 로그인 쿠키가 발행된다.
로그인 쿠키는 사용자의 이름과 식별자, 토큰을 포함한다. 식별자와 토큰은 충분히 큰 난수이다(암호화). 이 셋의 쌍은 데이터베이스 테이블에 저장된다.
로그인하지 않은 사용자가 사이트를 방문하여 로그인 쿠키를 제공하면 사용자 이름, 식별자, 토큰이 DB에서 조회된다.
셋의 쌍이 있는 경우 사용자는 인증 된 것으로 간주된다. 사용 된 토큰이 DB에서 삭제되고, 새 토큰이 생성된다. 새 토큰은 사용자 이름과 이전과 동일한 식별자와 함께 DB에 저장되고, 새 로그인 쿠키가 사용자에게 발급된다.
사용자 이름과 식별자가 같은 DB 정보와 토큰이 일치하지 않으면 도난이 일어난 것으로 간주된다. 사용자에게 강한 경고를 보내고 사용자가 기억 한 모든 세션이 삭제된다.
사용자 이름 과 식별자가 없으면 로그인 쿠키가 무시된다.
식별자는 재사용되는 것이 중요하다. 식별자가 매번 바뀔경우 도난당한 경우와 만료되어 삭제된 경우를 구별할 수가 없다.
마치며
이 디자인은 밀러의 디자인에서 2가지의 추가 장점을 지니게 된다.
공격자는 세션의 만료시기가 아닌 피해자가 웹 사이트에 다시 접속할 때까지만 도난한 쿠키를 사용할 수 있다.
피해자가 사이트에 접속한 순간 도난 사실이 통보된다.
2023년 새해에는 성장하고 함께하고 싶다면?
Pre A 단계 이상의 스타트업 C 레벨들이 모여서 커뮤니티를 만들었습니다. 같이 스터디하고 친해질 일잘러를 찾습니다.