In a nutshell, all forms will have a new hidden field "lj_form_auth" which will have value:
join(":", "c0", ServerSecretTime, CurrentTimeOffset, AuthExpiryAge, join("-", randchars(10), $remote's userid, $remote's current login session auth), MD5(all previous fields + ServerSecret(ServerSecretTime))
I'm not sure how much of this I've covered before, so in another nutshell:
-- "c0" is the auth version.
-- The server generates a (SecretGenerationTime, Secret) pair every hour. Getting at this is fast and easy (LJ::get_secret() -> ($stime, $secret)), and the secret must never be given to clients. If one is, somehow, it can be invalidated on the server and worst case, it's not caught and it's only good for an hour.
-- The CurrentTimeOffset is just the number of seconds elapsed from ServerSecretTime to the present.
-- AuthExpiryAge is the number of seconds the auth key is good for, past ServerSecretTime + CurrentTimeOffset
-- The next field is a caller-defined attribute which it can validate independently. It can be trusted, though, since it's part of what's signed.
-- The final field is the "signature", the MD5 of all the previous fields and the site's secret. If the client tampers with any part of the auth, it'll be invalid.
So, it's resubmitted later and we have a corresponding function to both check the signature and expiration of the auth overall, then a function to check the attribute field for this use case and make sure it's the same remote user and session.
I'm not a crypto guy, and I don't play one on TV, but this is definitely better than what we had before.
(BTW, everything it the second nutshell above is old. The only new part is using it for forms.)