Skip navigation.

miscoded

the web is a hack

Posts tagged with "sniffing"

Most expensive javascript ever?

, , ,

I've wanted to tell this story for a while, and I don't think I'm spilling any beans or disclosing any sensitive information at this point.

So, a while ago Opera Software needed more servers. Not just a few servers either - we were planning Opera Mini's growth, implementing Opera Link, and My Opera was also growing quickly. We predicted crazy server load increases for the foreseeable future (and man, were we right!)

Clearly we needed to make a massive investment on the server capacity front (basically buying these shiny things and then some.)

Management put a hefty check on the table - I'm sure our beloved sysadmins felt like kids before Christmas - and salivating sales people from major hardware vendors grabbed our requirements spec, dived into their CRMs and crunched their spreadsheets. They emerged with offers and sample servers shipped all the way to Oslo for our testing pleasure.

However, one of the world's biggest hardware vendors - whose name every single reader will be familiar with, and whose hardware a good share of you will be using right now - apparently didn't do their homework. When Opera's sysadmin booted up the server to test its web-based administration interface, they came across a single JavaScript statement that managed to piss off everyone up to and including the CTO.

This single statement, apparently written by some sub-contractor they had outsourced admin interface programming to, cost them millions of NOK in lost sales.

And the code they sent all the way to Oslo for testing? Here's an extract:

if (is.opera)
{
window.location.href="config/error.htm";
}

'ESPN FLASH detection system' meets Flash 0

, , , ...

Even in the classy company of bad version detection scripts we've met since we started testing Opera 10, this Flash detection approach stands out. That script goes to great effort to require an update every.single.time Adobe releases another Flash version.

It starts with a bold claim to be the ESPN "Flash detection system", no less:

// Author: Danny Mavromatis
// Version: 2.07.0
// Created: 10/29/2001
// Updated: 3/6/2006
// ESPN.com FLASH detection system
var f2 = false;
var f3 = false;
var f4 = false;
var f5 = false;
var f6 = false;
var f7 = false;
var f8 = false;
var f9 = false;

Look at all those variables. What might they be used for? Read on:

var fD = navigator.plugins["Shockwave Flash" + isVersion2].description;
var fV = parseInt(fD.charAt(fD.indexOf(".") - 1));

So, first it extracts one single letter that precedes a dot in the plugin's description of itself. This is presumably the plugin's major version number, you know the 8 in "8.0", the 9 in "9.0", and, um, the 0 in "10.0". Then:
f2 = fV == 2;
f3 = fV == 3;
f4 = fV == 4;
f5 = fV == 5;
f6 = fV == 6;
f7 = fV == 7;
f8 = fV == 8;
f9 = fV == 9;


..it just sets the corresponding "f"-variable to true. If the major version was 8, f8 will be true and so on. A great way to make sure the code will require maintenance - new variables for each new version. And then comes the real gem:

for (var i = 2; i <= mV; i++) {
if (eval("f" + i) == true) aV = i;
}
// alert("version detected: " + aV);



Let's see, we just had a variable fV which contained Flash's major version number (or at least its least significant digit) - but this script has severe amnesia. What was that number again? Better use a loop and 8 eval() calls to check the value of that variable. You never know, do you?

Now, dear readers - Mr. Mavromatis clearly needs some help with this code. Obviously, complexity and maintenance requirements are among his design goals. The natural question is whether there are good, non-obvious ways this script could be improved to be more complex and require even more maintenance? Suggestions welcome in comments.

Update: Danny Mavromatis responded in comments and - though he no longer works on the ESPN site - has made sure that the page where we found this problem has been updated. Kudos to Mr. Mavromatis for his quick response and sense of responsibility. I wish more web developers would act this way!

No more personal attacks, please!

10 is the one

,

So we're busy preparing the major upgrade from 9.5x and 9.6x - and what's more obvious than calling it Opera 10? What's in a name, or a version number?

Apparently a lot of trouble.

As Andrew Gregory already noticed, we're the first browser ever to release with a two-digit version number. If websites assume that version numbers always have a one-letter "major" part and look for a single digit, they are going to "detect" Opera 1!

Since we released the first preview of Opera 10, we're seeing the bug reports come in. Web sites go belly up because of their bad sniffing. Some of them aren't even ashamed of it..



Thanks, Bank of America. Do you feel like it's 1995 again? Yeah, me too.

You'd think that with the intense development Microsoft has been lavishing on live.com they would have found somebody capable of writing a usable browser sniffer (or ideally a person clever enough to say "wait, we don't really need one - what if we just use feature detection instead?"). Think again..


..and for further evidence that their backend version detection is an odd piece of software engineering, read their cookies closely - Opera 9.62's request first, then Opera 10:
GET /mail/browsersupport.aspx 
Host: co109w.col109.mail.live.com 
User-Agent: Opera/9.62 (Windows NT 5.1; U; en) Presto/2.2.0 

Set-Cookie: BrowserSense=Win=1&Downlevel=0&WinIEOnly=0&Firefox=0&Opera=1&OperaVersion=9.2&Safari=0; domain=.live.com; path=/


GET /mail/browsersupport.aspx 
Host: co109w.col109.mail.live.com 
User-Agent: Opera/10.00 (Windows NT 5.1; U; en) Presto/2.2.0 

