Hello 👋 I'm Dan.

I do Cloud DevOps and write PHP. I also care about web performance and security.

Using X-XSRF-TOKEN HTTP Headers for AJAX in Laravel 5 (Updated)

Update (24/02/2015): Laravel 5.0.6 has been updated to support cleartext X-XSRF-TOKENs. As explained in the recent post CSRF Protection in Laravel explained by Barry vd. Heuvel, Laravel can now process X-XSRF-TOKENs if they are transmitted in cleartext. Some would argue it’s still better to encrypt the CSRF token, but that’s for much smarter InfoSec people than me.

The following article was written for Laravel 5.0.5 in mind, but is still relevant as of 5.0.6

If you’ve recently started using Laravel 5 and are trying to use csrf_token() with the header X-XSRF-TOKEN with your AJAX requests, you’ll notice that you get a HTTP Error code 500, rather than a 200 OK response. This is because the CSRF middleware is expecting the csrf_token via X-XSRF-TOKEN to be encrypted - Something the Laravel documentation doesn’t make clear.

When I originally stumbled across this issue I thought it was a bug in Laravel and submitted a PR (which turned out to be a bad, naughty, terrible, not so good thing to do - in short, I should learn to search.) Regardless, we have two ways of getting around this. Our first way is to just encrypt the damn CSRF token and use that in our code, or alter the middleware to not perform decryption on the CSRF Token.

Option 1 - Encrypted CSRF Token

Our first option is to encrypt the CSRF token. As you may already know, you can access the CSRF token by using the function csrf_token. Load up your routes.php file so we can add the encrypted token to the views.

For each view you call, you’ll need to append this method:

withEncryptedCsrfToken(Crypt::encrypt(csrf_token()));

So, if you were calling a view for the home template, you’d do this:

view('home')->withEncryptedCsrfToken(Crypt::encrypt(csrf_token()));

Terrific. In that template you can access the variable like below:

<meta name="csrf_token" value="{{ $encrypted_csrf_token }}" />

Chuck that in your main view in the <head> so your JavaScript framework of choice can gobble it up. Just make sure to do use Crypt; if you’re in a different namespace.

Option 2 - Non-encrypted CSRF Token

Our second option is to alter the VerifyCsrfToken middleware to not expect an encrypted CSRF Token when transmitted via a HTTP Header.

Open up the VerifyCsrfToken.php middleware (located at app/Http/Middleware/) and we’ll extend the method tokensMatch.

protected function tokensMatch($request)
{
    $token = $request->session()->token();

    $header = $request->header('X-XSRF-TOKEN');

    return StringUtils::equals($token, $request->input('_token')) ||
        ($header && StringUtils::equals($token, $header));
}

Essentially, what I’ve done is copied the method from Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.php then removed the call to $this->encrypter. You’ll also need to add a use at the top of VerifyCsrfToken.php like so:

use Symfony\Component\Security\Core\Util\StringUtils;

Once you’ve done that, you can safely use plain old csrf_token in your X-XSRF-TOKEN header and get 200 - OK with all your AJAX calls. If you didn’t quite figure out the middleware alteration, load up this Gist to see how I modified the VerifyCsrfToken middleware.

Implementing in jQuery

If you happen to be using jQuery with Laravel, here’s how you can add the HTTP Header to your AJAX requests. As usual, there’s a few different options. If you’re doing a heap of requests over the lifetime of the session, you’ll want to set this token for all AJAX requests. If not, you can do it inline with the AJAX call.

First up, the pre-filter to make this global for all $.ajax requests:

$.ajaxPrefilter(function(options, originalOptions, xhr) {
    var token = $('meta[name="csrf_token"]').attr('content');

    if (token) {
        return xhr.setRequestHeader('X-XSRF-TOKEN', token);
    }
});

Good stuff. Now, all $.ajax requests in the application lifecycle will use that prefilter with the token and HTTP Header.

If you just need the HTTP Header for one or two requests, here’s how you can add it to the $.ajax call:

