Drupal

Drupal security: video example of user account hijacking with XSS

In this short screencast a variety of security holes are shown, as well as some malicious things which are made possible due to these lapses. We'll take a walk-through of two security issues showcased in the vulnerable.module, as well as two other exploits which I put together:
  • User account hijacking via cookie/session XSS thievery
  • User account hijacking via password-changing-inline-XSS

It's worth noting that in the screencast we demonstrate security exploits in the context of a Drupal installation which uses custom code (e.g., the examples in the video do not represent actual vulnerabilities in Drupal core). Likewise, these exploits and security holes potentially apply to any web site, Drupal or not, which accepts user input.

Links
Cracking Drupal (also, my review)
Drupal.org: Writing secure code
xssed.com
2 March, 2010

Simple cross-browser Xdebug helper. Session starter and stopper, no add-ons needed.

During a recent browser upgrade I found myself stuck in a bit of a corner. The Firefox add-on I had been using, Xdebug Helper, was discontinued, and the supposed replacement add-on for it didn't work correctly.

Since the functionality of this now-defunct add-on made my life a lot easier (e.g., don't have to manually append/strip '?XDEBUG_SESSION_START=default' in my browser all day long to start/stop debugging sessions) I took it upon myself to keep this functionality and perhaps get rid of yet-one-more-add-on (which pays off when upgrade time comes).

In all their simplicity, here are two bookmarklets you can use to start and stop a Xdebug session in your browser of choice. Note that if you are using a custom proxy key value then you'll need to change the '=default' part in the bookmarklet to '=YourProxyKey'.

The 'start session' bookmark
Save this bookmark and then all you need to do to start a debugging session (assuming that you have Xdebug setup correctly and a breakpoint set in your code, of course) is to select the bookmark. I chose to put my bookmarks in the Toolbar at the top of window to make it even easier to get to. Also, just for the sake of posterity here is the code for the bookmark.
javascript:(function(){location.href=location.href+'?XDEBUG_SESSION_START=default';})();

The 'stop session' bookmark
Save this bookmark and put it next to your 'start session' bookmark. When you're done with your session, simply click this bookmark and viola. Again, here is the code:
javascript:(function(){var currentUrl=location.href;var gotoUrl=currentUrl.replace("?XDEBUG_SESSION_START=default","");document.cookie='XDEBUG_SESSION=default;expires=Fri, 3 Aug 2001 20:47:11 UTC;host=none;path=/';location.href=gotoUrl;})();

1 February, 2010

Scaling Drupal: HTTP pipelining and benchmarking revisited

UPDATE: I've updated some of the numbers below to reflect corrections for a testing error. Let's just say to be sure not to benchmark with any external links in your test pages (because if you do use external links you'll obviously be benchmarking the external server too, which is not what we want in this case). To summarize the effect of these corrections - having lighttpd in front of Apache and pipelining actually provide a substantially larger boost in performance than I had indicated before. Other than that the results are the same.

So things with my first attempt at benchmarking HTTP pipelining did not go exactly as planned. It turns out that if two different domains/subdomains you are using for content on your site are pointing to the same IP, based on previous testing, it looks like browsers (at least FireFox) will not pipeline requests (e.g., create more concurrent requests to your site) because it considers the requests as being from the same origin. In order for a browser to pipelining requests at all, they seem to require two domains/subdomains which are using two separate/unique IPs. If you read the Wikipedia entry for hostnames this all makes sense, as it indicates domains are associated with IP's, and browserscope's testing of browsers checks for "Connections per Hostname", not "Connections per Domain".

After figuring out how to get requests to pipeline correctly, I re-benchmarked all the configurations from the first article . Everything from that article regarding lighttpd is still holds true, so without covering those aspects again, here's the updated benchmarks and notes for browser request pipelining:

  • Once the conditions for request pipelining was setup correctly there were discernable performance implications. Some of them I definitely wasn't expecting. On the one end of the spectrum, with browser pipelining working (via string replacement of domains within the rendered HTML) and lighttpd serving the static files there was an 11% increase in throughput vs not using the pipelining methods. So static file serving ='s good, and static file serving + HTTP pipelining ='s a little better.

    This is not where the story ends with pipelining however, as there was a net performance decrease by enabling pipelining with all configurations which did not use a separate static file server! (in my case lighttpd on the same machine)

27 January, 2010

Scaling Drupal: Benchmarking static file serving with lighttpd and browser pipelining

I finally had a chance to investigate an optimization which I've been wondering about for a while now - serving static files of a site from somewhere else. As a side, but related, experiment I also tested the claim that serving files from a static file server/separate domain/subdomain will speed things up because it results in browsers opening more concurrent requests than they would from a single domain.

For my tests I used lighttpd (pron. lighty) as a static file server for Apache. The idea is that lighttpd, which is acclaimed as being fast and light on memory, will serve the non-dynamic pages of the site (images, CSS, Javascript, etc), which should thereby help relieve Apache of some of its workload. This arrangement involves changing the paths, either on the backend or frontend, to these static resources so that they no longer get served by Apache.

The pieces
All tests took place on my Macbook Pro and involved two pages on a large Drupal 5 site running Pressflow. For the static file server itself, I installed lighttpd using Macports. Two separate pages of the site were tested, the smaller page's number of static files was in the category of 'average' for most sites. The larger page of the two, was very large - 39 CSS files, 23 Javascript files, and 46 image files.

Methods tested and benchmarked
I implemented and benchmarked the following methods of path modification in order to enable static file serving:

25 January, 2010

Convert your MySQL database from MyISAM to InnoDB, and get ready for Drupal 7 at the same time

If you haven't already heard, Drupal 7 will default to using the InnoDB storage engine instead of MyISAM for MySQL (though a MyISAM database will continue to work just fine in Drupal 7). This is fairly substantial change within Drupal core, and as the thread in the issue queue I linked to shows, there were a lot of questions and apprehension about it. However...

...we are going to just skip over a lot of that apprehension and get down to point of this article - there's no good reason not to hop right into using InnoDB today on your Drupal 5 or Drupal 6 site. The rewards are; a possibly significant improvement in performance, a definite improvement in scalability (most highly trafficked Drupal sites have been using InnoDB for some time now because of this), and you'll start getting used to working with what will be more and more common in your Drupal-life, InnoDB.

My experience
I came to the conclusion about how great InnoDB is after researching the experiences of others, and after converting a large Pressflow-driven Drupal 5 site from InnoDB vs MyISAM. This change resulted in a 14% increased throughput during load tests performed in JMeter. That's a very substantial increase, and while everyone's mileage will vary based on their own site, server, and any number of variables it's clear enough to me that there's nothing to be afraid of as far as InnoDB goes (quite the contrary).

Converting your database to InnoDB
Before you go any further backup your database before doing any steps below. If you 'splode your database for any reason, you'll need it.

Here are the steps:

1. Shutdown MySQL

2. Move/copy/change the name of ib_logfile0 and ib_logfile1 files. (find where MySQL exists on your system - locations can vary greatly). MySQL will recreate these files when you start it up again. Not anytime you change the innodb_log_file_size parameter you will need to shutdown MySQL, move these files, and start up MySQL again.

3. Tune it up a bit
Based on a lot of searching around and benchmarking with JMeter I arrived at the setting below for running on my Macbook Pro. See the links at the end of this post for articles which can help you determine what to adjust these numbers to for other machines (ones with more RAM/CPU, for instance. The production server for this particular site ended up with 5000M setting for innodb_buffer_pool_size. So settings will, and should, vary greatly just depending).

18 January, 2010

"I have an older version Drupal site and I feel stuck between a rock and hard place..."

"Official support status" for various versions of Drupal core:

So, official Drupal.org policy is no support for more than one version back. Many Drupal developers/shops have the same policy as Drupal.org itself - no services, development, or maintenance for legacy Drupal versions.

In a perfect world free of money and time limitations, the benefits of staying with the most current version of Drupal make enough sense. However, the reality is that there are practical reasons to try and stick it out with an older site sometimes. These reasons can include (but are probably not limited to):

  • Older sites which are merrily chugging along. For these sites "upgrading" or "migrating" simply translates into having to paying big money just to have the same exact site they have now, only with a newer Drupal version number next to it.
  • Older Drupal sites of such customization, scope, and/or scale that upgrading them would be unmanageable in the near term. I worked on such a site for 4 years. With over 30+ custom coded modules (not just downloaded modules from Drupal.org), upgrading to a new version of Drupal would have taken hundreds if not thousands of hours.

Drupal project lead, Dries Buytaert, recently called for more developers to go after niches within the Drupal ecosphere. I believe serving users of older Drupal sites could be a valuable one to some Drupal users, as well as to the Drupal project itself.

As a fan of older Drupal versions and as someone who has spent a lot of time working with them (and yes, plenty of time working with newer Drupal versions), I'm throwing my hat into the ring to try and assist these particular Drupal users. If you have an older Drupal site (or know someone with one) which needs development, support, maintenance, or server administration drop me a line.

9 November, 2009

Pages

Subscribe to RSS - Drupal