Password-Protecting Ajax Requests






Password-Protecting Ajax Requests

Password-protecting Ajax requests is fairly simple because we could simply append an additional variable to the query string that represents a password and verify it on the server side. This would work fine, but could easily be discovered if the password never changedwe would run into the same problem of people being able to see the variable being passed via the request. This is where unique passwords would be extremely helpful because it would be nearly impossible for a hacker to decipher a password and send a malicious request if every request had a unique password.

Creating Unique Passwords

Now that we understand how useful unique passwords will be to our applications' XHRs, we will learn how to create a server-side method that creates them. Let's start by creating the PHP class on the server side called PasswordManager. This object will be a Singleton object so that it is accessible on an applicationwide level. In order to make this object a Singleton, we need to make the constructor function private and create a public static method called getInstance. This method will check to see whether the object has already been instantiated. If not, it will create an instance and return it; if it does exist, the method will return the previously instantiated version of the object. Listing 23.2 shows how this object uses the Singleton design pattern.

Listing 23.2. Creating a Singleton PasswordManager Object

<?php

class PasswordManager
{
    private function PasswordManager(){}

    public static function getInstance()
    {
        static $instance;
        if (!is_object($instance))
        {
            $instance = new PasswordManager();
        }
        return $instance;
    }

}

?>

Now that we can access this object applicationwide, we will create a method that will provide us with unique passwords. This method will be called getPassword and will accept an array of unique values that we will define shortly. When the method is called, it takes the array, gets a count for the length of the array that was passed to it, and sets it to a local variable called max. This variable is then used to generate a random number between 0 and itself, which is then set to a local variable called index. The index variable is then used to generate a variable called seed by setting it to this specific index in the array. At this point, we have selected a random value from the array that was passed in as the parameter, which makes it that much harder for a hacker to get the first value correctbut this definitely is not enough yet. To make it even more secure, we take the newly generated seed variable and encrypt it with the md5 encryption method in PHP. md5 is a one-way encryption method, meaning that it cannot be reverse engineered to provide the original seed value that we provided it. After we encrypt the seed, we append a colon and the random index in the array. After we have our password created, we return it to the caller. You may be wondering why we appended the random index to the end of the password; we will cover this when we verify the password during XHRs. See Listing 23.3 for an example of the getPassword method.

Listing 23.3. Creating a Password Array (Constants.class.php)

public function getPassword($arr)
{
    $max = count($arr);
    $index = rand(0, $max);
    $seed = $arr[$index];
    return md5($seed).":". $index;
 }

The array we will use to eventually pass as a parameter to the getPassword method will be added to our Constants object. This array will be another static property so that we can access it applicationwide. The property is named PASSWORD and can include as many values as you want to add to it. This is because when we created the getPassword method, we got the count of the array, so the code is flexible enough to accept any size array. The values in the array can also be any value you want and should be something that is secure, such as a typical password. The values and the number of them can also change as often as you like to make it that much more secure. Listing 23.4 shows this property with a few dummy values as an example.

Creating a Password Array (Constants.class.php)

// Password
 static $PASSWORD = array('temp_password_1', 'temp_password_2', 'temp_password_3');

In order to send the password to the server-side with all of our XHRs, we will add a property to the AjaxUpdater that sends the password each time a request is made. This ensures that all our requests are secure and that we or another developer on our team did not forget to add the password to a request string. It also keeps the code much cleaner so that we do not have random password-protected requests throughout our application. This would make it very difficult to make later updates to the request and would become very unruly. Take a look at Listing 23.5 to get an idea of how this property is added to the AjaxUpdater initialize and Update methods.

Listing 23.5. Adding the Password to All Ajax Requests (AjaxUpdater.js)

AjaxUpdater.initialize = function()
{
    AjaxUpdater.uid = null;
    AjaxUpdater.isUpdating = false;
}

AjaxUpdater.Update = function(method , service, callback)
{
    if(callback == undefined || callback == "")
    {
        callback = AjaxUpdater.onResponse;
    }
    Ajax.makeRequest(method, service+"&uid="+AjaxUpdater.uid, callback);
    AjaxUpdater.isUpdating = true;
 }

Now that we are generating unique passwords and have a property that is sent with all our requests, we must provide this property with some sort of value. This value will be set in our application's mail.php (Listing 23.6) page with PHP as the AjaxUpdater.uid property in JavaScript. In other words, we will write JavaScript with PHP and set the password in the process. In order to use PHP to get the password and add it to the page, we must include the Constants and PasswordManager objects. After we have included these files, we will get an instance of the PasswordManager and call its getPassword method with a parameter value set to the PASSWORD array that we added to the Constants file. When the password is returned, we will write a JavaScript init method between JavaScript tags in the page, which sets the AjaxUpdater.uid to the generated password.

Listing 23.6. Setting the Password (mail.php)

require_once("classes/utils/Constants.class.php");
require_once("classes/security/PasswordManager.class.php");
$pwManager = PasswordManager::getInstance();
$uid = $pwManager->getPassword(Constants::$PASSWORD);
echo "function init() { AjaxUpdater.uid = '". $uid."'; }";

We now have a unique password that is being sent with each and every request through the AjaxUpdater, but this doesn't do us any good if we do not verify the password on the server side when the request is made. Let's take a look at how we accomplish this verification and ensure that our requests are secure.



 Python   SQL   Java   php   Perl 
 game development   web development   internet   *nix   graphics   hardware 
 telecommunications   C++ 
 Flash   Active Directory   Windows