$.ajax({
    url: 'http://example.com/api',
    beforeSend: function (xhr) {
        var token = $('meta[name="csrf_token"]').attr('content');

        if (token) {
            return xhr.setRequestHeader('X-XSRF-TOKEN', token);
        }
},
/* ... */
});

That “pre-filter” will be in effect for that $.ajax call only.

Moving Forward

Now, it’s entirely up to you how to proceed. Just to be safe, I’ve decided to go with Option 1 because I want to err on the side of caution, but if your Laravel 5 app is super simple and can’t do much/any harm, I think it’s OK for your CSRF Token to match in a string-to-string comparison, but not be valid JSON.

Only time will tell.

Updates:

  • 19/02/2015: — I originally had the CSRF Token encrypted in the boot method of the AppServiceProvider. This was incorrect as csrf_token isn’t set unless it’s called from within a Route. My mistake!
  • 24/02/2015: — Updated with comments about Laravel 5.0.6 now supporting cleartext X-XSRF-TOKENs.

Changing Times

These last few months have seen many changes happen in my life. I’ve moved away from the Apple Systems Engineer role/world and transitioned into a Web Developer role here in Perth. I’ve moved state, proposed to my girlfriend (now fiancée), and bought a house (we’re also getting a dog).

This year saw me launch a fun project that I had been working on for a few months, a database for the best podcast in the world, Stop Podcasting Yourself. The website, SpyDB, is built on Laravel, my favourite PHP framework. This is my biggest project I’ve used Laravel on, and it was a blast to see just how easy it was to make something quite functional with relatively little past experience in Laravel.

The OS X Mavericks Server articles I wrote last year have continued to be a huge hit, but unfortunately there will be no OS X Server tutorials this year. I had planned (and started writing) a OS X 10.10 Yosemite Server eBook that was going to be distributed through Leanpub, but I’m just not able to dedicate time to writing about OS X Server, especially with paying customers. It wouldn’t be fair on the buyers of an incomplete book to wait months for a potentially completed book. I’m just not that kind of guy.

The content of this website will likely change to a more Web Developer aspect, but I’m still playing around with OS X Server so no doubt I’ll blog about some issues I come across.

Many thanks for reading, I hope you have a good rest of your day.

Dan xx

Learning Nagios 4 - A Book Review

As a longtime user of GroundWork, I’ve always had an abstraction layer between me and Nagios. I’d always thought that having a better understanding of the internals of GroundWork would make it easier for me to use, but I didn’t take the opportunity to learn about Nagios until now.

The book, Learning Nagios 4, by Wojciech Kocjan, weighs in at 400 pages and is the second edition. I found the book to be very well written, and it contained a lot of good technical information that I thought was interesting and beneficial.

Chapter 1 introduces Nagios to the unfamiliar user, and Wojciech gives good examples that ensure system administrators that Nagios is suitable for them. can provide IT staff with a very good system to check infrastructure and software to ensure it’s working correctly.

Chapter 2 runs through installing and configuring Nagios. I was very pleased to see a book providing instructions on installing software from source, as it’s rather unusual in my experience to find books that don’t just provide installation by package manager. Going through common Nagios configurations was also interesting, as I learnt a few quirks about templates and precedence.

Chapter 3 is all about the web interface that compliments Nagios. As a user of Nagios by proxy through GroundWork I was a little shocked at the Web GUI and how different it was to the interface I was used to, but it is nice to see Nagios 4 has implemented PHP support so there’s a bigger avenue for theme customisation.

Chapter 4 talks about the basic plugins that are provided with Nagios. If you’re a follower of my blog you would’ve seen my Nagios plugins for OS X Server, some of which were co-authored with/by my friend Jedda Wignall. I learnt quite a bit about the inbuilt plugins that come with Nagios, including the plugins that can schedule package manager checks - very cool!

Chapter 5 discusses advanced configuration details, mainly about templates and the nuances to inheritance, along with describing what flapping actually is. I thought the section on using multiple configurations (like OS type, location etc) to generate a configuration for a specific machine was quite interesting, and would allow the user to create advanced host settings with relative ease.

