Want to get Lullabot article, videocast, and podcast announcements delivered right to your in-box? Let us know your email address (we won't share it) and we'll let you know when anything exciting happens.

Is that site running Drupal?

Various attempts at "fingerprinting" a Drupal site have been tried in the past, none of which are completely fool-proof.

These range from *super* easy stuff like checking for CHANGELOG.txt to checking the source for a reference to "drupal.css" (Drupal 4.7) to checking for common paths like taxonomy/term/1, and /user, (which might be aliased to something else with something like Pathauto/Path Redirect module), and so on.

However, since Drupal 4.6, there's a super geeky trick you can use to fingerprint a Drupal site that works 90% of the time.

  1. Get Firefox.
  2. Get the Live HTTP Headers extension.
  3. After restarting Firefox, click Tools > Live HTTP Headers. This'll pop up a little window to the side.
  4. Visit a website you suspect of being Drupalish. You know, like http://drupal.org/ (except, you know, I bet they're running WordPress...).
  5. Highlight the Live HTTP headers window and type "exp", looking for the following in the output:
    Expires: Sun, 19 Nov 1978 05:00:00 GMT
    You know, like so!
    Fingerprinting Drupal

Update 2008-May-31 Or! For you command-line junkies out there, check out TBarregren's helpful bash script which allows you to just do ./is-drupal www.lullabot.com - Awesome!

By the way, this date has special significance in the Drupal community. Anyone know why? ;)

Hat tip to chx for this trick. :)

Comments on this post will automatically be closed three months from the original post date.

Comments

Might it have something to

Might it have something to do with this fellow?

Well, this plugin sure detects that Drupal!

Well, this plugin sure detects that Drupal:

http://www.backendinfo.com/

It's a firefox extension and at least verifies that this is a version of drupal, althought it fails at finding the specific version.

Cool plugin

That's a cool plugin. I admire Angie's tip and the ingenuity, that might come in handy one day, but I must say that the backendinfo plugin wins for convenience. Angie's way requires a plugin anyway.

Great tool!

Great tool! It defines the versions as well now. Thanks for that.

Why only 90%?

Why only 90%?

Probably 99.99999%

But always safer to be conservative. ;)

Oh joy.

How convenient for script kiddies. Now they have one more litmus test to find sites vulnerable to the next 0-day exploit.

No problem...

A quick hack to /includes/bootstrap.inc takes care of that. Set it to your own birthday instead of Dries'.

How is this convenient? It

How is this convenient? It is much easier to write a bot that scans sites for certain URLs. People who want to harm other sites will find enough sites that way.

Agreed; additionally...

This is pretty safe as fingerprints go. It only identifies the presence Drupal itself, not any particular version (other than "4.6 or newer," which should hopefully be *all* Drupal sites by this point ;)). Script kiddies really need to know the version of Drupal down to the point release (4.6.9) in order to do anything really damaging.

I disagree

The version does not need to be known to the point.

The kiddie has a script that hacks version 5.4.2 and 6.6, he runs them. That's it. If it works, he knows you have one of those versions. And if you have 6.8 or 5.4.6 then the script fails, so what? The attack is still an attack.

Actually, whether it is a Drupal in the first place does not matter at all. The script can still be run against all sites (you have a WordPress anyway, don't you? 8-) )

Alexis Wilke.

Hide Drupal-specific URLs too?

Perhaps Drupal-specific URLs could be done away with or hidden then too? I like the idea of obscuring the software running the site.

Cool trick

And is there a good way to figure out the version number?

Patch

A cracker tip!

Thanks Angie. I have been looking for an answer to this question for some time. I'm pretty non-technical so a simple tool like this is most welcome.

Before you go blaming Angie for helping script kiddies...

... you should know that there have always been dozens of ways to find out if a site is running Drupal. And they're not hard to find. Take the time and install a default Drupal and then start picking some of the texts you see. Any of these can be googled. Think of those smurfs on the search page when no results are found. When the zero day exploits come, it won't be hard to find Drupal sites, and obfuscating the fact that any site is running Drupal is very hard. This is true of any stock CMS. If you're really worried about people knowing what software you run, roll your own. After all, starting from scratch and writing it all yourself is well known to be best way to produce bug-free code.

Of course!

After all, starting from scratch and writing it all yourself is well known to be best way to produce bug-free code.

Couldn't have said it more sarcastically myself. :D Thanks!

Some obscurity may be good

If your site is not vulnerable to the simplest/most common ways to programmatically pick out a Drupal site, then your site may be spared when the next 0-day Drupal exploit hits. In other words, it may be good to be different.

I don't think this post would help hackers much, but it does raise this issue of hiding that a Drupal site is Drupal.

No No No

Obscurity is NOT security, nor is it really helpful.

Please see http://drupal.org/node/79018 for more info on this subject.

Many many, admins will tell you that the script kiddies don't care at all about checking a site first. They just run the actual exploit. The number of log entries on a major site for forum software issues (most common), or vulnerabilities in other CMS software is staggering.

Reasons for hiding the software behind a site, often include trying to prevent others from knowing the technology decisions being made inside corporations, or just not understanding the real issues of security.

A command line option

An easier way to do this without firing firefox and installing extensions would be (on a Unix based machines:

$ 2>&1 wget -S http://drupal.org|grep Expire
  Expires: Sun, 19 Nov 1978 05:00:00 GMT

(replace drupal.org with your site in question)

Thanks for the nice tip!

Shell script

Wonderful trick. Thank you for sharing it.

An alternative to using Firefox with HTTP Live Headers is this trivial Bash script:

#!/usr/bin/env bash

wget -S $1 2>&1 | grep -q -m 1 "Expires: Sun, 19 Nov 1978 05:00:00 GMT" && echo "Yes" || echo "No"

Save the script in a file called is-drupal, and make it executable (i.e. chmod +x is-drupal). Now, you can easily check a site with following command:

./is-drupal www.lullabot.com

:)

Very cool; smart thinking.

Wicked!!

I added a note about this to the original article. Thanks! And thanks to yhager too! :)

