Content Security Policy update

A quick update about CSP. Browsers are well on their way to all adopt the specification.

An early draft was already adopted by Firefox 4, and I just found out that it's also working in Chrome, Safari and IE 10.

IE10 and FF are using the following header:

  1. X-Content-Security-Policy: default-src 'self'

While Safari and Chrome use:

  1. X-Webkit-CSP: default-src 'self'

When the specification is finalized, the X- will be dropped, and it will simply be 'Content-Security-Policy'.

A call for support

Hi Developers! Start implementing this feature! It's important for the future and security of the web. The web's biggest vulnerability, from what I understand, is still XSS, but if people start to properly implement CSP, XSS can effectively be a thing from the past.

So even if you don't want to risk using CSP on a production environment, at least consider adding the headers in your development environment. It will force you to write better code, by not embedding javascript directly into the HTML source. By considering this right now, you will also make it much easier if you do decide to adopt CSP at some point in the future.

I'm implementing CSP full-on in a new project, and one of the things I've noticed already is that some of the javascript we embed from 3rd parties use eval() and inline html events (onclick & friends). For the sake of security we will most likely decide to only use 3rd party code if they are indeed CSP-compatible.

What happened to HTTP authentication?

Rant warning

We enter our usernames and password on pretty much all the sites we commonly visit. Authentication is probably one of the first things you're being taught when starting to work with PHP. For some reason, in 99% of the cases this is done through an HTML form, with the username and password submitted as a urlencoded string.

You probably know that HTTP also has native authentication, in the form of Basic and Digest authentication (read my older article if you want to know how). Every browser and pretty much any HTTP client does too. There's some big benefits to that, because it provides a very standardized mechanism to authenticate a client, whether you're a machine or human.

What baffles me is that HTTP authentication hasn't been developed further. HTTP Digest is pretty secure by itself, and has some nice features (hashed password, protection against man in the middle and replay attacks, message digests) which is way more advanced than an HTML POST form with a session cookie can provide.

What's missing?

  1. There's no way for a user to see if they are authenticated to a site. Perhaps a username in the addressbar?
  2. Pretty much everybody always wonders how they can code a logout mechanism. Because there are no session cookies that can be destroyed, there are some hacks that trick the browser to ask for credentials again. There should be no need for the server to provide this functionality. The browser knows it's logged in, and HTTP applications are stateless. We need an in-browser log-out button.
  3. Less important, some javascript hooks that allow developers to still use html forms to setup HTTP authentication.

Mozilla is doing some interesting things with their Account Manager Add-on for firefox, but even that add-on does not support HTTP authentication. With Account Manager they are jumping through some hoops with javascript hooks so it works with regular authentication systems, but you'd think that if HTTP Authentication was used, things could be a lot more straightforward. The browser knows exactly who is logged in.

So, does anyone know how this happened? Is there a major flaw in HTTP authentication I'm just missing?

Goodbye old Firefox profile

My firefox was getting a bit sluggish, which sucks.. because it's still my favourite browser. Today was just a disaster. The entire browser would just hang for seconds at a time, slow startup times.. etc.

I realized that firefox was running on a profile I made 4 years ago. It has seen Firefox 2.0 up until 3.6, as well as some beta and minefield builds. Dozens of add-ons have been installed, updated, removed and installed again and it has been migrated to 3 different computers. This couldn't be good for performance. Who knows what kind of settings, files and data is left hanging here and there.

So I went ahead today and created a new firefox profile. This is simply done by starting firefox with the --profilemanager argument.

I needed my bookmarks, history and saved passwords though. To get these 3 items, copy the following files from your old, to your new profile (while firefox is not running!).

  • places.sqlite - Contains history and bookmarks.
  • signon.sqlite - Contains all your saved passwords.
  • key3.db - Contains the encryption keys to decode your passwords.

After that, it was just a matter of installing Firebug, Firecookie and noscript again.

Right now the browser feels like new again. If you're seeing similar problems, I can highly recommend it.. but I can't be help responsible for losing any of your valuable data.. make backups! Your new profile will also have none of the customizations you've ever made.

Some links

<input type="email"> and Firefox Contacts Add-on

Mozilla Labs

Yesterday Mozilla Labs published the Contacts add-on, which I think is pretty neat. The add-on integrates your existing (Twitter, Gmail and AddressBook.app) contacts into your browser. It's pre-alpha stability, but it seems to work for me.

After installing it, it allows you to use contacts in two new ways:

  1. Any <input type="email" /> field will now auto-complete with the contacts in your list.
  2. A javascript api is added, allowing you (the developer) to pull in contacts from the user. The api is in the W3C standards track.

