CSRF Protection
Tokens
CSRF protection in Geeklog is based on tokens. A token is a unique ID that's only valid for a certain amount of time. Typically, it is created when a form is displayed, sent with the POST (or GET) request, and checked for validity when processing the form.
Tokens are stored in the gl_tokens table, introduced in Geeklog 1.5.0.
Creating and using Tokens
Standard practice is to embed both a token name and the token value in the form's template like so:
$template->set_var('gltoken_name', CSRF_TOKEN); $template->set_var('gltoken', SEC_createToken());
and then embed a hidden input field in your form, like so:
<input type="hidden" name="{gltoken_name}" value="{gltoken}"{xhtml}>
CSRF_TOKEN
is a constant, whereas the call to SEC_createToken()
will create and return a new token.
Normally, you will only use one token per form, so make sure to call SEC_createToken()
only once. The function has an optional parameter that defines the length of time ("ttl", time-to-live) that the token is valid. The default ttl is 1200 seconds, i.e. 20 minutes.
When processing the result of the HTTP request, simply call SEC_checkToken()
to check that the token sent with the request is valid. Abort the operation if the function returns false
. You may want to log the occurence of invalid tokens and the IP and username involved in the operation to be able to track abuse.
Considerations
- Avoid creating new tokens when not required. One token per form or page is usually enough.
- A call to
SEC_checkToken()
will invalidate the token. So if you display a new form after checking the token, you will need to create a new token. Consider this in the control flow of your form processing, e.g. when checking for missing required fields. Keep in mind that the user may use the back button which will display the form again - including a token that has just been invalidated. - Protect any operations that create, modify, or delete content. There is usually no need to use tokens when listing things (e.g. a list of articles). If the list has active elements, however, e.g. a checkbox to enable/disable something, then you should use tokens for those operations.