Chapter 6 was a chapter that I found very interesting as it focused on alerts and contacts. As a former member of a very small team we were inundated by emails every day and it became hard to keep track of what was coming in. The authors example of constant email flooding was exactly what happened to us. It’s worth spending a bit more time setting up proper alerts to make sure the right information reaches the right people, rather than spamming everyone constantly.

Chapter 7 talks about passive checks, and how they compare to the normal active checks. NCSA, or the Nagios Service Check Acceptor is also discussed, which is a daemon on the client end that can send check results back to the monitoring service securely. I’ve not used either types of passive checks, so learning about them was quite interesting. I’m looking forward to putting them into good use some time.

Chapter 8 contains a ton of great information and detail about the remote server checks performed by SSH, and the Nagios Remote Plugin Executor (NRPE). The author provides good arguments for choosing either of the services, depending on your requirements. I hadn’t actually heard of NRPE before, but it looks to be quite powerful without the overhead of SSH connections by the host.

Chapter 9 is all about SNMP and how it can interact with Nagios. In past experience I’ve only ever had bash scripts to process SNMP responses, but now I know how to implement it properly into Nagios without having a conduit processing script. I also never really knew much about SNMP, so it was good to learn about what SNMP actually is, not just how to interact with it, which can be an issue in some technical books where interacting is explained, but the source/destination isn’t.

Chapter 10 starts off by covering getting Nagios working with Windows clients, which to me isn’t very applicable as I’m purely a Linux/Unix/OS X man myself so my eyes glazed over as I pushed through that section. Having said that, it’s good to know Nagios monitoring is fully supported in Windows with the appropriate software installed. Another concept that is looked at in Chapter 10 is the setup and configuration of a multi-server master/slave setup with multiple Nagios servers. Now, unfortunately (or fortunately, depending on which way you look at it) I’ve not been in a position where I’ve needed to have multiple Nagios servers performing checks, but it’s useful to know that it’s possible, and to have some instructions on getting it set up.

Chapter 11 is probably my favourite chapter of the book because it’s all about programming Nagios plugins. The book has a multitude of examples written in different languages. I’ve always done my scripts in Bash, but had never even thought of writing plugins in PHP, which is my strongest language. Having seen code for a few languages (like Tcl) that I’ve heard of but not used, this book has encouraged me to try other languages for Nagios plugins, and not limit myself to Bash.

Chapter 12, the final chapter, talks about the query handler which is used for two-way communications with Nagios. There’s also a section on Nagios Event Radio Dispatcher (or NERD) which can be used for a real-time notification system for alerts.

Overall, I would highly recommend this book to any sysadmins looking to implement an excellent monitoring solution that is easy to set up, yet powerful enough through its extensive plugin collection and flexibility. After reading this book I’ve come away with a stronger knowledge of Nagios that will benefit my work in the future.

Note: I was provided with a free eBook to review this book, however, this review is 100% genuine and contains my true thoughts about the book.

Donations Now Accepted

For a very, very long time I’ve put off accepting donations to the site, but with Stripe accepting me into their Australian beta, I’ve decided to sign up and see how it goes.

If any of my articles have helped you out and if you’ve got some coin to spare, help a fellow dev/sysadmin out and donate a caffeinated drink or two! Many thanks.

Donate to yes > /dev/null

Installing the APR-based Tomcat Native Library for Jira on Debian 7 (Updated)

If you’re self-hosting Jira on Debian (or another platform, but this post is Debian specific) you might notice in the catalina.log file a line that reports something like this:

INFO: The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: /usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib

While this message isn’t a bug per se, but if you’re a completist like me, you’ll want to get it installed to speed up performance for Jira.

First up, you’ll want to install Apache Portable Runtime library along with OpenSSL, if you want to use SSL. Using the command line, we’ll install them with apt-get:

apt-get install libapr1-dev libssl-dev