I love seeing these types of bite-size non-obtrusive features getting implemented in the browser.

The <input type="email" /> form element is specified in the HTML5 specification, but it mostly discusses validation & sanitation. It has been supported by Opera for a while, and Safari now does too. Any old browser will also gladly accept type="email", because the behaviour for unknown types has always been to revert to type="text".

So the next time you're asking your users for an email address, consider using type="email", which automatically makes you future compatible when all the browsers get around implementing it.

Frame busting and clickjacking prevention

Clickjacking allows an attacker to trick your users into clicking parts of your interface without their consent. A simple way to describe describe this is, an attacker will embed your application in their site as an iframe. On top of the iframe they can show a completely different interface. You're thinking you're clicking buttons on your own interface, while in fact you are hitting the 'Delete my account' button in for example GMail.

Because this technique completely operates with frames, it can be circumvented by using a 'Frame busting' technique. As a bonus, this will also disallow for example Digg to steal and monetize your content.

Frame busting can be achieved with a simple javascript technique:

  1. <script type="text/javascript">
  2. if (top !== self) top.location.replace(self.location.href);
  3. </script>

Security through javascript?

If you think this sounds like a bad idea, you are probably right. Users might simply have javascript disabled, and I also don't like relying on UI developers too much to implement preventive security measures (although I realize in most cases you do have to).

In Internet Explorer the situation is worse, IE allows you to specify the non-standard attribute security="restricted":

  1. <iframe src="http://www.rooftopsolutions.nl/ security="restricted"></iframe>

This attribute tells IE to not allow executing of javascript in the iframe, which actually is not a bad security measure for other types of attacks. In this case however, it allows the attacker to disable the framebusting script.

X-Frame-Options

Thankfully, Internet Explorer 8 introduces a new feature that allows the site owner to disallow frames altogether, which is in my opinion an even better protection mechanism, because it doesn't rely on javascript to be executed.

The name of the http header is specified as such:

  1. X-FRAME-OPTIONS: SAMEORIGIN
  2. X-FRAME-OPTIONS: DENY

You only have to specify one of these two, 'sameorigin' means the page can only be framed from an html page hosted on the same domain, deny will kill framing altogether.

PHP example:

  1. <?php
  2. header('X-FRAME-OPTIONS: DENY');
  3. ?>

Firefox also appears to have started implementing this feature, and there's a feature request for webkit open as well.

Protecting yourself

Unfortunately you can safely assume most sites don't implement either of these security measures. For firefox users I would therefore strongly recommend using the NoScript plugin. Not only does it implement the X-FRAME-OPTIONS for firefox, it also actively detects clickjacking attempts.

Reference: hackademix.net

PHP Quicksearch in firefox

If you're a PHP developer, you'll likely often need to open up php.net to find out the [the order of ;)] arguments for a function.

Generally i just type, php.net/functionname, but if you want to save 4 more keystrokes you can easily add a quick search. Just open up your bookmarks (or places if you're on FF3). And add a new bookmark to the Quick Searches folder.

PHP quicksearch

Use 'php' in the keyword field, and for the url, use:

  1. http://www.php.net/search.php?show=quickref&pattern=%s

Now, you can simply type php in_array in your address bar, and you can find out if the needle or the haystack comes first.

p.s.: similarly, the 'slang' quicksearch has helped me adjust to north america a lot ;)
p.p.s.: lovin' the firefox 3 experience on beta, can't wait for all the extensions to work..

My Firefox extensions

Firefox

And now for something completely off-topic. Which firefox extensions do you use? I'm mostly interested in the extensions that help web development in one way or another.

  • Firebug - Anyone who is into web development, and not using firebug should be hit the face with a stick or something pointy.
  • NoScript - If you are a web developer, you know you can't trust 90% of the other developers on the web. This extension prevents you from suffering from other peoples mistakes. As a bonus it also works like an ad-blocker. Because most ad-solutions use flash and/or javascript, you can easily block out certain domains.
  • Web developer toolbar - Easy access to a lot of web developer tools. A lot of the features can also be achieved with Firebug, but I still like this one, because most tools are 2 clicks away.
  • Whatmon - Monitor whatever. This is a really small extension that allows you to display a status of "whatever you want". All it takes is to generate a tiny XML document and you'll have it up and running.

Aesthetics

  • Stop or reload - Merges the stop and reload button, because you never need both at the same time.
  • Growl download notification - I like growl for all notification-style messages and I try to find plugins for every program it might be useful.
  • History submenus - For a safari-style history menu.
  • OS/X favicon theme - This firefox theme is exactly like the default firefox theme, except that it displays favicons in your bookmark toolbars, like on Windows and Linux.

