Saturday, March 31, 2007

Fun with getallheaders() and var_dump() - another excerpt from Chapter 8

In PHP, the Apache-specific functions give an extremely easy way of checking referers via the getallheaders() library function. Calling it, with PHP installed as an Apache module, returns an associative array containing all of the header names as the array keys, with their corresponding header values as the array values. Calling var_dump(getallheaders()) would display something like the following, with "Referer" as the last entry in the array:

array(9) {
  ["Host"]=>
  string(13) "192.168.2.106"
  ["User-Agent"]=>
  string(92) "Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en-US; rv:1.8.1.3) Gecko/20070309 Firefox/2.0.0.3"
  ["Accept"]=>
  string(99) "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5"
  ["Accept-Language"]=>
  string(23) "en-us,en;q=0.7,fr;q=0.3"
  ["Accept-Encoding"]=>
  string(12) "gzip,deflate"
  ["Accept-Charset"]=>
  string(7) "UTF-8,*"
  ["Keep-Alive"]=>
  string(3) "300"
  ["Connection"]=>
  string(10) "keep-alive"
  ["Referer"]=>
  string(31) "http://192.168.2.106/utilities/"
}

However, the following shows that a simple telnet connection can set the header to anything and the server will simply believe it, since it lacks any way of verifying it.

$ telnet 192.168.2.106 80
Trying 192.168.2.106...
Connected to 192.168.2.106.
Escape character is '^]'.
GET /utilities/getallheaders.php HTTP/1.1
Host: 192.168.2.106
Referer: The Forbidden Zone

HTTP/1.1 200 OK
Date: Thu, 22 Mar 2007 02:08:01 GMT
Server: Apache/2.2.3 (Unix) PHP/5.2.1
X-Powered-By: PHP/5.2.1
Content-Length: 117
Content-Type: text/html

array(2) {
  ["Host"]=>
  string(13) "192.168.2.106"
  ["Referer"]=>
  string(18) "The Forbidden Zone"
}

Labels: ,

Sunday, March 25, 2007

3500 words today, and counting

By standing on the shoulders of giants, Chapter 2: Accessibility has gone much easier than I even anticipated. Excerpt from the chapter, specifically the intro to the section "Screen readers can handle Ajax:"

If a user cannot see the screen (and the web application within it), they will need something to describe and read it to them. Note that it describes, as well as reads it. As touched upon in Chapter 2: Usability, semantic markup makes these descriptions much more relevant and meaningful to someone who does not (for example) have the ability to tell at a glance that four links have anything to do with each other, let alone that they provide navigation access to other parts of the web application.

A common misconception among Ajax developers and users alike: screen readers cannot handle dynamic content. They can, but similarly to supporting all of the major rendering engines of browsers, supporting the major engines in screen readers takes time and understanding. As a common example, Jaws and Windows-Eyes might recognize a focus change as a point to start reading, while Home Page Reader does not. As such, much like writing generic or all-encompassing code to support multiple browsers, writing scripts to dynamically change the DOM structure just needs to include all of the steps necessary for the most commonly used and supported screen readers.

Though use of text-only browsers such as Lynx or screen reader simulations such as the Firefox extension, Fangs do prove incredibly useful for quickly and easily checking a web application on initial page load, only by using a fully-fledged screen reader can you accurately and consistently test a dynamic web application. Jaws, developed by Freedom Scientific, has put itself into the majority of the market, especially in the United States, commanding a portion of the market comparable to IE's market share of browsers.

For developers whose primary development environment does not happen to consist of Windows and IE, the Fire Vox extension for Firefox has recently come onto the scene, and can run in Windows, Mac, and Linux. Initially written as a demo of CLC-4-TTS1, the extension has proven quite popular, and (through the CLC-4-TTS library) has beaten all of the big names in screen readers to offering support for the drafted WAI-ARIA guidelines, explored later in this chapter. It also provides MathML support (which Firefox supports "out of the box") and support for the CSS3 Speech Module.

  1. 1 Core Library Components for Text-to-Speech, written by Charles L. Chen, also the author of the Fire Vox extension

Labels: ,

Thursday, March 22, 2007

