XSRF in phpBB, and probably a lot of other CMS software.

Major forums such as vBulletin and Invision Power Board have recently altered a lot of their codebase to require a security token to prevent their previous vulnerability to XSRF (Cross Site Request Forgery). Unfortunately, phpBB seems to be lagging behind a little and has not yet added this feature.

To test, I set up phpBB 3.0.9 with the default settings, then went to my server and created the following script:

<?php
header('Location: http://target.com/phpbb/ucp.php?mode=logout');
?>

I then used the [img] tags in phpBB to point at the above script. Upon viewing the post, I was logged out. Obviously this is a problem (it would be very annoying to users) but the real worry is that an attacker finds a URL that does something nasty. Imagine if an admin was logged into a board’s ACP and viewed such an image.

I can imagine there’s a huge number of content management systems out there that have this problem, too. Any situation where a user can select a remote resource to be accessed by the browser (images are the obvious one, but even a link can be malicious in this sense) is problematic, because it would allow XSRF.

The obvious solution, which some sites are already using, is some sort of link-cookie system whereby each link has a security token embedded to prove that the request came from a legitimate source. The first method I thought of for generating these tokens is a hash of the session ID, but came to realise that since a lot of CMS software places the session ID in the URL, it might be leaked using the HTTP referrer header. So, after that consideration, here’s my example:

<?php
// when a session is created, set $_SESSION['url_xsrf_key'] to a random string.
// this keeps the key specific to the session, but cannot be broken through leaked referrer URLs.
// I'm also hashing with the session ID to prevent (albeit unlikely) collisions of url_xsrf_key.

function GenerateLogoutLink()
{
    // hashing the path is important as it prevents use of known keys on other URLs
    $logout_path = $settings->siteBase . "/logout.php";
    $key = md5(session_id() . $_SESSION['url_xsrf_key'] . $logout_path);
    return $logout_path . '?k=' . $key;
}

function ValidateRequest()
{
    if(!isset($_GET['k'])) return false;
    if($_GET['k'] == "") return false;
    $logout_path = $settings->siteBase . "/logout.php";
    return $_GET['k'] == md5(session_id() . $_SESSION['url_xsrf_key'] . $logout_path);
}
?>

As long as every script on the site that is user-facing (i.e. not an include) uses this system, it’s safe against this form of XSRF.

Update
I’m using this post to create a short list of major CMS softwares and websites that are vulnerable to XSRF on at least the logout page. I tested with the above PHP script and a mod_rewrite rule to fake a .jpg extension. Not all of these can be attacked directly, since they don’t allow users to post images. However, a malicious user could find another site that a target user frequents and post an image on there that performs the XSRF attack.

Forums:
phpBB 3.0.9
TinyBB 1.4.2
Serendepity 1.5.5
Blogs:
WordPress 3.2.1
b2evo 4.0.5
Generic CMS:
PHP-Fusion 7.02.03
Drupal 7.2
Concrete5 5.4.2
Websites:
Google Mail
YouTube
Blogger
Blogger
Google (via Google accounts)
Google AdSense
Google AdWords
Jaiku (yet another Google service)
Google Wave
Hotmail (a.k.a. Windows Live Mail)
Slashdot
Typo3

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s