GCHQoogle: so much for "Don't be evil" So, unless you’ve been living under a rock for the past few months, you will be aware of the disclosure, by one Edward Snowden, of a massive multinational criminal conspiracy to subvert the security of internet communications and place us all under surveillance.

Even if you believe the security services won’t misuse this, what GCHQ can figure out, other criminal organisations can as well, so like many others, I’ve decided this’d be a good time to tighten the security of some of the sites I am responsible for.

Enabling HTTP Strict Transport Security

So, lets start off by making sure that once you end up on the secure version of a site, you always get sent there. For most sites I had already had a redirect in place, but this wouldn’t help with a number of threats. Thankfully, modern browsers support a header, that when received, will cause the browser to rewrite all connections to that site to the secure endpoint before they are sent.

A quick and easy win, so in my apache conf I placed:

Header add Strict-Transport-Security "max-age=15768000; includeSubDomains"

Auditing my SSL configuration, enabling forward secrecy

The next step was to examine the actual SSL/TLS configuration used by the various servers.

During the initialisation of a secure connection, there is handshake that takes place which establishes the protocol used (SSL / TLS), the version, and what algorithms are available to be used. The choices presented have an effect on exactly how secure the connection will be, and obviously, older and insecure protocols and weaker algorithms present security risks.

I have been, I admit, somewhat remiss in the past, and have largely used Apache’s defaults, which was ok for the most part, but as SSL Lab’s handy audit tool revealed left a number of weak algorithms available as well as not taking advantage of some newer security techniques.

I quickly disabled the weaker algorithms and SSL protocols, and also took the opportunity to specify that the server prefers algorithms which support Forward Secrecy.

Forward secrecy is a property of newer algorithms (supported, sadly, only by newer browsers), that means that even if the key for a given session has been compromised, that key could not be used to decrypt any future sessions. This means that even if the attacker compromised one connection, they would not be able to compromise any past or future connections.

Here is a handy guide for implementing this on your own server.

The downside of these changes of course is that older browsers (IE6, I’m looking at you) are left out in the cold, but these browsers (IE6, I’m still looking at you) are using such old implementations with weak algorithms, they would likely be in trouble anyway.

Security is a moving target, so it’s important to keep up to date!

Update: If you’re running Debian (as I am), you will have some issues with ECDHE suites until stable updates to Apache 2.4. Until then I’ve tacked on AES support at the end, to support IE with something reasonable, but giving forward secrecy to more modern browsers.

Update 27/6/14: Debian recently backported a few 2.4 cipher suites into the 2.2 branch in debian stable. This means that Perfect Forward Secrecy is now supported for Internet Explorer!

As with the code I’ve released previously, I have found myself cutting and pasting this code about the place again and again, so I’ve packaged up my simple PHP template framework and stuck it on github.

This library comes complete with a basic HTML5, JSON, and JSONP templates, that you can extend and override, making the development of web applications (hopefully) slightly easier. It does for me at any rate, because I really hate repeating myself!

Usage

The default template engine provided by this library – the Basic template – should be fairly familiar to anyone who’s used Elgg or similar systems.

You initialise it with a set of template base paths (“base” provides a basic HTML5 hierachy). If you pass an array to the constructor, each array overrides the one preceding it, and so you can replace some functionality (for example providing a bootstrap layout) without having to replace everything.

Views are in a file hierarchy off of [basepath]/[template_type]/path/to/view.php, and are named simply as the path without the base gumph (in the example I give in the docs, this view would be ‘path/to/view’).

HTML5 versions of pages are in the /default/ template type branch, but the basic template comes with json and jsonp encoding of the pages, you can specify which template to use at runtime by passing the _vt=[branch] variable on the GET line, or from within your program code.

The basic template also makes a call to the simple event dispatcher before and after a given view is generated, passing “view:[viewname with colons instead of slashes]” as the namespace and either “prepend” or “extend” as the event, together with an array of all the variables passed to the view.

So, to listen to my documented example, you’d listen for events on “view:path:to:view” and either “prepend” or “extend”, echoing any extra stuff you want.

Anyway, hopefully this’ll be useful to someone!

» Visit the project on Github...

So, another in a series of posts where I package up some code I often use into a reusable library, let me introduce a simple PHP library for creating virtual pages.

Virtual pages are pages on a website that are generated in code, and are sent to the client’s browser, but don’t correspond directly to a physical file. This process requires mod_rewrite on Apache, but similar functionality exists in other web servers.

Defining your endpoint

You must specify your endpoint, and then a handling function. This function can be anything callable; functions, methods or an enclosure.

\simple_page_handler\Page::create('my/page/', function($page, array $subpages) {
        // Your page handling code
});

Writing your endpoint handler

You then trigger the handled pages by writing a page handler, and then directing Apache to redirect unhandled requests to this endpoint.

Example endpoint:

try {
        if (!\simple_page_handler\Page::call(\simple_page_handler\Input::get('page'))) {
            \simple_page_handler\Page::set503();
            echo "Something went wrong.";
        }
} catch (Exception $e) {
    echo $e->getMessage();
}

And your redirect code:

# Redirect anything that isn't a real file to our example page handler
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f 
RewriteRule ^(.*)$ example_page_handler.php?page=$1 [QSA]

Hopefully this’ll be useful to someone!

» Visit the project on Github...