I have had this functionality (csrf protection) for quite some time now. The thing I never liked about it is that it saved csrf tokens in the session file. While it may not be a real problem I see it as a pain because eventually tokens may build up so I need to utilize a gc mechanism and keep track of what was issued when and it all just seems too much for me.
So I spent the last couple of days working on improving this "imperfection" and here's what I've come up with. I will not be posting any real code I'll just explain the idea.
When a form is issued, by default a token is generated. The token consists of some data unique to the user, like session id or user id, combined with the current datetime string in format
YmdHi. All of this is encrypted using
password_hash and I have thought of further obfuscating the hash by swapping parts of it but haven't done that yet.
The validation was kind of tricky and turned out to be quite a disappointment. In order to validate a token I create a loop that hashes the same information about the user with the date and subtracts 1 minute on each iteration. Number of iterations is equal to the amount of minutes the token is valid for, which is not stored in the token therefore all tokens must be valid for the same amount of time, which doesn't seem like a disadvantage to me, yet.
I want to ask you if you see any possible flaws and exploits with this concept.
The only possible problem I see is that tokens are not actually kept by the server so theoretically anyone can assemble a valid token, however I think it's highly unlikely anybody would spend days in collecting tokens and would happen to have a super-computer in their basement to run statistical analysts on, which is again no guarantee that they would be able to crack the encryption.
Anyway I guess I should stop exposing my incompetence and let the smart people decide what's up.