• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    해결됨

[Remember Me] 관련 문의입니다.

20.08.24 02:30 작성 조회수 751

0

좋은 강의 잘 듣고 있습니다.

Remember Me 가 쿠키에 저장됨으로, 보안에 취약한 부분은 없나요?

쿠키기간이 긴 경우, CSRF 등에 대한 방지 토큰이 없는 경우,

Remember Me 정보만 가지고, 로그인이 가능할 것 같아서, 문의드립니다.

혹시,  보안 침입자가 Remember Me 정보를 탈취할 경우, 로그인이 되는 상황은 아닌 가 해서

문의드립니다.

답변 2

·

답변을 작성해보세요.

1

스프링 시큐리티에서 Remember Me 는 메모리 방식과 DB 방식이 있습니다.

이 중에서 메모리 방식으로 Remember Me 인증을 사용하다가 공격자에 의해 토큰(쿠기) 도난당할 경우 

토큰값 자체는 해시 알고리즘에 의해서 비밀번호가 암호화 되어서 복호화가 어렵겠지만 토큰을 이용해서 인증을 받을 수 있습니다

분명히 보안에 취약한 점이 있습니다.

그러나 이 상황은 비단 Remember Me 뿐 아니라 쿠키를 이용하는 모든 인증방식에서 동일하게 보안에 노출되어 있습니다

반드시 여기에 대한 대비책을 세워야 합니다. 즉 토큰을 도용당했다 하더라도 원천적 차단 혹은 피해를 최소화하도록 여러가지 정책을 세워야 합니다. 가령 만료시간을 짧게 한다던지, 인증에 성공했을 경우 토큰값을 새롭게 갱신한다던지 등...

이에 반해 DB 방식으로 사용할 경우 스프링 시큐리티는 다음과 같이 처리하고 있습니다.

토큰값과 더불어 유니크한 식별자(Series) 를 생성해서 DB 에 함께 저장하는 방식입니다.

그리고 사용자가 Remember Me  인증에 성공할 때 마다 토큰값은 새로 발급하고 DB 에도 저장하고 식별자는 그대로 두는 방식입니다.

이렇게 되면 사용자는 새롭게 발급된 토큰과 식별자를 가지고 DB 에 저장된 값과 비교하게 되는데 새로운 토큰값과 기존의 식별자가 동일한 경우에만 인증이 성공하게 됩니다.

그래서 만약 침입자가 토큰을 도용해서 인증에 성공하게 되면 토큰이 새로 발급되고 DB 에도 그 토큰값이 저장되기 때문에 침입자가 인증에 성공한 이후에 사용자가 인증을 시도할 경우 DB 에 저장된 식별자는 동일하지만 토큰 값은 침입자의 토큰으로 업데이트 되었기 때문에 사용자의 토큰과 틀려서 인증에 실패하게 됩니다.

그렇다면 사용자는 누군가가 인증을 시동했다고 판단하게 되고 그 즉시 세션과 토큰, 식별자 등을 삭제하는 등의 처리를 할 수 있을 것입니다.

이와 관련된 소스는 다음과 같습니다.


// 식별자로 DB 에 저장된 토큰 정보 가지고 옴
PersistentRememberMeToken token = tokenRepository.getTokenForSeries(presentedSeries);


// 토큰이 서로 틀릴 경우 토큰 정보 삭제
// presentedToken : 사용자가 가진 토큰
// token.getTokenValue() : DB 에 업데이트 된 토큰
if (!presentedToken.equals(token.getTokenValue())) {

tokenRepository.removeUserTokens(token.getUsername());

throw new CookieTheftException(
messages.getMessage(
"PersistentTokenBasedRememberMeServices.cookieStolen",
"Invalid remember-me token (Series/token) mismatch. Implies previous cookie theft attack."));
}

// 인증에 성공할 경우 새로운 토큰을 발급 (generateTokenData()) 해서 DB 업데이트, 나머지 정보는 그대로 사용

PersistentRememberMeToken newToken = new PersistentRememberMeToken(
token.getUsername(), token.getSeries(), generateTokenData(), new Date());

try {
tokenRepository.updateToken(newToken.getSeries(), newToken.getTokenValue(),newToken.getDate());
addCookie(newToken, request, response);
}
catch (Exception e) {
logger.error("Failed to update token: ", e);
throw new RememberMeAuthenticationException(
"Autologin failed due to data access problem");
}

결론적으로 도난당한 토큰은 인증이 가능할 수 있습니다.

그렇기 때문에 빠른 대처가 필요하고 피해를 최소화 할 수 있는 보안 정책과 구현이 따라야 합니다.

0

궁금한 부분에 대해서 설명을 잘 해 주셔서 감사드립니다.