Curl version

Some OSes (like Mac OS X) don’t have wget installed by default. Here’s a curl version of the same script:

#!/usr/bin/env bash

curl -I $1 2>&1 | grep -q -m 1 "Expires: Sun, 19 Nov 1978 05:00:00 GMT" && echo "Yes" || echo "No"

Add -f, -s, -L to Curl command

You might want to add the -f, -s, and -L options to the Curl command. That way, it can handle failures silently, silence progress output (-s), and follow redirects to new locations (-L).

Without -L, redirects (or URL rewrites) that send the user to site.com from www.site.com (or vice versa) won’t be followed, and would produce the erroneous output of “No.” With -L, however, I have had it follow such redirects and produce the expected output.

#!/usr/bin/env bash

curl -fsIL $1 2>&1 | grep -q -m 1 "Expires: Sun, 19 Nov 1978 05:00:00 GMT" && echo "Yes, this appears to be a Drupal site." || echo "No, this does not appear to be a Drupal site."

better, faster:

don't wget the whole page, but only the headers, with a http head request:

wget -S --spider ...

better, faster:

don't wget the whole page, but only the headers, with a http head request:

wget -S --spider ...

BugFix - Creates 'index.html' files

I don't know about you all, but when I run that script, it makes index.html, index.html2, index.html3, etc. files in whichever directory I run it in. (Usually my home dir)

You can fix the wget version by adding the option "-O /dev/null"

The complete version being:

#!/usr/bin/env bash

wget -O /dev/null -S $1 2>&1 | grep -q -m 1 "Expires: Sun, 19 Nov 1978 05:00:00 GMT" && echo "Yes" || echo "No"

Thanks...

I'll be running this daily, I'm sure.

Although, this may be less and less important as we start to ask the question -- "Wait, is this one of THOSE sites NOT running Drupal?"

And btw, do we still have to tell people to "Get Firefox?"

Sigh. Soon my friends, soon.

Strange

When I do this on lullabot.com I get june 1st 2008 as expiration-date...

grep should be "^Expires"...

grep should be "^Expires"... you're grepping the cookie expires.

Page for checking if a site is running drupal

Hi!

I've made this little page on my website for checking this basing on the comments of this post :)

You can check it out here:

http://cambrico.net/check-drupal-site

I noticed most drupal sites

I noticed most drupal sites have this kind of pattern,

@import "/sites/[website]/files/css/bcb7ecf370d40044ccf58487dc993ea6.css";

any accuracy in this assumption?

I think that this import of

I think that this import of css is done only when you have the compress css performance setting enabled (you should!), if not, you will see a lot of css files imported (one for each module that uses its own css file)

How about the following

How about the following URL?

http://sitename/user

Thanks for the tip, this

Thanks for the tip, this will definitely help me add more sites to the gallery.

thanks

Thanks

I'll be running this daily, I'm sure.
Very cool; smart thinking.

JS FIles

One more or less definitve more easier way is to look at the core files like misc/drupal.js

Every site has this js file and you can access it everywhere

For example here:

// $Id: drupal.js,v 1.29.2.2 2008/08/13 18:12:23 drumm Exp $

Noone is allowed to hack core, so this js files will be there and you will be able to the the $id: ...

I'm usually check:

Inspired by this article and

Inspired by this article and the comments I whipped this together the other night.

http://isthissitebuiltwithdrupal.com/

nice!

Nice Job!

The header-trick does not

The header-trick does not work anymore.

bash script

you could also use "Drupal

you could also use "Drupal Detect" by Adulmec :)

http://www.adulmec.com/drupaldetect/