Nick Carroll Software Professional

Protect your Play! application with the CSRF filter

Play! 2.1 introduces a new filters API and Cross Site Request Forgery (CSRF) protection. The CSRF filter is not well documented and it took a while to work out how to enable it in my Play! application. It took a bit of digging through the Play! source code and looking through the CSRF tests to work out how to use the CSRF filter. Below is a summary of what is required to protect your Play! 2.1 application with the new CSRF filter.

First of all add the filters module to your app dependencies in appname/project/Build.scala.

import sbt._
import play.Project._

object ApplicationBuild extends Build {

  val appName         = "appname"
  val appVersion      = "1.0-SNAPSHOT"

  val appDependencies = Seq(
    // Add your project dependencies here,
    jdbc,
    anorm,
    <strong>filters</strong>
  )
}

Next create appname/app/Global.scala and extend the Global settings so that it uses the CSRF filter.

import play.api.mvc._
import play.api._
import play.filters.csrf._

object Global extends WithFilters(CSRFFilter()) with GlobalSettings

Now the CSRF tests will convey that you need to do the following in all your controllers that return a view with a form post.

def index = Action { implicit request =>
  import play.filters.csrf._
  Ok(views.html.index(CSRF.getToken(request).map(_.value).getOrElse("")))
}

and use the CSRF token in your view template as follows.

@(csrf: String)

@main("Welcome to Play 2.0") {</pre>
<style type="text/css" media="screen"><!--
      label{display: block}

--></style>
<div>
<h2>With token</h2>
<form accept-charset="utf-8" action="@routes.Application.save()?csrfToken=@csrf" method="post">
<label for="name">Name:</label><input id="name" type="text" name="name" value="" />

<label for="age">Age:</label><input id="age" type="text" name="age" value="" />

<input type="submit" value="Continue →" /></form></div>
<pre>
}

Relax you don’t have to call CSRF.getToken() in all of your controllers that present a form. Fortunately there is a CSRF view helper that takes an implicit token so that you won’t need to set up the token in your controller and pass it to the view. Instead you just have to declare the implicit token in the view and wrap your post action with the CSRF helper function as follows.

@(signInForm: Form[(String,String)])(implicit token: play.filters.csrf.CSRF.Token)
@import helper._

@implicitFieldConstructor() = @{
    FieldConstructor(bootstrapInput.render)
}

@main(Messages("shopanoptic")) {
    <div class="offset3 span6">
        <div class="well">
            <h3>@Messages("signin")</h3>

            @form(CSRF(routes.Session.authenticate()), 'class -> "form-vertical") {

                @signInForm.globalError.map { error =>
                    <p class="error">
                        <span class="label important">@error.message</span>
                    </p>
                }

                <fieldset>
                    @inputText(
                        signInForm("email"),
                        'placeholder -> Messages("email"),
                        '_label -> null,
                        '_help -> Messages("signin.your.email")
                    )
                    @inputPassword(
                        signInForm("password"),
                        '_label -> null,
                        'placeholder -> Messages("password"),
                        '_help -> Messages("signin.your.password")
                    )
                </fieldset>

                <div class="form-actions">
                    <input type="submit" class="btn btn-primary" value="@Messages("signin")">
                </div>
            }
        </div>
    </div>
}

Now you can protect your web application from one of the OWASP Top 10 security vulnerabilities.

Setting up VMWare shared folders on Ubuntu guest

For some reason Ubuntu 12.04 is unable to complete the VMware tools automatically. I discovered this by checking if the hgfs module was loaded using the following command.

$ lsmod | grep vmhgfs

And got a bunch of errors when trying to load the module.

$ modprobe vmhgfs

To install VMware tools follow the below instructions.

In VMware Fusion click on Virtual Machine -> Reinstall VMWare Tools. This will attach the VMware tools ISO to a CDROM on the guest VM. Mounting the CDROM doesn’t seem to automatically work on my set up so I had to manually mount it with the following command.

$ sudo mount /dev/cdrom1 /media/cdrom

Tip: You might need to try /dev/cdrom if /dev/cdrom1 doesn’t work for you.

Next you need to install linux headers and build essentials. Use the following commands to install these packages.

$ sudo apt-get install build-essential $ sudo apt-get install linux-headers-uname -r

Now copy the VMwareTools tar ball to your working directory, and install it.

$ cp /media/cdrom/VMwareTools-.tar.gz . $ tar zxvf VMwareTools-.tar.gz $ cd vmware-tools-distrib $ sudo ./vmware-install.pl

This should initiate the install and configuration settings. I just accepted all the default values.

Now you should be able to access your host’s shared folder at /mnt/hgfs.