Go through the process of installing the libraries by following the apt prompts. Note that the version of OpenSSL installed is 1.0.1e, but is patched for CVE-2014-0160 aka Heartbleed).

Next, we’ve got to grab the tomcat native library source tarball (tomcat-native.tar.gz) from Jira so we can compile from source. If you installed Jira from the .bin installer, Jira should be installed at /opt/atlassian/jira. From there, you’ll find the tomcat-native.tar.gz in the bin/ folder (full path: /opt/atlassian/jira/bin). To keep the bin directory clean, we’ll extract the tarball to the home folder of the logged in user:

tar -xzvf tomcat-native.tar.gz -C ~

Now if you cd into the home directory (cd then ls -la) you’ll find a directory called tomcat-native-1.1.29-src. We’ll need to locate the configure script that is some where in that folder. Thankfully, I’ve already done the research for you and it’s in jni/native. cd to that location.

Now that we’ve got the configure script, we need to run the script with the appropriate configuration locations and files. At minimum, you should provide the APR location (--with-apr) and the JVM location (--with-java-home). If you installed APR with apt, the APR config binary will be in /usr/bin/apr-1-config.

Next, the JRE/JDK location. Jira comes with a bundled JRE, but it’s not sufficient for the Tomcat Native Library configurator. If you use the Jira JRE path of /opt/atlassian/jira/jre you’ll get the error checking os_type directory... Cannot find jni_md.h in /opt/atlassian/jira/jre when you run the configuration script. To rectify this, you’ll need the OpenJDK JRE for Linux. Once again, using apt we can install it with ease: apt-get install openjdk-7-jre. After that has completed, if you do find / -name "jni_md.h" you should get something like this:

/usr/lib/jvm/java-7-openjdk-amd64/include/jni_md.h
/usr/lib/jvm/java-7-openjdk-amd64/include/linux/jni_md.h

You can use either file, as a diff shows that both files are the same. With that in mind, our configuration variable --with-java-home can be set to /usr/lib/jvm/java-7-openjdk-amd64. Finally, with SSL support, you can safely set --with-ssl to yes as the configurator can guess the OpenSSL settings. With all that in mind, our final configure string will be as follows:

./configure --with-apr=/usr/bin/apr-1-config --with-java-home=/usr/lib/jvm/java-7-openjdk-amd64 --with-ssl=yes

Hit return and let the configure script finish. Now you can finish it off by making and installing by doing the following: make && make install. As we did not specify an installation prefix, the compiled library will be installed at /usr/local/apr/lib. Jira expects the library to be in one of these folders: /usr/java/packages/lib/amd64, /usr/lib64, /lib64, /lib or /usr/lib. I’m just going to copy them to /usr/java/packages/lib/amd64, do that like so:

