Old cookie format:
*.$LJ::DOMAIN = ws:<user>:<sessid>:<auth>:<flags>
Insecure.
Own one cookie, own an account.
But, still used if $LJ::ONLY_USER_VHOSTS is not enabled.
New cookie format:
2 + n cookies
The 2 cookies work like this:
Master session cookie. We control this one tightly.
Bound to: www.$LJ::DOMAIN. No user content is on www.*
Format:
v<version>:u<uid>:s<sessionid>:a<auth>:f<flags>//<generation/poetry>
The version number is a code-wise version number.
uid is used now, now instead of user.
session/auth/flags all work as before.
generation/poetry is free-form text/poetry, so you can write a haiku and
go after people for subverting security to steal copyrighted, perhaps poetic, material.
The “I'm logged in!” cookie. This one advertised to all subdomains that the user is logged in. If it is stolen, it does not matter. It is only used to bridge the two cookies. It is useless by itself.
Form: not present (not logged in), or:
u<uid>:s<sessionid>
The n cookies work like this:
The “n” cookies are 1-per-user account. They are bound to <subdomain>.$LJ::DOMAIN optionally with a path=/username/ restriction when <subdomain> is not a username, and is actually “users” or “communities”.
“ljdomsess.<subdomain>” or ljdomsess.bob “ljdomsess.<subdomain>.<user>” or ljdomsess.community.knitting ljdomsess.users._underscoreman
The format of this cookie is:
v<version>:u<userid>:s<sessid>:t<unixtimestamp>:g<signature>//<gen/poetry>
Where:
t = Unix timestamp updated from LJ::get_secret(),
LiveJournal's rolling server-secret that is updated every 30/60 minutes.
This t value is the key into which server secret we are using.
g = HMAC-SHA1(key = server-secret(t),
value = JOIN("-", session-auth(u, sessid), domain, uid, sessid, time))
So, cookie is valid if:
v is supported version
gen/poetry is current generation/poetry in
$LJ::COOKIE_GEN_POETRY
session(uid, sessid) is still valid/logged in
g is correct signature
t is not older than $N hours (48?)
The cookie should expire every 24 hours.
Future: cookies are bound to first two octets of IP address.
Procedure 13.1. Cookie re-direction
If cookie is not present, but ljloggedin=1 cookie is present, then redirect user to:
http://www.$LJ::DOMAIN/set-domain-cookie.bml?redir=<source_url>
which will make a “ljdomsess_*” cookie, then redirect them to:
http://subdomain.$LJ::DOMAIN/__setcookie?redir=<source_url>&domsess=<domsess_cookie>
which will then redirect them to <source_url>.
Mapping to Paths. LJ::get_remote() needs to be modified to respect the right cookie based on the current hostname.
For talkscreen.bml or any XMLHTTPRequest that
goes to a userdomain, that endpoint has to make sure it only operates on data
owned by the current hostname/path.