Fast NTLM authentication proxy with tunneling

If you are using Linux behind a corporate firewall that only supports Windows, and the Windows proxy authentication is causing you pain, then I suggest installing and using CNTLM.

The problem I was experiencing behind my corporate firewall is that I need to authenticate using the windows domain prepended to my username. It seems that you are not able to have a backslash in your username when setting your http_proxy environment variable using the below format.

http://username:password@host:port/

In other words I was getting strange errors when using the following in my .bash_profile.

export http_proxy=http://domainusername:password@host.com/

You can’t escape the backslash, nor wrap everything in quotes etc. The only solution I came across was to use an NTLM authentication proxy such as CNTLM, which is a fast NTLM authentication proxy written in C. The Ubuntu package is described as follows.

Cntlm is a fast and efficient NTLM proxy, with support for TCP/IP tunneling, authenticated connection caching, ACLs, proper daemon logging and behaviour and much more. It has up to ten times faster responses than similar NTLM proxies, while using by orders or magnitude less RAM and CPU. Manual page contains detailed information.

It can be installed using the command, but you’ll need to do this when you are connected directly to the internet, and thus bypassing your corporate proxy!

sudo apt-get install cntlm

You will then need to configure CNTLM by modifying the config file at /etc/cntlm.conf. You’ll need to specify your windows domain login credentials in the config file.

Once configured, restart CNTLM using the command:

sudo /etc/init.d/cntlm restart

Once CNTLM has been configured and restarted, you can then update your http_proxy settings to use http://localhost:3128, or whatever port number you used in the CNTLM config file. By default CNTLM listens on port 3128. Now you will be able to use apt-get, but this time behind your corporate proxy.

Persisting managed objects with scalar attributes

Core Data natively supports attributes that are of type NSString, NSNumber, or NSData. You can however use other types with a bit of extra work. If you have an attribute that is a scalar value such as BOOL, you can have your managed object persist it by first converting it to a NSNumber. For example, CheckBox is a NSManagedObject with an attribute called checked that is of type BOOL. BOOL in Objective-C can easily be converted to and from a NSNumber.

The header file contains the BOOL attribute for CheckBox.

// CheckBox.h
#import <CoreData/CoreData.h>

@interface CheckBox : NSManagedObject {
}
@property(nonatomic) BOOL checked;

@end

The implementation file contains a PrimitiveAccessors category for the underlying primitiveChecked value, which stores the checked value as a NSNumber. We then override the accessors and mutators for the checked attribute to convert the BOOL value to and from a NSNumber.

// CheckBox.m
#import "CheckBox.h"

@interface CheckBox (PrimitiveAccessors)
@property (nonatomic, retain) NSNumber *primitiveChecked;
@end

@implementation CheckBox

- (BOOL)checked {
    [self willAccessValueForKey:@"checked"];
    BOOL isChecked = [[self primitiveChecked] boolValue];
    [self didAccessValueForKey:@"checked"];
    return isChecked;
}

- (void)setChecked:(BOOL)isChecked {
    [self willChangeValueForKey:@"checked"];
    [self setPrimitiveChecked:[NSNumber numberWithBool:isChecked]];
    [self didChangeValueForKey:@"checked"];
}

@end

Gradle Android Plugin

I have recently joined a newly formed team developing Android applications at a large telco, and I am pleased to announce that we are using Gradle for our builds. We are using Gradle with the Android plugin, and instantly we managed to build a simple application, run tests, and have it installed on a device. Our build script simply looks like the following, which is all that is necessary to use the Android plugin.

buildscript {
  repositories {
    mavenRepo(urls: 'http://jvoegele.com/maven2/')
  }
  dependencies {
    classpath 'com.jvoegele.gradle.plugins:android-plugin:0.8'
  }
}
usePlugin com.jvoegele.gradle.plugins.android.AndroidPlugin

Of course this is a rather simplistic script, but it does everything I need it to do right out of the box. The Android plugin provides a number of tasks that allow you to build, test, package and sign your application. You can even install the packaged application on a device or emulator by running gradle androidInstall. Make sure to set the property “adb.device.arg” to “-e” for a running emulator or “-d” for a connected device.

There is also support in Hudson to trigger a Gradle script. Hudson has a Gradle plugin that can be installed from the Admin console, and allows you to directly trigger a Gradle script in your project. Otherwise you can create a simple shell script to call the Gradle tool from the command line.

It is also worth noting that both IntelliJ and Eclipse provide support for Gradle and the Groovy syntax. That is if you don’t like using the command line to trigger your builds.

Gradle has allowed us to spend less time setting up our build and continuous integration environment, and more time on actual Android development. Our team has benefited greatly from this boost in productivity.