The typical way of protecting against CSRF attacks is to create a cookie with a random string. Then using that string as a hidden form field value and checking that the cookie browser sent to server matches the hidden form value.
Cookies are not context aware enough
Secure flag in cookie means that browsers won't send the cookie over non-encrypted connection. It does not prevent non-encrypted connections from overwriting the cookie.
Man-in-the-middle attack and cookie forcing
How to fix this?
I can see two options here:
- Don't use CSRF cookie, rather concatenate the info to session cookie and re-create the CSRF value during login
- Store the CSRF value also on server-side
With option 1, if the attacker changes session cookie value, the user is logged out from the service. Then re-creating the CSRF value during login prevents attacker from knowing the value. This means you need to split the cookie in parts on server-side before using it.
When going with option 2, you need to match the CSRF cookie sent by browser and the CSRF value from forms with the CSRF value stored server-side. If those don't match, discard the request and create new CSRF cookie.