cp /usr/lib/* /usr/java/packages/lib/amd64

Now you’re done. Simply start Jira using your prefered method and you should find that APR is being loaded correctly. You can verify this by doing cat /opt/atlassian/jira/logs/catalina.out | grep -A 1 "AprLifecycleListener" and you should see something like this:

Jun 02, 2014 4:23:11 PM org.apache.catalina.core.AprLifecycleListener init
INFO: Loaded APR based Apache Tomcat Native library 1.1.29 using APR version 1.4.6.
Jun 02, 2014 4:23:11 PM org.apache.catalina.core.AprLifecycleListener init
INFO: APR capabilities: IPv6 [true], sendfile [true], accept filters [false], random [true].
Jun 02, 2014 4:23:11 PM org.apache.catalina.core.AprLifecycleListener initializeSSL
INFO: OpenSSL successfully initialized (OpenSSL 1.0.1e 11 Feb 2013)

Hooray! Jira is running, and it’s loading the Tomcat Native Library with APR successfully!

Updates

  • 27/09/2014: updated with newest package name and cp path.

OS X Server and Heartbleed

Heartbleed OS X

If you keep up with technical news you would’ve seen an abundance of articles on something called Heartbleed (or CVE-2014-0160). Essentially, it’s a protocol implementation bug that affects newer versions of OpenSSL, which is used in a majority of Linux installations and can affect many services like Apache, nginx and even IMAP (just to name a few). I’m not going to go into the details because I’ll leave that to the experts, but I highly recommend taking a look at the Heartbleed website to learn more.

Now, when I saw this I got immediately worried about all my clients’ (not to mention my own) installation of OS X Server. Thankfully, OS X has an older implementation of OpenSSL (on 10.9.2 it’s 0.9.8y - found by doing this command in Terminal: openssl version) and according to the Heartbleed website, is not vulnerable. Just to make sure, I ran a Python script found online written by Jared Stafford (download) and when against my server at home, I get the following:

Connecting...
Sending Client Hello...
Waiting for Server Hello...
 ... received message: type = 22, ver = 0301, length = 53
 ... received message: type = 22, ver = 0301, length = 2551
 ... received message: type = 22, ver = 0301, length = 525
 ... received message: type = 22, ver = 0301, length = 4
Sending heartbeat request...
 ... received message: type = 21, ver = 0302, length = 2
Received alert:
      .F

Server returned error, likely not vulnerable

Further testing on OS X has revealed that Heartbleed won’t be exposing anything, which is a huge relief for me. Having said that, as this was undiscovered for 2 years, theoretically there’s nothing stopping there being another vulnerability in the wild that could be causing the same (or more or less) damage as Heartbleed.

If you run the Python script and find you are affected, I urge you to patch your OpenSSL installation and regenerate your SSL certificates from scratch. As this vulnerability grabs 64KB worth of data from memory, it’s possible your private key could be in that 64KB. This means you need more than just a CSR, you’ll need to start from the beginning. You can check yourself using an excellent service by Filippo Valsorda.

Good luck out there.

Bryzone - Trial Run / Stargaze

I got an email this morning from Bryzone’s PR team with a link to his debut EP. Normally, when I get a promotional email I tend to ignore them, but with anything music related I got curious. I jumped over to his SoundCloud set page and now I can’t stop listening to it.

I really enjoy Bryzone’s style, it feels similar to Zero T in that it’s almost a blend of chill out/lounge vibes but has the tempo and beats of good old Drum and Bass. The first track, Trial Run, has a great piano melody and Jenny Mayhem’s voice is a killer. I wouldn’t be surprised if she finds herself up there with highly talented DnB vocalists like Diane Charlemagne or Jenna G within a year or two. The second track, Stargaze, has got a real deep house feel - it reminds me of the Jaytech tracks you’d hear on the Anjunadeep label, but instead it also has the backing of a strong DnB groove. Overall, I’m really impressed with his music and I look forward to seeing more of Bryzone in the future.

If you’d like to see more of Bryzone, check out the press release or head over to the SoundCloud EP set page to give it a listen.

I hope to see Bryzone play in Perth, Australia some day because I will definitely be there to watch him groove.

Note: for those who are curious, this was not a payed promotion, I just really like Bryzone’s stuff.

Update: for full disclosures sake, since posting this article I did receive a free copy of the EP from Bryzone’s PR team. Cheers!

Last.fm Album Image Generator

If you didn’t know already, I have run a Last.fm Album Image Generator on my old site for a couple of years now. Recently I started playing with Laravel (Façade controversy ho!) and I’ve really loved it, so I decided to port my image generator over to Laravel, and to open source it.

Number 1 Album
The album artwork for Last.fm

Using Laravel has allowed me to make the service a lot easier to develop, and also extend. I’m taking advantage of the logging and caching features in Laravel, along with using plenty of other fantastic packages from Packagist. Overall, I’ve found Laravel has a gentle learning curve (unlike ZF2) and is easy to get started with. I started with Code Bright which was a really good read and gave me a very good head start in developing with Laravel. Of course, the Laravel docs were very useful, along with my friend, Dr. Google.

If you go to http://lastfmalbumimagegenerator.com (and don’t pass any variables in the query string) you’ll be directed to the generator where you can enter your Last.fm username then hit Generate! and you’ll be given BBCode to put on your Last.fm profile page. Pretty simple really!

Here’s an example of the BBCode you’ll get:

[url=https://lastfmalbumimagegenerator.com?user=yesdevnull&num=1&type=link][img]http://lastfmalbumimagegenerator.com?user=yesdevnull&num=1[/img][/url]

If you’re a developer, I invite you to take a look at the code and submit any PRs for fixes, improvements, enhancements etc.

I hope this service works well for you!

Queens of the Stone Age / Nine Inch Nails

QotSA and NIN

Yesterday night I saw Queens of the Stone Age and Nine Inch Nails at Perth Arena in Perth, Western Australia. Last night was the first time I’ve seen either band live, and they were both fantastic! If you, the reader, ever get the opportunity to see either band in concert, I highly recommend it.

I’ve listened to Nine Inch Nails for a few years and never really saw myself as being able to dance along to their music because, let’s be honest, a fair bit of Trent’s music is very mellow and not exactly dance material. Boy was I wrong — I danced the night away.

The warmup act, Brody Dalle, was pretty good. I’ve never heard her stuff before, but I will definitely be checking her out on Spotify.

Highlights

While the concert was excellent and I loved every song that was played, I do have a favourite song for each set, check ’em out below:

  • Queens of the Stone Age: A Song for the Dead · Runner Up: Little Sister
  • Nine Inch Nails: Head Like A Hole · Runner Up: March of the Pigs

Lowlights

  • Typical stupid drunk idiot antics like pushing and fighting
  • So many people smoking weed in the arena, I walked out at the end of the night stinking of smoke and pot

Using PHP 5.4 cli on Media Temple's Grid Hosting

I recently ran into a problem on Media Temple’s grid hosting where I couldn’t get Composer to run any post-install-cmd scripts. I was racking my brains on why it would be failing, it was working on my dev environment OK!

Composer error
The Composer error in my Terminal.

The problem was that the PHP binary that is at /usr/bin/php via the cli is 5.3.27, which is below my minimum required version of 5.4. Luckily, a much newer version of PHP (5.5.6 at the time of writing, to be precise) is available at /usr/bin/php-latest. The solution was a two pronged approach.

First off, create a bash profile (or edit an existing one) to have an alias to link php to php-latest. You should SSH into your grid server and enter the following commands:

nano ~/.bash_profile

Now, we’ll add the alias:

alias php="/usr/bin/php-latest"

Exit out of nano by pressing ^X (or Control+X), then hit Y to confirm the changes, then press Return to save your changes to the same filename. Finally, type in the command below to make those changes live (otherwise you’d have to log out/in again to see that alias change):

source ~/.bash_profile

You’ll now notice that if you do php -v you’ll be using the PHP 5.5.6 cli binary. Hooray! But, don’t celebrate yet. If you try to run a Composer post-*-cmd script that requires PHP 5.4 (or greater), it’ll fail. Unfortunately, the commands through Composer don’t seem to be able to pick up the bash alias so we’ll have to manually edit the composer.json file to update the binary paths. Once again, jump back to your SSH session (or you could edit it in a text editor):

Before I continue, the composer.json file I’m using is the one for laravel/framework. So, using nano I’m updating each instance of php in the scripts section of the composer.json file, and replacing them with php-latest.

"scripts": {
  "post-install-cmd": [
    "php-latest artisan clear-compiled",
    "php-latest artisan optimize"
  ],
  "post-update-cmd": [
  "php-latest artisan clear-compiled",
  "php-latest artisan optimize"
  ],
  "post-create-project-cmd": [
    "php-latest artisan key:generate"
  ]
},

Save and edit, then enter php composer.phar update and watch as Composer downloads, installs and does its post-install optimisations, all withouts errors!

You can now safely kick back with the knowledge that your PHP cli will be running the latest version of PHP (as available from Media Temple).

Enjoy!

1 2 3 9 10 11 15