Skip to content
This repository was archived by the owner on Aug 25, 2019. It is now read-only.

UseBB 1 CSRF

dietrichm edited this page Aug 11, 2011 · 1 revision

Protecting UseBB 1 mods against 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 forms

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 links

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);

Notes

  • 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 the verify_form() and verify_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.

Using tokens manually

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.

Clone this wiki locally