Safeguard
Application Security•

ASVS 5.0 V7.2.4: Issue a New Session Token on Every Login

ASVS V7.2.4 requires a fresh session token on authentication and reauthentication, and the old one must die. Prevent session fixation with a few lines and a test.

Safeguard Security Team
4 min read

ASVS 5.0 V7.2.4 (Level 1) requires that the application generates a new session token whenever the user authenticates, including reauthentication, and terminates the token that was in use before. The identifier a visitor held before login must never become the identifier of their logged in session.

Why it matters

This is the defense against session fixation. In that attack the adversary gets a session id onto the victim's browser first, perhaps by a crafted link or a cookie set from a sibling subdomain. The victim then logs in, the application upgrades that same id to an authenticated session, and the attacker, who already knows the id, is signed in too.

Rotating the token at login breaks the chain. The value the attacker knows is dead by the time it would be useful.

Reauthentication matters for the same reason. When a user confirms their password to perform a sensitive change, the privilege level of the session rises. A fresh token ensures that anything learned about the earlier one no longer helps.

How to implement it

Create a new session, copy over only what you want to keep, and delete the old one. Do it after credentials are verified and before the response is sent.

Express with express-session:

app.post("/login", async (req, res, next) => {
  const user = await verifyCredentials(req.body.email, req.body.password);
  if (!user) return res.status(401).send("Invalid credentials");

  req.session.regenerate((err) => {
    if (err) return next(err);
    req.session.userId = user.id;
    req.session.authTime = Date.now();
    req.session.save((err2) => {
      if (err2) return next(err2);
      res.redirect("/dashboard");
    });
  });
});

The regenerate call issues a new id and discards the old session data. Flask with a server side session store works the same way: clear the session, create a new id, then set the user.

Spring Security does this by default with session fixation protection set to change the session id. Check that nobody switched it to none:

http.sessionManagement(s -> s.sessionFixation(f -> f.changeSessionId()));

Run the same rotation on reauthentication, MFA completion and privilege elevation. If you use signed tokens, issue a new token with a new jti and add the old jti to your revocation record.

Set the new cookie with HttpOnly, Secure and a sensible SameSite value, and clear the old one.

How to test it

  1. Open the site as an anonymous visitor and record the session cookie value.
  2. Log in.
  3. Compare the cookie. It must have changed.
  4. Replay a request with the original value. It must not be authenticated, and should not even be accepted as an anonymous continuation.
  5. Repeat for the reauthentication step and for MFA completion.

You can script this with curl using a cookie jar, or let a dynamic scanner check it. The web app scan demo shows how automated checks flag a cookie that survives login.

Click through it at your own pace, or open it full screen.

Common mistakes

  • Setting userId on the existing session object without regenerating.
  • Rotating on login but not on reauthentication or MFA success.
  • Regenerating the id but keeping the old one valid in the store.
  • Accepting session ids from the URL, which makes fixation trivial.
  • Forgetting that a load balancer or CDN may cache or pin the cookie.

Try it yourself

Write a three step integration test: fetch the login page, capture the cookie, post valid credentials, then assert that the cookie value changed and that the old one returns a 401 on a protected route. Add it to continuous integration so a framework upgrade cannot quietly undo the behavior.

Quick check

Does HTTPS prevent fixation?

No. Encryption protects the cookie in transit, but fixation is about who chose the value. Only rotation at login addresses it.

Should data from the anonymous session carry over?

Only deliberately, such as a shopping cart. Copy the specific fields you want rather than the whole session object.

Sources

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.