WordCamp Salt Lake City 2013

WordCamp Salt Lake City is back for 2013!

This year we are moving the location to Sandy, Utah, which should make it easier for our friends in Utah county. The big day is Saturday 21 September 2013.

Do you have a WordPress topic that you are passionate about? Submit a presentation for consideration. Want to help us cover the bills? We have sponsorship opportunities too.

Registration is now open, with discounted early bird pricing.

WordCamp Salt Lake City has a history of bringing local ( and some not so local ) WordPress users, developers, designers and fans together in one spot on one day. I look forward to seeing everyone again.

Stateless CSRF Tokens

UPDATE: I posted improved versions of these functions in Better Stateless CSRF Tokens.

I’ve been thinking about CSRF tokens lately. If you are using the built in $_SESSION feature of PHP a common pattern goes something like this ( similar to what Chris Shiflett describes ) :



$token = base64_encode( openssl_random_pseudo_bytes( 32 ) );
$_SESSION['token'] = $token;
$_SESSION['token_time'] = time();


echo '<input type="hidden" name="token" value="' . $token . '" />';


if ( 
    isset( $_POST['token'] )
    && $_POST['token'] === $_SESSION['token'] 
) {
    if ( ( time() - $_SESSION['token_time'] ) <= 300 ) {
        // valid token, within time limit

A few notes about this approach. First, use openssl_random_pseudo_bytes instead of mt_rand ( suggested by Kevin Schroeder ) when possible. Second, be sure to only use === when comparing the token value. You want to avoid automatic type juggling.

Why worry about automatic type juggling when comparing CSRF tokens? Try this script:

$token = 'abc123';
$form_token = 0;

if ( $form_token == $token ) {
    echo "Valid token\n";
} else {
    echo "Invalid token\n";

Even though $token and $form_token clearly don’t contain the same values this script will display ‘Valid Token’ because of automatic type juggling. That makes your CSRF token basically useless as an attacker can set the token to zero and it will be considered valid. Switching to === will display the expected ‘Invalid token’.

This is all fine and good until you want to avoid using PHP sessions. Perhaps you have several web servers and don’t want to deal with shared session storage. Or have servers in multiple data centers and don’t want to try and sync state across them. What ever the reason, popping a token into $_SESSION isn’t an option in this case. In short you want some sort of stateless CSRF token.

One method is to generate a token based on known values that won’t change and lasts for a given period of time. This is what WordPress does. You can see the WordPress implementation in the inaccurately named wp_create_nonce and wp_verify_nonce functions ( WordPress nonces aren’t really nonces, they can be used more than once ). The high level version is that WordPress takes a known set of values like the user id, NONCE_KEY, descriptive action text, and current time; then runs them through an MD5 HMAC.

By default the tokens are good for 24 hours. You can adjust the time a WordPress nonce value is valid for by filtering nonce_life. That isn’t very flexible though. If you want to use different HMAC keys and timeouts across various requests then you end up having to filter both sides ( create and verify ).

I got to wondering what a more flexible approach to stateless CSRF tokens would look like. Here is what I’m thinking of:

function request_token_generate( $data_str, $key, $timeout = 900 ) {
    $now = microtime( true );
    $hash = hash_hmac( 'sha256', "$data_str|$now|$timeout", $key );

    return base64_encode( $hash ) . "|$now|$timeout";

function request_token_verify( $token, $data_str, $key ) {
    list( $hash, $hash_time, $timeout ) = explode( '|', $token, 3 );
    if ( empty( $hash ) || empty( $hash_time ) || empty( $timeout ) ) {
        return false;

    if ( microtime( true ) > $hash_time + $timeout ) {
        return false;

    $hash = base64_decode( $hash );
    $check_hash = hash_hmac( 
        'sha256', "$data_str|$hash_time|$timeout", $key 

    if ( $check_hash === $hash ) {
        return true;

    return false;

For request_token_generate you’ll need to provide a string containing unique data about the user and request, an HMAC key value, and an optional timeout. One example of the data string would be a combination of the internal user id, descriptive text about the action being taken, timestamp of when the password on the account was last changed, and the last 6 characters of the hashed password. Depending on the flow of the request you might want to include the URL that the form is expected to be on and the remote client IP address.

There is no specific limit on what you could include in the data string. Anything likely to be fairly unique to that user and request would be a good candidate. For that mater you could generate an additional unique key for each user at signup time that could be included.

$key = '5up3R53cr3T!';
$data_str = '45873' . 'delete_post_345' 
    . '2013-05-01 14:45:32' . '2dH6hi';
$request_token = request_token_generate( $data_str, $key );

echo "Token: $request_token\n";

That will produce a token that looks something like:


This is really 3 values separated by |, the first is the base64’d HMAC ( using SHA256 instead of MD5 ). The second value is the timestamp for when the token was generated and the third is how long the token is good for in seconds. Verifying the token is easy enough:

if ( request_token_verify( $request_token, $data_str, $key ) ) {
    echo "Valid token\n";
} else {
    echo "! INVALID ! token\n";

The verification side needs to have access to the same values that went into building $data_str and the HMAC key. You don’t need to know the timeout for the token because the timeout is included as part of the token value.

This approach prevents tampering by including the timestamp and the time out values as part of the HMAC call ( as does WordPress ). Testing this is easy enough:

$key = '5up3R53cr3T!';
$data_str = '45873' . 'delete_post_345' . '2013-05-01 14:45:32' . '0dH6hi';
$token = request_token_generate( $data_str, $key, 15 );

// confirm original works
echo "Should be valid: ";
if ( request_token_verify( $token, $data_str, $key ) ) {
    echo "Valid token\n";
} else {
    echo "! INVALID ! token\n";

// turn back time
list( $hash, $hash_time, $timeout ) = explode( '|', $token, 3 );
$hash_time = $hash_time - 100;
$fake_token = "$hash|$hash_time|$timeout";

echo "Should be INVALID: ";
if ( request_token_verify( $fake_token, $data_str, $key ) ) {
    echo "Valid token\n";
} else {
    echo "! INVALID ! token\n";

// alter timeout
list( $hash, $hash_time, $timeout ) = explode( '|', $token, 3 );
$fake_token = "$hash|$hash_time|10000";

echo "Should be INVALID: ";
if ( request_token_verify( $fake_token, $data_str, $key ) ) {
    echo "Valid token\n";
} else {
    echo "! INVALID ! token\n";

The first test checks that the unmodified token is valid. The second test attempts to set the timestamp back in time. The third attempts to increase the timeout value. The two altered tokens fail because the hash values no longer match.

Overall I’m happy with this approach to stateless CSRF tokens.

WordPress 10th Anniversary Party in Utah

You might have heard about WordPress turning 10 years old on May 27th. To celebrate local WordPress communities around the world are having anniversary parties on May 27th, 2013. This includes the greater Salt Lake City, Utah area. The details are at http://www.meetup.com/WordPress/Salt-Lake-City-UT/930892/:

When: Monday, May 27, 2013, 7:00 PM
Where: Sonny Brian’s; 33 East 11400 South in Sandy

View Larger Map

If you are coming be sure to RSVP so that we have an idea of how many people to expect. Bluehost is also giving away the 10th Anniversary WordPress t-shirts to the first 30 people who fill out this form on wpslc.com.

It will be a fun time to hang out and chat with other local WordPress fans/users/designers/developers.

Code Garage Migration to VaultPress

Today VaultPress announced the Code Garage migration details. We really wanted to make sure that we had the details and options on this right. I know that migrations like this can often be annoying, so we went out of our way to make the process smooth and inviting.

Code Garage users that migrate to VaultPress will get their first two months on VaultPress free. For those who don’t want to migrate, we’ll refund your last payment.

Even if you aren’t a Code Garage customer, you should go read Peter’s CodeGarage Locker is Migrating to VaultPress post. He gives a personal history of how Code Garage came to be, how it grew, and how it ultimately was sold to Automattic.

I am Speaking at the OpenWest Conference

The OpenWest Conference is happening May 2-4, 2013 (formerly the Utah Open Source Conference) at Utah Valley University in Orem, Utah.

This year the keynote speakers are Rasmus Lerdorf, creator of PHP, and Mark Callaghan, lead of the MySQL engineering team at Facebook.

For my part I’ll be giving three different presentations this time around. First up is “Simple Filesystems with Python and FUSE”, where I’ll cover the basics of getting a simple filesystem up and running written in Python using the FUSE library. Next up is “Site Testing with CasperJS”, which is an intro to using CasperJS to run user tests against your site. Last, but not least, is “Scaling WordPress”, where I’ll talk about some of the methods that WordPress.com (the largest WordPress install in the world) uses to host tens of millions of sites that add up to billions of page views per month.

I tried to keep my session titles direct and to the point. At times there will up to ten sessions running at once ( OpenWest session schedule ), so I wanted people to be able to tell at a glance what my sessions are about.

Tickets for OpenWest are available at $80. Every open source group in the area has been given a discount code though, so you can bring that down significantly.

If you’ll be at the OpenWest conference be sure to say hi.

HTML Purifier

In the world of HTML filtering in PHP HTML Purifier appears to be the current top dog. WordPress long ago forked kses for HTML filtering, which is fine, but as John Godley ( a co-worker at Automattic ) put it:

There is nothing fundamentally wrong with the way WordPress and bbPress filters comments, and in fact there has been no security alert related to this. However, this doesn’t detract from the desire to make things better, and the fact that HTML Purifier is much more thorough and exhaustive.

He wrote the HTML Purified WordPress plugin, which “replaces the default WordPress comments filters with HTML Purifier”.

For new PHP projects, or ones that allow you to easily swap in/out libraries, it looks like HTML Purifier is the current best option for HTML filtering.

Genericons Icon Font


Some of my great co-workers recently released a new icon font – Genericons

The details are in The Genericons Icon Font Story announcement post. In additional to being a nice general use icon font, it is licensed under GPLv2 (or later), so no more trying to sort out licensing terms to see if the icon font will jive with your existing open source projects. They are also free, as in no cost. The font is already in use in the new WordPress Twenty Thirteen theme ( demo site is at http://twentythirteendemo.wordpress.com/ ).

For more examples check out the bottom of the announcement post and genericons.com site.