Firefox gets httpOnly cookies

httpOnly cookies allow you to hide your (session-)cookies from javascript. In the case of an XSS hole in your application, it will make a hackers life much harder to steal someones session.

Internet Explorer support httpOnly cookies for a long time, but since version 2.0.0.5 Firefox also supports this feature. Apparently Mozilla hasn't openly promoted this new feature yet, because its still possible to fetch the cookies with XMLHttpRequest. PHP has support for httpOnly cookies and sessions since 5.2.

Exploring OpenSearch

OpenSearch is a pretty cool new technology which will soon be available to mainstream with the release of Firefox 2.0 and Internet Explorer 7.

Most of the browsers nowadays come with a search bar in the top-right, this was pretty quickly adopted after a big group of users started installing toolbars for easy searching.

OpenSeach allows web developers to integrate with the built-in browser search.. If you go to a site like technorati.com it will give you the option to add technorati to your search tool..

I did the same thing for FileMobile (currently only on dev servers, will appear shortly), and here's how it looks like:

OpenSearch in IE7
Internet Explorer 7 was a little bit buggy, because I could only use the search after I added it to my search providers. If I tried to just select it, it wouldn't work. I'm sure this will be fixed once IE7 is released.

OpenSearch flashing thing in FireFox 2FireFox 2 worked without problems, it first displays a different color for the search button to indicate the current site has opensearch enabled.

OpenSearch in FireFox2 (image2)The only thing I didn't really like is that it doesn't give me the option to do a single search on a site; I have to add it to the search providers first.

OpenSearch in Amazon A9 toolbarThe people who invented OpenSearch provide a toolbar that works in various browsers.. It actually didn't work for me at all, but I'm assuming this is because they don't support FireFox 2.0 yet, which is at the time of writing also beta..

Implementing it yourself is not hard.. and auto-discovery for your homepage works in a similar fashion as doing it for RSS. Simply put this in your <head> section of your html..

  1. <link rel="search" type="application/opensearchdescription+xml" title="My Search" href="http://www.example.org/osd.xml" />

The osd file (OpenSearch description file) is pretty straightforward too, you can find technorati's here. And mine looks like this:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">
  3. <ShortName>FileMobile Search</ShortName>
  4. <Description>Search FileMobile Media</Description>
  5. <Image width="16" height="16" type="image/vnd.microsoft.icon">/favicon.ico</Image>
  6. <Url type="text/html" template="http://www.filemobile.com/community/media/?q={searchTerms}&amp;page={startPage?}" method="get"/>
  7. <Url type="application/rss+xml" template="http://www.filemobile.com/services/rss?q={searchTerms}" method="get"/>
  8.  
  9. </OpenSearchDescription>

You can specifiy multiple images, right now I have only specified my favicon, but it is recommended that you also add in a 64x64 jpeg or png.

The URL part is the page where people will be taken to if they search for something, I added in links for a html result page (text/html) and one for a RSS feed. When a user is searching {SearchTerms} will be substituted by the user input..

This should be enough to get you started. Be sure to check out the full specs at A9.

On HttpOnly, Firefox-specific XSS and this years major Livejournal XSS attack

Yep, thats a long title, but they are all related to each other in some way. In the first few paragraphs I will explain what cookies are and XSS. You might want to skip ahead if you already know what this is.

Sessions, Cookies

HTTP is stateless. This means that every request to the server is a 'new' one and normally there is no relation to a first or second request. To allow maintaining a session or 'state' between multiple requests, HTTP cookies are used.

A cookie is basically a HTTP header with a tiny piece of information that gets re-sent with every request to the server. A popular way to make use of this is through PHP's$_SESSION system. This sends a cookie with a unique id to the client that allows PHP to retain a users' information across pages.

XSS

If you allow users to for example comment on one of your pages and allow (certain) html, it is sometimes possible to inject a piece of javascript. There are many tricks to evade the so-called html sanitizers.. strip_tags() is PHP's built-in sanitizer, but it doesn't work really well.. if, for example, you would allow users to use a <p> tag, which might seem harmless, there would be tricks to abuse the style="" or onclick="" attributes, just to name a few.

XSS and cookies

So how do you abuse javascript and cookies combined?

Because with for example PHP's session system, you can use the contents of the cookie to steal someone's session. The hacker would be logged in as you and might able to change your password and log you out afterwards. The contents of the cookies is stored in the javascript variable document.cookie.

HttpOnly, a solution