Set-Cookie: BrowserSense=Win=1&Downlevel=1&WinIEOnly=0&Firefox=0&Opera=1&OperaVersion=&Safari=0; domain=.live.com; path=/


Did you spot the missing version value? We really confused them by adding 0.37 to our previous value, didn't we?

Speaking of cookies, they are the main reason we added the feature that lets you hide Opera's identity. Back then in 1996 or so, some sites would do browser sniffing and send cookies only to known browsers. On the next page, if you didn't serve it cookies the site would say "hey, you don't support cookies so go away". What would Joseph Heller make of that, I wonder?

So, rewind to meet the catch-22 server, re-born at Bank South Australia:
GET /InternetBanking/ HTTP/1.1
User-Agent: Opera/9.62 (Windows NT 5.1; U; en) Presto/2.1.1
Host: ibanking.banksa.com.au

HTTP/1.1 200 OK
Set-Cookie: JSESSIONID=000019WTazsWAk-lB38OrmKD3kR:13l3ifhnq;Path=/
Set-Cookie: bhCookieSess=1;Path=/
Set-Cookie: bhCookiePerm=1;Expires=Sat, 20-Dec-2008 23:35:40 GMT;Path=/

..and Opera 10..:
GET /InternetBanking/ HTTP/1.1
User-Agent: Opera/10.00 (Windows NT 5.1; U; en) Presto/2.2.0
Host: ibanking.banksa.com.au

HTTP/1.1 200 OK
Content-Type: text/html;charset=ISO-8859-1
Content-Language: en-AU
Date: Thu, 18 Dec 2008 23:34:37 GMT
Connection: close


Um, I'm hungry. Where are your cookies? Predictably the next page looks like this:



This is probably just the beginning. :frown:

Will the web ever learn?

MS' Virtualearth claims Opera has no SVG support

, , , ...

As seen in this discussion, the BBC site uses a map from maps.live.com - and all we Opera users get is an error message:

We're sorry but your browser does not support BBC Sport's Olympic map.



Looking into it, first there is some Opera-sniffing from the BBC itself that detects Opera and displays the warning instead of the map.

With that sniffing neutralised, the map loads - but shows the United States, not Beijing. Come one Live Maps, admit you're wrong by several thousand kilometers.. Or?

Not in the mood to admit any fault, the script instead spits out an error laying the blame on us:

JavaScript - http://news.bbc.co.uk/sport2/hi/olympics/7493757.stm
Timeout thread: delay 10 ms
Error:
name: Msn.Drawing.Exception
message: Your Web browser does not support SVG or VML. Some graphics features may not function properly.
stacktrace:   Line 1 of linked script http://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.1


So, my web browser does not support SVG, eh? Let's have a closer look at how you figured that out..

if(document.all)
         return new Msn.Drawing.VMLGraphic(e,b);
else{if(navigator.userAgent.indexOf("KHTML")!==-1)
         return new Msn.Drawing.SVGGraphic(e,b);
var c=0,f=0,g=new RegExp("Firefox/(.*)"),d=g.exec(navigator.userAgent);
if(d&&d.length>=2){
         var a=d[1].split(".");
         if(a){c=a[0];
         f=a[1];
         if(parseInt(c)>0&&parseInt(f)>=5||parseInt(c)>=2)
                  return new Msn.Drawing.SVGGraphic(e,b)

         }
}
throw new Msn.Drawing.Exception(L_GraphicsInitError_Text)


Yes, nothing but browser sniffing.. Not a single attempt at intelligent feature detection. Basically, by claiming Opera doesn't support SVG and can't load the map Microsoft is lying to the BBC and to our users.

practising and preaching

,

The Surfin' Safari blog writes:

We strongly recommend looking for the AppleWebKit string and its version number, *not* for Safari



Apple's Safari FAQ writes:

If you need to identify the exact browser and version of clients accessing your site, use the AppleWebKit/XX portion of the string.



And lib.js on apple.com says:

this.isSafari= (agent.indexOf('safari') != -1);


Makes you wish browser vendors had tried suing browser sniffer authors back in 1996, rather than adding elaborate workaround strings to their UserAgent information. Seriously, authors should try a lot harder to not use name sniffing.

Saab says //TODO: Opera-compatibility

, ,

function getFlashMovieObject() {
var errmsg = 'Sorry, your browser is missing the functionality for viewing this page...';
if (isOPERA  ||  isMAC) {//have to find out about this...
alert(errmsg);
return null;
}


source

Sorry Saab, your web developer is missing functionality for avoiding browser detection.

sniff and die

, , , ...

Well, I didn't quite get to the bottom of the Live.com problems last time but now I know: it's a bug in their browser sniffer. They say

Web.Browser._isIE=!Web.Browser.isMozilla()&&!Web.Browser._isOpera;


but mean

Web.Browser._isIE=!Web.Browser.isMozilla()&&!Web.Browser.isOpera();


.. so isIE is set to true even though we're Opera. That means the script gets into the wrong branches of the getElementsByTagName stuff in my previous post.

Yet another proof that all the world's evils come from browser sniffing. If sniffing wasn't necessary, we would have peace in the Middle East, no starvation in Africa .. OK, sorry, I'm getting carried away here but at the very least Live.com would be alive and kicking.