Sunday, January 13, 2008

Never Render a POST!

There are a few things in web design that you should never do, yet people seem to do them quite often.  I'll give a little explanation of this one first so my non-technical audience can tag along.  PHPers, please pay attention.

Web browsers understand two verbs when making a transaction with a web server: POST and GET. Generally, POST means you're sending information to the server, and GET means you're getting information back. In a perfect world, every web page you ever see would be the result of a GET, and every time you POSTed you would be redirected to a GETable page. But we don't live in a perfect world, do we?

The culprits are poorly-designed web-forms. Good web-forms like google.com submit via GET, which puts your search arguments in a query string after the url, like so: http://www.google.com/search?q=awesome . This is good because now you can copy that url and paste it to someone else, and they can see your search results too.

POST, on the other hand, sends the form's information to the server invisibly. If you render a page on a POST, you can't paste the url to someone else, because they will not have posted that information. If you hit Refresh on a posted page, or try to navigate back past one with your Back button, your browser will warn you that you are posting again. You have to POST again in order to see that page again. And that's annoying. Your browser can't even cache the page because it knows this is a dynamically generated response to a POST, so it will load slowly too.

POST should only be used for actions that change something on the server's side. They should never render content, but rather redirect to a GETable page to do that.  When you redirect, the POST's target page is stricken from the record, so can no longer navigate back to it and accidentally POST again.  Hooray!

Tuesday, January 8, 2008

Probability, Coincidences, and His Dark Materials

I finished reading The Subtle Knife yesterday, the second book in Philip Pullman's action-packed His Dark Materials science-fantasy series that deals with alternate universes, and attempts to link all of religion, science, and mysticism at once. Well, today was quite an interesting coincidence for me, but I'll have to say more about the series first.

Quite often Pullman refers to probability theory: it's at the root to his multiple universes idea (and everyone else's, for that matter), and he also makes the point that many of the characters' smallest choices could have had a dramatic effect on the multiverse--most especially the very first scene. It's almost a game at times, like when he states that Lyra is a girl who is "destined to end destiny". This passage near the beginning of The Amber Spyglass refers to probability theory explicitly:

"When you choose one way out of many, all the ways you don't take are snuffed out like candles, as if they'd never existed. At the moment, all Will's choices existed at once. But to keep them all in existence meant doing nothing. He had to choose, after all"

Well you can imagine my surprise when I went to my first day of classes, and that's exactly what both of my professors were talking about!

In Stochastic Mathematics, the professor told us that many elementary events exist in a sample space at first, but once an event has occurred, many of the outcomes cease to exist. The Professor even went so far as to explicitly say that they exist in alternate universes, and that "It is impossible to reach these alternate universes" in which these other outcomes would have occurred, once they are past.

On the way to lunch, a girl walking by said "Ugh, why must it be cold AND rainy. Couldn't it just be one or the other?" And I was compelled to say that the probability of cold ^ rainy far outweighed the probability of ~cold ^ rainy, because I am a geek and was in a probability mood.

It didn't end there, though, because next was Algorithms Analysis. And once again, we talked about probability theory! We were discussing pairing algorithms, and this professor just happened to use the very same wording as the other, when examining possible outcomes of stable pairing algorithms to prove it was optimal or pessimal for the related parties. "If, in some alternate universe, Ann and Zeus were together..."

Both were required classes, and I didn't give a second thought to what they were about before I stumbled in, though it seems they were both tightly linked to probability, and just as I got into the His Dark Materials series! What are the chances of that? *laugh track*

Anyway, in an alternate universe, I would have said this portion first:

The first book, for those unfamiliar, is called The Golden Compass. Any recent printing of this installment in the series is adorned with a little yellow bubble informing you of the related "Major Motion Picture" that New Line Cinema just released. And anyone interested enough to read the book and see the movie can tell you what a horribly mangled product New Line has produced. Though even those who haven't should be able to tell from the ridiculous dialog that something isn't quite right. Check out Bridge to the Stars, the series' fan-site, for a little back-story on how this atrocity occurred. Excuse me for the following paragraph's rant.

Much of the magic in the book is in how Pullman gradually reveals the facts, making earlier oddities and clues suddenly clear, and twisting your perception of his world in an instant. But the movie makes no attempt to preserve this--in fact, it reveals nearly everything you shouldn't know in the opening narration. The story itself is mangled beyond belief; it introduces a brand new antagonist, switches the order of the latter two thirds of the book, chops off the final three climactic chapters that change your perception of the entire story, and destroys every defining emotional moment for the sake of family friendly entertainment. The book was filled with compelling metaphors about religion and authority, but the movie seems to have only one moral: "It's better to read the book".

