Novemberborn, Straight lines circle sometime

MyBlogLog Dissected

Via Merlin of 43 Folders I found out about MyBlogLog, a service which tracks outbound links from your site. It does this by detecting clicks on the body, after which it determines if the click originated from a link. If this is the case it then sends the URI, link text and a timestamp of when the click occured to a server by constructing a new Image and setting its src property.

Okay, so I’ve already explained how it worked in the introducing paragraph… so much for dissecting! Well, there are a few comments I’d like to make about the JavaScript, including tips to make the code invisible to the visitor and some ramblings about privacy. Read on!

4th March 2005: I sent a link with this article to the MyBlogLog people and they replied to me within 20 minutes. They’re going to take my tips into account, so this article will probably be outdated in a couple of days. But don’t worry, I’ll write a follow-up ;-)

19th June, 2005: I checked the JavaScript again today, and the only thing which has been changed is that the methods and variables are now all prefixed with cs. No follow-up necessary, I’d say…

The Code

You can find the code at here. The original code was wrapped in a comment, but I’ve removed it here so you can see the code from the browser.

I have to say here that the sign-up process was really fast. Just fill in the form at the front page and you’re ready to go.

I’m afraid I don’t like the code that much, it does its work, but there are lots of things which could be improved. For example, the script is loaded externally: this means there is no need to wrap it in a HTML comment.

Another issue I have with it is that its functions and a some variables are in global scope. This is a bad idea if you want to write a script for people to use in their own websites. Variables like url and trackUrl are too likely to interfer with other scripts. It’s interesting to see though that a different variable, cs_url_trker, and some of the functions, are prefixed with cs_. The variable which holds the ID is prefixed with mbl though. This prefixing makes the variables less likely to interfer with other scripts — the question remains why the prefixes are different.

Some other parts of the code are illogical. Take this code, for example:

if(tg.innerHTML){ text = tg.innerHTML; } //most browsers
else if(tg.innerText){ text = tg.innerText; } //ie only
else if(tg.text){ text = tg.text; } //mozilla only
else{}

innerHTML is indeed supported by most browsers, including IE and Mozilla. Which means that the innerText and text properties will never be used.

And what’s up with that extra else{}? Is it meant to provide a fallback for browsers which don’t support innerHTML in true XHTML pages? I hope that’s the cause, but this empty else condition is used elsewhere in the code as well:

if(document.body){
  document.body.onclick = cs_det_oc;
}else if(document){
  document.onclick = cs_det_oc;
}else{}

Keeping The Function Alive

I did found an interesting hack in the code, namely the pause() function:

function pause(numberMillis) {
  var now = new Date();
  var exitTime = now.getTime() + numberMillis;
  while(true){
    now = new Date();
    if(now.getTime() > exitTime){ return; }
  }
}

pause() is called in this piece of code:

function cs_track_oc(text, url){      
  try{
    var now = new Date();
    trackURL = cs_url_trker + '?t=2&u=' + url + '&te=' + text + '&i=' + mblID + '&now=' + now.valueOf(); 
    var x = new Image();
    x.src = trackURL;
    pause(1000);
  }catch(err){ }
}

Appearantly this is used to make sure that data is indeed send to the server. From what I understand from the code the request to load a new image stops if the function returns before the request is made. This “timeout” makes sure the request is made.

It would’ve been nice to document this, though. My first thought was that this was an alternative to setTimeout()

Improving the Script

The issues I pointed out above can be easily fixed. And, while that’s being fixed, we can also make the script invisible to the visitor. Here’s how.

By wrapping the code in an anonymous function you create a closure. This means that the functions and variables which are now defined in global scope will exist in the scope of that closure. And, even better, by using block scope you can completely hide the code from the visitor.

Well, almost. The events are set using document.body.onclick or document.onclick, which is still visible to the outside world. If you’d use a DOM1 way of setting the event, though, this becomes a non-issue. The added benefit here is that another script will not “accidentally” hijack (or overwrite) the onclick event. Now the code is completely hidden from the visitor.

Well, almost. The script tag still exists. If the site which uses MyBlogLog really wants to hide it, it could point the script tag to a URI on the site which redirects to the MyBlogLog script.

Privacy Concerns

Scripts like these raise various questions. Do you want the sites you visit to be able to tell which links you click? Are sites even allowed to track this? I don’t know the answer to the second question, but there are ways to prevent this from happening.

For this specific script you can disallow images from third party domains. A possible workaround for this is that the site owner runs this script and the tracker on his own server. Therefore the only real solution is to disable JavaScript.

But There Are More!

There are a few other tricks people can use to get to know more about you amd your browsing habits. One it to use the CSS visited pages disclosure. A more advanced monitoring system is Stephen Cote’s IMNMotion Behavior Monitor.

In view of these other techniques MyBlogLogs is just one of many. I’m not sure if this specific method creates privacy concerns either: the page you visit knows where you came from, why shouldn’t the page you left know where you went to?

link | javascript | 4 March 2005, 13:00



Novemberborn: Extra

About the author

Mark Wubben is a hacker/writer in Enschede, the Netherlands.

Read more about Mark...

Go to

Jobs (NL)

Xopus zoekt programmeurs! Verbeter de code en win!

Subscribe