spring-projects / spring-projects/spring-security

SEC-2985: PersistentTokenBasedRememberMeServices generates many tokens for one user

Open
#3,194 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

in: web type: bug type: jira
Dominant language
Java
Stars
9.6k
Forks
6.3k
Avg merge
2d 11h
Merged PRs (30d)
52

Description

Sergey Klimenko (Migrated from SEC-2985) said:

Hi team,

Scanning my database I found a lot of persisted tokens for the same user. Digging this problem I found that the PersistentTokenBasedRememberMeServices doesn't remove previous tokens in the following cases.

Let's suppose that we have a user that was authorized by username/login first time. In this case the onLoginSuccess method will be invoked and new token will be created and stored in PersistentTokenRepository.

After that in a few days, for example, the same user will by authorized by RememberMeAuthenticationFilter (we had valid token) and as result the processAutoLoginCookie method will be invoked and new token data will be generated and cookie and DB will be updated.

Now suppose that for any action full authentication is required. In this case the user will be forwarded to authorization form and as result onLoginSuccess method will be invoked. As result new token will be generated and stored in DB but please keep in mind that we already have valid token already in DB.

At this moment I see two solutions:

We can remove previous token from DB and store new one;

If we already have token it must be updated instead of creating new one.

I would preffer #2 so my code is:

    @Override
    protected void onLoginSuccess(HttpServletRequest request, HttpServletResponse response, Authentication successfulAuthentication) {
        String username = successfulAuthentication.getName();
        this.logger.debug("Creating new persistent login for user " + username);

        try {
            PersistentRememberMeToken token;
            final String rememberMeCookie = extractRememberMeCookie(request);
            if (rememberMeCookie != null) {
                final String[] strings = decodeCookie(rememberMeCookie);
                token = this.tokenRepository.getTokenForSeries(strings[0]);
                if (token != null) {
                    token = new PersistentRememberMeToken(token.getUsername(), token.getSeries(), generateTokenData(), new Date());
                    tokenRepository.updateToken(token.getSeries(), token.getTokenValue(), token.getDate());
                } else {
                    token = new PersistentRememberMeToken(username, this.generateSeriesData(), this.generateTokenData(), new Date());
                    this.tokenRepository.createNewToken(token);
                }
            } else {
                token = new PersistentRememberMeToken(username, this.generateSeriesData(), this.generateTokenData(), new Date());
                this.tokenRepository.createNewToken(token);
            }

            this.addCookie(token, request, response);
        } catch (Exception var7) {
            this.logger.error("Failed to save persistent token ", var7);
        }
    }

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by locating PersistentTokenBasedRememberMeServices and its onLoginSuccess method, then inspect the token repository methods used by the existing remember-me flow. Update the login path so an existing cookie series is refreshed rather than creating another persisted token, and verify that repeated authentication does not create duplicate persisted tokens.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
authentication, security
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
58/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.