It was pretty funny to watch, being so bad, but it bothers me how a lot of people will probably just watch the movie instead of reading the book, and cheapen the whole experience for themselves. Movies have a way of becoming the definitive source for things, so of course the videogame will be terrible as well, as all games that ride on movie marketing are, and so will be many people's perceptions of the story. So I'd be quite interested in acquiring recordings of the two theatrical versions of His Dark materials, from the National Theatre and Playbox Theatre. Non-readers may actually watch these too!

The Subtle Knife is great, but it's a terribly violent book. I'd like to see New Line try to make that one family-friendly. But still, I hope they do make their silly movie after all, so I can play the second terrible game! The Subtle Knife cuts through dimensions after all--hey Portal fans, are you pondering what I'm pondering? I sure hope this gets something interesting started in the Half Life 2 Homebrew community!

Wednesday, December 12, 2007

Naive Computer Security

I love Jeff Atwood's blog, Coding Horror. This guy posts something new and interesting for CS nerds to think about almost every day, and has really inspired me to get into blogging with his gratuitous self-referential blog posts about blogging. So I thought, instead of posting a comment on today's ridiculous article, "why not blog about it"?

It seems to me that malware prevention takes three forms. Don't let it execute, don't let it do what it wants to do, and of course, get rid of it once it's started doing that stuff.

Don't let it execute

Executables
It means nothing to have a virus sitting on your hard drive if it isn't ever triggered to execute, right? This is where user intelligence comes in: just don't run stupid programs! With enough internet experience, people learn how to spot these: they usually say FREE in big flashy letters but have no GPL to be seen, and often advertise unlicensed third party addons for commercial software-- mostly web browsers and chat clients. If it says "50 free smilies plus fun sounds and flashy goodness!" please don't run it. Video codecs and plugins you've never heard of that show up on advertisement-ridden porn sites are another danger.

This is the sort of thing a good antivirus program can be helpful with: warning the user before they run something stupid. And good antivirus programs do this. Unfortunately, they tend to get things wrong more often than not, because as Atwood says, they are indeed working with blacklists. For example, my favorite free antivirus program AVG still makes false virus detections on any game made in the excellent game maker program Multimedia Fusion because they happen to use a compression algorithm that has historically been used in viruses. Clearly blacklists are no great idea, but at least they do something. The rest is up to your own intelligence and experience.

Non-Executables
Unfortunately, it's not quite that simple, because many viruses come in the form of data specifically designed to break the program interpreting it and execute arbitrary code through it. This is where the Outlook JPEG exploits come in. If this happens, it is usually not the fault of the user at all. In fact, it is everyone else's fault.

1) It's Intel and AMD's fault for not making the program text segment read-only
2) It's The C Programming Language's fault for making it so easy to cause buffer overrun
3) It's the software developer's fault for using C/C++ without rigorously testing all forms of buffer overrun and misinterpretation of data
4) It's the operating system's fault for letting the compromised program do as it pleases

While the first one may never be fixed, the second is rapidly improving as new languages gain popularity. Even something so simple as writing your programs to compile to a virtual machine like M$.NET or JVM acts to combat this problem quite well. Stages three and four here are the way things are traditionally done, albeit ineffectively. It just makes me wonder how much better a place the world would be if we could fix #1.

Then again, if there's a fix to the software or OS that the user hasn't applied yet, it is indeed their fault.

Don't let it do what it wants

This is where permissions come in. And Atwood is correct: avoiding running as an administrator is a great form of protection. If an exploit can't modify core application files, it will have a hard time living after you restart the application, and an even harder time of causing damage to the main system. It can, however, insert itself into user-space startup scripts to keep itself going, and do whatever it wants to the current user's files. In fact, on most systems all files anywhere are readable, and won't really hide their data from a user-space virus. The virus simply has to transmit them over the internet. And that's where things like Windows Firewall come in, in the class of defense by not allowing processes to do what they want.

Of course, with all the permission / behavior checks in the world, there is still the problem of users who will just click OK GO AHEAD by reflex, and end up enlisting their poor machine as a slave in someone's epic DDOS army of doom. Though even without the clueless user response, permission systems can be circumvented via buffer overrun and exploits in just the same way that data can take over an application, so long as the target application has some of the desired permissions. So until we invent unbreakable applications (or Intel and AMD do, you know, that thing), we're back to: don't run dodgy stuff on your computer!

Get rid of it once it's there!