For a good example of why web applications should always regenerate session ID tokens on login

A sidenote in Chapter 8: Keeping a Web Application Secure

For a good example of why web applications should always regenerate session ID tokens on login, run tcpflow -i en0 -c port 80 | grep 'Set-Cookie:' and then navigate to a few banking or online payment sites. Most of them will set a cookie in order to store things like language, or to track your browsing for metrics. However, if the institutions do not regenerate a new session ID token on login, anybody who steals the initial, cleartext cookie, can then (assuming they take no other precautions such as tying sessions to IP addresses) use the cookie themselves without needing to authenticate as the victim.

Writing this chapter makes me hope more than ever that web developers working for financial institutions know how to keep things secure...unfortunately, common sense (and issues I've run into in the past) tells me that at least a few of them need to work on it a bit more, to put it entirely too mildly.

Labels: ,

Sunday, March 18, 2007

Intro to Chapter 8: Keeping a Web Application Secure

Many people currently have a misconception about Ajax-based web applications inherently lacking in security. While this has a basis more in misunderstanding the technology than in serious research, developers need to ensure that they do not leave doors open in the application that they might otherwise neglect, and inadvertently encourage this line of thought.

The only new technology occurring in Ajax-driven applications comes in the form of the XMLHttpRequest object, which only has the ability to make requests all browsers currently make already, with the restriction that the requests can only get made to the same domain name. In other words, while a browser makes request to any domain specified, the XMLHttpRequest object cannot perform cross-domain requests.

The largest security consideration specific to Ajax-driven web application development, a developer's mentality when writing the code itself must get kept in check. Just because users does not need to interact directly with JavaScript objects that send data to the server does not mean that they never will. Tools like Greasemonkey have made user scripts available and popular with users who don't even have any JavaScript knowledge, and can open up those abstracted objects to useful (if occasionally dangerous) functionality never intended by the developers.

In a nutshell, Ajax has not opened up any new security holes in web development, but it can raise the stakes. By exposing more of the server-side application to client-side scripting, developers broaden the surface area available to attackers. By involving more "moving parts" than in less dynamic web applications, it increases the chances that mistakes will get made. The practices elaborated on in this chapter minimize this risk.

Labels: ,

Monday, March 12, 2007

Opera Developer Console

It figures I would find this as I wrap up the initial draft of the chapter on client-side debugging, but it makes me extremely happy to see it: Opera has started work on a Developer Console, which (among many other things) logs XMLHttpRequest calls.

An Opera debugging window showing HTTP, Cookies, and an XHR logger.

The Opera Developer Community runs through some of the DOM, JavaScript, and CSS tools, and the Opera Desktop team posted about it over a month ago when they initially started putting it into their development builds.

From what I can tell by peaking at the source (since, like most Opera extensions, they wrote it in JavaScript), it looks like they made a simple wrapper object and replaced the native object (after storing a backup reference for when logging gets shut off again) in order to create hooks into each of the events so it can report everything as it happens.

This means that I can now debug XMLHttpRequest usage in more than one browser, which makes life much easier than either guessing how it went or using a standalone traffic sniffer.

Edited two minutes later to add: you can get it from the Opera Developer Tools page.

Labels: , , , , ,

Thursday, March 08, 2007

Unit testing intro

Along with documentation, unit testing often gets left behind as a chore that should get done, but simply does not earn the attention from developers that it deserves. Maintaining and regularly running unit tests can have any number of beneficial effects on an application's development. These can include keeping the trunk stable, rather than having thoroughly untested changes create a ripple of frustration and lack of productivity hit other developers working on the same project.

More recently, unit testing has had a boost in popularity due to the Agile methods of software development, the short turnarounds of which thrive when the software has rigorous, frequent testing. No matter which methodology the development of an application follows, unit testing by individual developers can only help the quality and stability of the overall application.

For JavaScript, developers mostly use JsUnit, a JavaScript port of the Java JUnit unit testing tool. It works in all major browsers (IE6, IE7, Mozilla, Opera, and Safari), and provides a simple enough API to create tests almost immediately, while flexible enough to create entire nested suites of unit tests.

Labels: , ,