-
Notifications
You must be signed in to change notification settings - Fork 12
UseBB 1 CSRF
Since 1.0.12, a protection mechanism against CSRF (cross-site request forgery) attacks was added and applied to a big number of actions in the default UseBB 1 package. This mechanism uses tokens, generated on the server side and added to forms or URLs. A token is a string similar to "1201655092.3234-1911bde3194178c343cd7fb58596fbe9
". Upon making the request by accessing the URL or submitting the form, the submitted token is compared to the server stored ones. When not present, the request is invalid and no action is taken. Every page in UseBB issues at most one token, and tokens remain valid until they are cut off (only a number of recent tokens is kept) or too old.
Without the protection, malicious users passing URLs or pages containing JavaScript to a logged-in user could execute actions the latter is not aware of. With the tokens, it is not possible to use the "old" URLs (no token = invalid token), and nearly impossible to guess the correct token required. Only XSS (cross-site scripting) could reveal a valid token to the hacker.
Since UseBB 1 has no framework or model for "forms" or "actions", every action needs to be secured manually.
Securing your custom pages/actions is fairly easy. For form tokens, the $template->parse()
method has received a new parameter $enable_token
. Passing TRUE
to this parameter will add a hidden input field containing a token to an existing template variable containing an input field. For example:
$template->parse('my_form', 'my_mod', array(
'var1' => $foo,
'var2' => '<input ... />',
'var3' => '<input ... />'
), FALSE, TRUE);
The last parameter is TRUE
, meaning the system will look up the first variable containing <input ... />
and append the hidden token. In the example, the token is appended at the var2
variable. This will not be visible and will not break validity.
If you mod the ACP or develop an ACP module, templates are not used. In that case, add the output of $admin_functions->form_token()
to a place inside the form and where input elements are valid (if you care about validity). Typically, after the submit button.
Now the token is added, you must verify it has been passed correctly before performing actions. On the usual place you verify input (POST) variables, perform $functions->verify_form()
. Ideally, do this at the end of a series of AND
(&&
) conditions inside an if
statement.
if ( !empty($_POST['foo']) && $functions->verify_form() ) { ... }
Securing GET requests is easy too. Again a parameter $enable_token
is added at the end, this time to $functions->make_url()
, and passing TRUE
adds a GET variable with the token. Verification is possible using $functions->verify_url()
.
$functions->make_url('file.php', array(
'id' => $foo,
'act' => 'bar'
), TRUE, TRUE, FALSE, TRUE);
- With both verification methods, a message will be added to the output whenever the token appears invalid. To disable this message box, pass
FALSE
along theverify_form()
andverify_url()
methods. - It is important to protect against XSS using
unhtml()
. XSS would allow the tokens to be leaked to other people and websites. - Although both approaches seem alike, it is advised to use forms over links for important and frequently used actions. When using links, please refrain from keeping the token visible in the browser's address bar. Redirecting to a "clean" (tokenless) URL after the action is advised.
- Tokens are not invalidated after usage. Doing so could be possible and improve security once more, but it would disable back and forward actions. UseBB may support this aggressive method in a later version.
If you don't use the template system or make_url()
method, you can manually make and verify token strings using $functions->generate_token()
and $functions->verify_token($try_token)
:
$token = $functions->generate_token();
// Use $token in form.
// Later...
if ( !empty($_POST['foo']) && !empty($_POST['token']) && $functions->verify_token($_POST['token']) ) { ... }
Please note it is still recommended to use UseBB's templates and URL handling instead of your own.