This is the feature antivirus programs advertise. They inspire fear and doubt and paranoia in their poor users to the point that everyone seems to immediately think they have a virus as soon as their computer starts acting weird. The methods they use, however, are often kludgy and awful, and will make you wish the virus was never there to begin with. Experienced sys-admins who find their machine has been compromised would often rather re-install the operating system than deal with disarming the threat, for fear of hidden backdoors. However, they do offer a quick fix for common users that isn't too bad, so why not run a virus checker every so often. At least it sort of gives you peace of mind.

Personally, I'm a naive computer user, and will more often than not run a game I maybe shouldn't. But it's comforting to have all three levels in place there, to catch the majority of problems before they get too big. After all, nobody has designed the ultimate exploit that is immune to every form of protection and survived it for more than a month.

Friday, November 2, 2007

Seagate Sued over Industry Convention

I'd hate to be a me-too blogger and just pass the latest links around, but this news really shocked me. I mean, I know deep down in the heart of every computer user is an urge to fix this stupid industry convention, but can they really sue a company for doing the same thing as everyone else?

But really, I'm happy to see these things are changeable! What long-standing bad convention can consumers attack next? Lets pick out the biggest producer of electronics schematics we can find and sue them because electrons are negative and actually flow in the opposite direction as the "current" in their electrical diagrams. I am sure someone out there can sound confused and irate about this! Current does not flow as advertised!

Either way, I'm surprised to see Western Digital didn't take the fall here, as they seem like a more household name.

Hey (non-existant) commenters: post some bad conventions and who you'd like to sue about them.

Thursday, November 1, 2007

Now You're Programming with Power

If you asked me last year what makes a good programming language, I would have said it's one that is simple and easy to read. I'd design languages like this in my head, daydreaming about clean syntax and beautiful understandable code. Lisp programmers would look down on me scornfully as I moaned about their parenthesis. It turns out they knew something I didn't.

Functions rule.

I can thank Stumble-Upon for this revelation, as it randomly tossed me to a video of the first ten minutes of a series of computer science lectures recorded in 1986! It is somewhat hard for me to believe that this has existed this long, yet has not seeped into any classes in the UCSC Computer Science (read: Java C Perl) department other than in an elective called "Comparative Programming Languages". Though it would make sense when you consider some of these professors still live in 1970, and bicker over ancient differences between vi and emacs and the number of characters that really should be displayed on a single line in the terminal.

What I learned is that functions can do anything. This may seem like common sense, but if it really was common then there wouldn't be so many languages out there that make creating functions at runtime extremely difficult. I'm looking at you, Java! Other languages tend to hack this feature in as a side-thought, and pitch the Object Oriented Paradigm as their primary facet. Well guess what: you can implement objects with dynamic functions!

Here's a rather simple way to do it in scheme:

First, lets make a constructor. Every class of objects needs one of those. This one will have three fields in it: foo, bar, and baz.
(define (thing-constructor foo bar baz)
(lambda (choose)
(cond ((equal? choose 'foo) foo)
((equal? choose 'bar) bar)
((equal? choose 'baz) baz))))
What we've really created here is a function that returns another function. The function it returns holds on to the three values from before, and allows us to choose which one we want out. Lets create an instance of our class and test it out.
(define x (thing-constructor "Joe" 'Mel 5.17)) ; an instance

(x 'foo) ; gives us "Joe"
(x 'bar) ; gives us 'Mel
(x 'baz) ; gives us 5.17
Well hey, look at that! We just created an object using only functions. Want methods instead of just data? You can put those in too.
(define y (thing-constructor sqr sqrt (lambda (x y) (* (+ x y) (- x y)))))

((y 'foo) 3) ; -> 9
((y 'bar) 16) ; -> 4
((y 'baz) 5 7); -> (* (+ 5 7) (- 5 7)) -> (* 12 -2) -> -24
Neat, huh? And of course you can also put in other objects, and put objects in those objects, and so on, and thus create a traversable tree, list, graph, you name it. And all it took to implement this was cond, equal?, and lambda. Functions are pretty darn cool.

As a disclaimer, I'd like to say that I'm new to scheme, and that this example should be pretty obvious to any good schemer. There are much better implementations of object oriented programming in scheme out there, with all the bells and whistles. But still, functional programming is powerful, and this example was surprising enough to me. Hopefully it will be inspiring to some other programmers out there who have yet to try a functional language.

Sunday, September 2, 2007

Hey, it's a Blog by Me! How Exciting.

What an adventure this shall be! I am not the world's greatest writer, so I will have to resort to cheap tricks like wowing you (the viewer) with silly games and web programmer niftyness and uh... cartoon foxes! Well it worked for _Why, so you can just sit here and enjoy it.

And Also, Activity time! I'd like my blog-postings to be as link-packed as possible to prevent the boredeom of my readers. So, if you can think of something silly to link from a phrase of mine, comment about it and I'll probably do it too!