The login page was solid.
Strong password rules.
A second factor.
Rate limiting
on failed attempts.
And still,
a tester got into
a customer's account
without ever knowing
the customer's password.
He did it before the customer
had even logged in.
He visited the site himself,
as nobody,
and the server
gave him a session cookie.
An anonymous session.
Harmless.
Then he got that same session ID
into the customer's browser.
On this site
it was easy,
because an old part of the app
still accepted the ID
as a parameter in the link.
He sent the link.
The customer clicked it,
saw the real login page,
and logged in properly.
Password.
Second factor.
All correct.
And the server did
what it had always done.
It took the session
the browser was already using,
and marked it as logged in.
The session
the tester was also holding.
He refreshed his own tab
and he was the customer.
No alert fired.
The logs showed
one normal login.
That is session fixation.
The attacker does not steal
your session ID.
He chooses it
before it is worth anything,
and waits for you
to make it valuable.
The fix is one rule.
When the level of trust changes,
the session ID changes.
At login,
throw the old ID away
and issue a fresh one,
carrying over only
what you need.
Spring Security
does this by default.
PHP gives you
session_regenerate_id.
Most frameworks have it,
and most custom login code
forgets it.
Do it again
when someone raises their privileges,
or confirms their password
to do something sensitive.
And stop accepting
session IDs from the link.
A cookie
the page cannot set for you
is much harder to plant.
Then write the test.
Note the session ID before login.
Log in.
Fail the build
if it is the same.
Logging in is not
proving who you are.
It is promoting a session.
Make sure it is a new one.
– Serguey Asael Shinder
Top comments (0)