Problem/Motivation
Drupal implements the Synchronized Token Pattern in order to protect against Cross-site request forgery. OWASP provides a nice description of the mechanism on their CSRF wiki page:
In general, developers need only generate this token once for the current session. After initial generation of this token, the value is stored in the session and is utilized for each subsequent request until the session expires. When a request is issued by the end-user, the server-side component must verify the existence and validity of the token in the request as compared to the token found in the session.
The mechanism implemented in Drupal varies in two details:
- By supplying the optional
$value
parameter toCsrfTokenGenerator::get
, the token can be varied for different purposes, e.g. per form-id. This is a very reasonable security hardening measure. - Instead of randomly generating the token, Drupal uses the session id as the token seed.
The idea behind the second point likely was that in order to make the token per-session it is enough to generate it from the session-id. However, this assumption leads to various problems. First and foremost to #961508: Dual http/https session cookies interfere with drupal_valid_token(). But also to a unnecessary dependency of the CsrfTokenGenerator
to the custom way we generate session ids (#2238561: Use the default PHP session ID instead of generating a custom one).
Proposed resolution
Instead of using session-id as the token seed, generate it on demand and store it in the session.
Remaining tasks
- patch from #46 was committed to D8 8.x in #48/49
- Backport | Contributor task document for backporting a patch
User interface changes
API changes
Blocking
Follow-ups
- #2238087: Rebase SessionManager onto Symfony NativeSessionStorage improves ugly workarounds needed here
- when (if) #2238087: Rebase SessionManager onto Symfony NativeSessionStorage goes in, there are some @todo's introduced here which will need their own issues. (So that issue is tagged with needs follow-ups)