Microsoft came up with a way to prevent this from happening, ever since Internet Explorer 6.0 (starting from Windows XP SP1). They added an extra piece of information to a cookie, that will still allow the use of cookies in the way you are used to, but it will prevent the cookie from being read by javascript (basically it is invisible for javascript). Be sure to check out microsofts spec at MSDN

Safari and Opera quickly started supporting this. Because of this it is becoming pretty useful to use in practice. Remember that this doesn't mean you can just accept any html on your site, you should still always sanitize the bad stuff or not allow it at all! But in the case you missed something, it can make it a lot more difficult for your attacker to steal sessions.

UPDATE: Safari/Opera actually ignore it, my excuses, I didn't check my sources.

Under the hood

Normally, a cookie header will look like this:

  1. Set-Cookie: USER=username; expires=Wednesday, 09-Nov-99 23:12:40 GMT;

But with the HttpOnly, it will look like this:

  1. Set-Cookie: USER=username; expires=Wednesday, 09-Nov-99 23:12:40 GMT; HttpOnly
.

It's a small change, and all normal browsers should still accept this even if they don't understand the HttpOnly part. There is an exception though, and it goes by the name of IE 5 for mac. This browser won't understand the cookie and totally ignores it. Personally I don't support this browser for any application anymore, as there are too many bugs in this browser. But if your boss wants it, this might prevent you from using HttpOnly

PHP support

A guy named Scott MacVicar created a patch for PHP that will add an extra parameter to set_cookie() to enable HttpOnly for your cookies. The patch should also enable this by default for the session system.

If the patch will get accepted we will likely be able to use this in PHP 6.0 and perhaps even PHP 5.2, I'm looking forward to that. There is a chance though, because of the IE5/mac breakage that it eventually won't be auto-enabled for the session system.

So what about firefox?

Firefox doesn't support it, there is currently a bug open for it (Bug #178993). There was an initial solution posted over 2 years ago (January 2004). And a few other patches later on, but the mozilla folks refused all of them because they want to maintain the exact format of cookies.txt (the file they use to store cookies), because other applications might rely on that format. A few solutions for that have been posted, but it doesn't seem like a high priority for them.

A workaround for firefox (kind of)

There have been solutions for firefox that also blocked reading of cookies by javascript. Firefox has a magic function __defineGetter__ that can block reading of variables. To do this for all cookies on your site, include the following snippet on top of your html page:

  1. HTMLDocument.prototype.__defineGetter__("cookie",function (){return null;});

However, you can't rely on this! There are still ways to get this cookie if the hacker can somehow create an iframe in your html page. The hacker has a reference to the same cookies if he uses the data: protocol in the src="" attribute. This will still make it a bit harder to steal cookies, so it's not a bad idea to implement. For a longer explanation of this workaround, check out http://www.wisec.it/sectou.php?lang=en.

The LiveJournal case

The same people who submitted the initial firefox-patch (see above) 2 years ago, also got hit by the attack in January 2006. Over 46% accounts were hijacked. This were over 900.000 stolen accounts. (check out their post about their solution.)

The reason they got hit by this is because they allowed users to use remote CSS stylesheets for their pages. CSS used to be only a specification for how html elements would look like on a page, but since a few years it has become more dynamic and now there are ways to exploit CSS with XSS attacks through for example IE's non-standard behavior: attribute and Firefox' -moz-binding: attribute (there are more you can exploit, but its outside the scope of the article). These attributes allow an author to create a custom behavior for a HTML element. The technique to do this for Firefox is called XBL.

Normally, when a page is loaded from domain A, and another (in a different frame for example) is loaded from domain B. Malicious scripts from domain B can never access cookies from domain A. This is called a 'same origin check'. This generally works in all browsers for all kinds of content, but an exception is XBL. (see bug #324253.)

Apparently this requires some major changes in how firefox works. The last comment in this bug is from February this year (2006). I hope they will wake up some day soon and make our life a little bit easier by both supporting HttpOnly and securing XBL.

So the LiveJournal attack could happen because the hackers used XBL in their CSS, which in turn accessed the HTTP cookies through javascript. The attack didn't affect users of other browsers, because: A) they support HttpOnly, B) even if they wouldn't.. the microsoft equivalent of XBL, which is .HTC files, don't work across different domains.

 1 2 Next →

About

My name is Evert, and I've been writing semi-regularly on this blog since 2006.

I'm currently available for contract work.

more info.

Subscribe

Dropbox

Dropbox is a simple cross-platform online backup and sync application. The first 2GB of space is free, and both you and me get an extra 250MB extra space if you sign up through this link.