Is comparing the CSRF token on the cookie header with the form's hidden element be enough?
A random token that has to be the same on the cookie and the form is a common anti-XSRF strategy, the ‘double-submit cookie’. It is used by, for example, Django, so clearly it is considered enough by some.
It is, however, weaker than the generally-recommended (eg by OWASP) ‘synchroniser token’ pattern, in which the form token has to match a token stored on the server and associated with the session.
Personally I wouldn't choose this method for a sensitive site.
The attack the double-submit cookie is vulnerable to, which synchroniser token is not, is cookie forcing.
CSRF tokens from the cookie header cannot be read because of the same-origin policy.
It is generally hard to read a cookie from another origin, such that routes to doing so (eg XSS, MitM) typically mean you have to have compromised the site pretty solidly already.
However writing cookies is not as locked-down, thanks to poor design in the original cookie specification. Most significantly, a malicious or compromised neighbour site at
dodgy.example.com can write a cookie with domain set for
example.com that will be read by
sensitive.example.com. Also, whilst an HTTPS-protected site is safe against having its cookies read by a network-level man-in-the-middle-attack, it is possible for a MitM to generate traffic to a non-HTTPS-protected neighbour domain that doesn't even need to exist, and use that neighbour domain to set a non-
secure cookie that will be read by the victim HTTPS site. And there are a few other attacks that could be used to get cookie forcing, for example header injection.
By forcing a cookie onto the victim site, the attacker knows what the token in the form has to be and so can include it in a cross-site form, evading the XSRF check. This constitutes an elevation of the attack from a slightly weak one to a stronger one.