February 22, 2007

Flash based alternative to mailto:

You will find other articles relevant to this document in these sections:
Richard Lee @ 5:11 pm

When publishing a number of email addresses to a web page you run the chance of a spam bot scraping your site. There are a number of alternatives; such as using a mail form, obfuscating the mailto link with JavaScript or even converting the address to an image. While mail forms will conceal your email address from spam bots, they also conceal your address from the users who may simply want your address for other correspondence. Obfusticating your mailto link with JavaScript is also pretty useless since, being client site any spam bot can “resolve” the link much like your browser. And last but not least using images to display your address takes away the linking functionality. So I suggest a different alternative - Why not use Flash to display the address?

Using Flash, we can load the address client side in parts; “username” “domain” and form the address in a Flash textfield. Then we can simply use the getURL() function OR better use the textfield htmlText with an anchor to simulate our mailto link.
Here’s a hardcoded example of how I do it:
1. Create a 200px x 18 px document (FPS doesnt matter)

2. On Layer 1 add a textfield to the first frame, setting it to type dynamic, and give it an instance name of address_txt
3. Create a new layer above the previous layer for your Actionscript and add the following:

address_txt.htmlText = (username != undefined && domain != undefined) ? '<a href="mailto:'+username + '@' + domain + '">'+username + '@' + domain+'': "no email";</a>

4. Now using Publish your document (making sure you publish a html page in addition to your swf file)

5. Open your published html file in Dreamweaver or your favourite editor and append the querystring “username=joebloggs&domain=gmail.com” to the

<param movie="..." ></param> and <embed src="..."> </embed> tags:

<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,0,0" width="200" height="18" id="mailto" align="middle">
<param name="allowScriptAccess" value="sameDomain" />
<param name="movie" value="mailto.swf?username=joebloggs&domain=gmail" />
<param name="quality" value="high" />
<param name="bgcolor" value="#ffffff" />
<embed xsrc="mailto.swf?username=joebloggs&domain=gmail.com" quality="high" bgcolor="#ffffff" width="200" height="18" name="mailto" align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" />
</object>

6. Finally run your movie in the browser and you should see your email address in the Flash textfield!

September 3, 2006

Stealth like…

You will find other articles relevant to this document in these sections:
Richard Lee @ 2:35 am

If your job requires you to be at the desk most of the day chances are you’re visiting websites from time to time not neccessarly deemed worked related - possibly incriminating. Be wary. Proxy servers can log your internet access meaning someone could quite easily spy on your surfing habits - what your visiting, even what pictures your downloading. But never fear, anonymous web surfing is here! Named “The Cloak” (http://www.the-cloak.com) the-cloak web service does 2 things
1. Encrypts all communication from your browser via SSL, making it pretty much impossible for somebody to intercept any request
2. Redirects your browsers request(s) through it’s own webserver, meaning the webserver  at the other end (i.e. website) won’t know where your coming from - thwarting tracking cookies
Pretty neat huh? For more information on The Cloak checkout the FAQ pages of the website http://www.the-cloak.com

August 17, 2006

Web 2.0 and Security

You will find other articles relevant to this document in these sections:
Cameron Manderson @ 10:43 am

Web 2.0 is proving to be an important step towards extending the capabilities of the HTML interfaces through technologies such as AJAX that use Javascript and asynchronous calls to the server. It has a number of benefits such as reducing the load on the web server through limiting the amount of traffic to perform a simple query or manipulation of the users session state. It also allows the clients interface to be more intuitive and offer potentials such as drill down menus, input suggestion and smarter client side validation. Javascript is used with the DOM to modify sections of the HTML to update the interface based on a request or a response.

It differs from the typical process that we have experiences in “web 1.0” of the past in that we typically have had to perform all server functionality in a single page request, such as a user submitting a product to their cart, or searching for a set of records. This process meant that to process even the simplest of actions required a page refresh.

The shift towards Web 2.0 is something that we are seeing more of. A lot of developers are eager to get any form of AJAX integrated into their site just to feel current with the industry and say they are “doing web 2.0”. Often developers are jumping into Web 2.0 without thinking about the potential implications both on Accessibility or Security.

Recently I read an article appearing on CNet identifying the hype behind Web 2.0 neglecting the Security implications that Web 2.0 raise as web developers push for features, neglecting design and security.

The buzz around the new technology echoes the ’90s Internet boom–complete with pricey conferences, plenty of start-ups, and innovative companies like MySpace.com and Writely being snapped up for big bucks. And the sense of deja vu goes even further for some experts. Just as in the early days of desktop software, they say, the development momentum is all about features–and protections are being neglected.

In previous articles we have discussed the realistic threat of security exploitations such as Cross Site Scripting and some techniques to overcome the cross site script attacks. AJAX increases the possibility of security exploitation due to increased “attack surface”. By this it is meant that increasing the scripts and request infrastructure we are potentially opening up more areas for exploitation of our application.

The increased “attack surface” is the result of upping the complexity of the client side interface but also the additional server side scripting required to provide the required functionality. The analogy been thrown around at the moment is that Web 1.0 is more like a house with no windows, just one big door. In this model you can spend time putting great big locks and beefy security on that one big door. Web 2.0 introduces new windows that have to have equal security to secure the whole house.

The model of Web 2.0 is fairly new, and has no real official practices available for the average “joe” programmer to identify. Most script appearing online and in recent books are not intended for “Production Ready” sites. Often the average “joe” will be implementing a whole bunch of server side scripts and client side scripts without having the correct models to secure those scripts.

Before rushing out and implementing dozens of scripts to perform AJAX think of the potential security risks associated with creating those “windows” in your application and how you will treat the requests and any sensitive responses.

June 16, 2006

PHP form input and Cross-Site attacks

You will find other articles relevant to this document in these sections:
Cameron Manderson @ 11:51 am

Something that we have to be careful to consider is hackers generating a Form and remotely sending form input to your website. eg.

  1. Hacker creates a form that has the same variables as your website form, and sets the action to your websites form action;
  2. Hacker hits submit to inject in values to your form; such as malicious code or generating a script that automatically inserts data

Although we learn never to trust information sent to us in a form and checking the submitted values to be valid, we will also want to consider the origin of the forms submission [Cross-Site Request Forgeries (CSRF)]. Our Environment variables allow us to check a variable called HTTP-REFERRER but this can be easily changed by the hacker. So instead we will need to consider ways to ensure the form originated from our website (and only issued once).

I have done a little research into ways and Chris Shifflet recommends a token placed into the form and applied to the users session. This method can prove a very useful method of identifying whether a form had been “issued” from your website. His example of a useful way to help limit the occurance of this issue:

<?php
$token = md5(uniqid(rand(), true));
$_SESSION[‘token’] = $token;
$_SESSION[‘token_timestamp’] = time();
?>


<form action=”/add_post.php” method=”post”>
<input type=”hidden” name=”token” value=”<?php echo $token; ?>” />
Subject: <input type=”text” name=”post_subject” />
Message: <textarea name=”post_message”></textarea>
<input type=”submit” value=”Add Post” />
</form>

Chris’s recommendation supplies quite a good method of forcing the use of your own HTML forms, but is linear in nature (one form with one submit). For this to be more rock solid we need to consider implementation issues we always face as Web Developers: Multiple Windows and the Back Button.

We can make some more modifications to the script by including a 2D array of issued form tokens, and individually identify the Form with the corresponding Token:

<?php
$formId = md5(uniqid(rand(), true));
$token = md5(uniqid(rand(), true));

$_SESSION[‘formTokens’][$formId][‘token’] = $token;
$_SESSION[‘formTokens’][$formId][‘token_timestamp’] = time();
?>

<form action=”/add_post.php” method=”post”>
<input type=”hidden” name=”formId” value=”<?php echo $formId; ?>” />
<input type=”hidden” name=”token” value=”<?php echo $token; ?>” />
Subject: <input type=”text” name=”post_subject” />
Message: <textarea name=”post_message”></textarea>
<input type=”submit” value=”Add Post” />
</form>

We now are able to uniquely identify the valid token based on a unique form ID, with its own timeout values etc. This will allow us to cater for multiple windows or use of the back button across our forms.

June 15, 2006

Sharing a session across multiple domains/servers with PHP

You will find other articles relevant to this document in these sections:
Cameron Manderson @ 5:40 pm

Updated 15 June 2007: I have provided the source code to this and a working example of sharing a session across unique domains here.

In-light of a recent project I have had to consider a strategy from diverting a user from an non-SSL server running to a different domain running SSL, and keep the same session. This would involve keeping the user who is signed in on the first server with a session cart selection being somehow shared to the next server. It also requires that the user have a single sign-in between several different domains.

Get your sessions into a database
To consider the sharing of information between different domains where they are potentially run by different users or servers, we would need to place the session information directly into a database that is able to be read in by each domain.

To get your sessions into a database, we could:
- Gain control of the Session with a PHP SessionWrapper using a Singleton
- Overwrite the main _open, _read, _write, _close, _destroy and _gc methods to persist to a common datasource (MySQL database)
- Create a _sessionInit method that checks for a PHPSESSID from the Request, if not checks the Cookie for a PHPSESSID
- Create the session with the ID present (if one)

My database table (session) would form:
- sessionkey varchar(32)
- data text
- expiry timestamp

This will securely conform with ownership issues in PHP Safe Mode as the session data will not be written to disk under each web user, it will be written to a common secure database accessible by other websites (with the correct username/password etc). Once again as you will be now taking over some of the security of a session you could read on ways of encrypting the information stored in the database for further security. You will simply need to add methods of encrypting the information (either with Symetrical or Assymetrical keys) in your _read and _write methods of your Session Wrapper.

* Note: I would recommend that you don’t store sensitive information in your session as by default it will be serialised in clear text to your datastore. Anyone capable accessing your session information will be able to see the details (such as CC details etc).

Updated 21 June 2006: Zend provide a good Code Gallery spotlight that gives a good example of a custom session handler to MySQL Database. You can read their article here.

Sharing the Session ID between sites
When diverting the user to the Secure server they would be parsed over using a URL containing the current PHPSESSID to resume on the next hosting service. If they end up at the website without travelling through a URL with PHPSESSID we can attempt to gain it from the user VIA the cookie (if present this is done automatically by PHP). But how can we ensure the user isn’t starting new sessions?

Centralised Issuing Session ID Server
So we have centralised our Sessions and made them available across multiple domains, but how can we further further ensure that the user holds onto the same Session ID? As there is not always clear sever points between the applications, parsing the Session ID in the URL might not be always as easy to track. Even if we searched through all links and applied the PHPSESSID in the URL - a user may decide to type in a domain directly to switch to the different server.

Unfortunately Cookies can not be shared across different domains (* although they can be across subdomains), so we cannot simply keep track of a session ID via a cookie.

A way to backup remedy to this would be to involve a Session ID issuing server that you can bounce a visitor off when creating an initial visit. The user is returned to the site URL they were requesting but after having a centralised Session ID inserted into their request. Also, if for some reason you wish to not reveal the Session ID in the bounce you could simply place in a retrieve_key that looks up the Session ID once the user is returned to their previous URL. You would also need to assign to the session a unique variable that indicated the session was “issued” and is not created by itself.

Using this central session ID manager as a fall back we could help eliminate those cases when the user shows up at a different domain and starting a new session ID. In some cases you may even be able to eliminate the requirement of parsing PHPSESSID in the URLs.

You will need to consider the security implications of handling sessions this way. If you need to regenerate a session ID it must be done with the Centralised Issuing server otherwise you will either loose the information in your session or start dual sessions that are not shared.

In most cases we will try to use the SSL server as the centralised issuing server and all secure steps can be processed under this URL. We can destoy the session on this server and start a new session. It will automatically cause the other domains to try and retrieve a new key (as long as we assign to the session a unique variable that indicated the session was issued, as when the session can’t be resumed on the other domains, they will realise they have to get a new session ID from the centralised server).

June 6, 2006

PHP Source Code Protect

You will find other articles relevant to this document in these sections:
Cameron Manderson @ 1:25 pm

I have been using PHP for commercial products now for some time and I have always been concerned with providing code to clients that is not protected from other developers - one thing that we are familiar with compiling/distributing code under C++ or Java. Often code that is included in even the smallest a job to make our life a lot easier and can be the result of hundred of hours of unpaid development.

There are a number of different methods to help disguise and protect our code under PHP and is often overlooked by many web developers. For reasons I am unsure, maybe the same reason that the Internet has failed to develop standards. As we have discussed topics of security on this site I think it is important to discuss ways to secure a commercial application or a standard library that you or your business have developed in PHP.

This scenario could apply to:

  • Distribute shareware or trial software written in PHP
  • Protect source code from being viewed by other developers or by your hosting provider
  • Freelancers working on small/group projects without giving away their entire library of developed code
  • Harden the ability for people to analyse ways to exploit/hack your code

Considering licences such as expiring applications or limiting what servers or domains host your files are all possible with the help of a few software packages. You can embed the licensing in each file, or call on a licence file that could be issued (FTP’d) to your server. Also, degrees of how you protect your intellectual property and source code are covered such as compilation, encryption or obfuscation.

In terms of protecting your source code instead of trying to explain the meaning better than wikipedia, I thought I would just include: “Obfuscated code is source code that is (perhaps intentionally) very hard to read and understand.” Typically we can perform obfuscation through replacing local variables, functions and removing formatting and commenting. (It is worth noting that if you are working with creating a reusable package that variable or function obfuscation may not be quite what you are after).

A method of obfuscation could be to create a intermediate compiled code, which often is smaller and more efficient. It also can be a way of protecting our code from reverse engineering. Obfuscation can also be an example of security through obscurity, (which should never be relied on). To further the protection of our code we should consider encryption of our code.

If you have used an MVC implementation you may only consider protecting your Model or maybe your Model and Controller. You may wish to leave your View (Smarty/HTML/etc) as open as you will not want to limit simple visual updates that you may not be available to update for your client. Typically your view is not reusable and does not contain your Intellectual Property – and I imagine may often cause more problems than it is worth, but depends on the scenario.

There are packages that help protect our source code (through compilation, obfuscation and encryption) and most come with friendly GUI to help us achieve protection and handle licensing.

When we protect our code typically it requires server side installation to provide the required functionality (although some can export bundled required files). There are a few that provide the functionality through included source files. Your decision of which package to use will be in some part dictated by the support of your hosting company. I recommend your first step to check what package is available to you. I gave my hosting company and quick call and asked them what methods they support to secure my PHP source code and found that my hosting company supports two popular packages:

Both are available for purchase at around the ~US$250 or ~AUS$380 which really is quite a small investment when you consider the protection it can provide. If you own your own business or freelance you would immediately see that for the small investment you will gain a big return: protection of your intellectual property and future work. You may also find that as part of your professional practice of being a responsible programmer that suggesting the cost be included in a project budget as it can help further strengthen your security.

ionCube Project Sheet

Default Project Sheets

ionCube add source code to protect

Select project files

Example of output code from ionCube:

if(!extension_loaded('ionCube Loader')){$__oc=strtolower(substr(php_uname(),0,3));$__ln='/ioncube/ioncube_loader_'.$__oc.'_'.substr(phpversion(),0,3).(($__oc=='win')?'.dll':'.so');$__oid=$__id=realpath(ini_get('extension_dir'));$__here=dirname(__FILE__);if((@$__id[1])==':'){$__id=str_replace('','/',substr($__id,2));$__here=str_replace('','/',substr($__here,2));}$__rd=str_repeat('/..',substr_count($__id,'/')).$__here.'/';$__i=strlen($__rd);while($__i--){if($__rd[$__i]=='/'){$__lp=substr($__rd,0,$__i).$__ln;if(file_exists($__oid.$__lp)){$__ln=$__lp;break;}}}@dl($__ln);}else{echo('The file '.__FILE__." is corrupted.n");return 0;}if(function_exists('_il_exec')){return _il_exec();}echo('This encoded file cannot be run. Please run the file ioncube-loader-helper.php for more information.');return 0;
 
?>
0y4hYErdHGVGixqeLj/G9FXUdF4/0fdmCtjjNAv3HcIYGaw0iOU34iT84LwcPV5XJcau0RQgkiNL
AVfBK2FhhSoxdC504USDRPO+lhcm5T6RBUjej+Xz8amc0pUigrTnMMmjcdW3ZewemB0XE5aLmAgT
fbcV0ToCKoCpSbfEpCAgH0tccGSSV3a1×1NC3KkjGLT0Ld/PzHVao/q6Zveq1/vLZ2FFpFK5lH6u
iT+lo8Av02HzMsKNl3zafQuLOTKQoWpGI3sRe9fKyK/pDQa/8FMYHCpwZ7lBKQzL5Ha3h56RS+e3
FbDgAbfY2t1i14GW8J5s6eq94fjhAEbGQ4fHa43LTeUy0qCLdW==

The first section of the code handles how to load the dynamic libraries and checks support for iconCube. The second is the ASCII (you can export out in binary) source code.

Unfortunately for some reason my hosting company didn’t support Zend’s product. Zend provides a Zend Guard which is more expensive but operates on the popular free Zend Optimiser server side which generally most hosting companies will have or won’t be bothered installing, although mine did.

Both of the other products provide an easy way to generate a licence file which allows you to customise the restrictions for individual end-users without having to resupply the compiled protected source code again. You can simply FTP or generate and email the new licence file. This is particularly good for converting Trial software into full working versions, or from a development version to a full version for production.

Standard License Options

Some standard options for licensing in ionCube

Example of licence file contents:

------ LICENSE FILE DATA -------
TY24U9294dRrU8XBUkuaZ9ITVuwcMAZc
9bBtv0mZcsLrK6E5LnHJMN9glODwfHF3
pSv9XCuR9JGhpfyXvYOXe3cjsMD6qzGr
2mnQcvm6zftypTDRLf+TdlCTjxWJKbVd
4eFgH6+cfvR8QqAIO8EQ3XCwZ/S+o7r/
mnGKru11PbFrsJvZ0oDPPZZgLH0OIHZL
edk4/AKKg2KMztID9oWoW9D4jmd3nGaN
kjgWaXeTU7yGN+ojRf/vOM984m4Fjmuu
eoGHlkbGLIR7Ot5lF3==
------------------------------–

Before you choose which package suits your requirements better, you will want to view over the feature checklist and download and play with a trial version (and test on your deployment server). I found it particularly difficult to find the differences between the two.

In the end? I chose ionCube as it came across to me as more established product and supported all the good features I expect from an encoding package. Also general comments from forums appear to be fairly positive and it runs on ionCubes own code optimiser.

After installation of the trial versions both come with easy to use Wizards and Licence Generators. You typically need to create your project and select your source file. Within a few minutes you can easily identify all the advanced functionality and have working encoded source files.

Advanced steps allow you to customise dynamic variables that are included in your licence. You can also even consider ways to write the licensing into your source code, but this will not be enforced by the your packages parser (e.g. By ionCube etc), but that way you can start to extend the functionality of your licensing past the standard; and even use Digital Signatures to ensure non-tampering of your source (and underlying licensing system). That way you are not relying on an individual encoders licensing and you may be able to encode using different encoders if you meet a project that needs to run on a different choice of encoder.

After setting up my first encode with ionCube I timed the originals versus the encoded. A simple API consisting of around 30 classes and about 100KB of code. A simple include of the class file saw an immediate 50% increase in speed of the include. (From around .03 seconds to around .015 seconds).

Also it may be worth mentioning that if you have a lot of classes it may be easier to concatenate all the files into one single distributable file. To do this you can create a simple concatenate/compress class that gets the file contents of each of your PHP class files and places them into a single temp file. You can then invoke PHP CLI to compress your classes. This removes white-space (new lines, tabs etc) and commenting. The end result is raw PHP. Note: Be sure to remove any “include” statements that call on included source code as it may cause errors.

// Consider security if variable contain user input
$execute = "php -w " . $incFile . " > " . $destFile;
exec($execute);

Testing this in the past it is a quick way of including your files. Including individually can result in large delays (depending on how many class-path directories need to be scanned to locate the files to include). One thing you will have to consider then is whether you concatenate all classes or just base classes, then use further includes to pull in required functionality, as part of your API may not be required. You can use simple profiling techniques to identify times taken to load.

Further to developing your commercial API you may consider using an documentation generator like phpDoc. Depending on how you setup your commenting and phpDoc, you can indicate which parts functions and files are documented publicly. Ensure to analyse how your API will be used, and protect functions that are not to be invoked. Further to this topic you will need to research ways of writing a commercial API that conceals unnecessary functionality and I.P.

Here are the some useful resources that will help you protect your source code:

May 19, 2006

PHP Generating Passwords

You will find other articles relevant to this document in these sections:
Cameron Manderson @ 10:24 am

There are many different ways to generate passwords, and (depending on the requirements) will need to involve both numbers and letters (preferrably additional special characters like !@#$%^ etc). With PHP the generally easiest way to generate a password is to use a random number mapping to a pointer in a string of ‘valid’ characters. A simple example may be as follows:

Generate password using a for loop and random pointer and string of allowed characters

// Generate a password
$password = '';
$len = 6;
$validCharacters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabchefghjkmnpqrstuvwxyz0123456789';
while (strlen($password) < $len) {
  $pointer = rand() % strlen($validCharacters);
  $nextChar = substr($validCharacters, $pointer, 1);
  $password .= $nextChar;
}
print "Your new password is " . $password;

Trying to use a larger set of valid characters and the length of the password will help build the strength of your password. Including special characters into the set will help also.
NOTE: Consider if having issues like i,I,1,l,L,0,O (all different characters) will cause confusion and you may consider stripping some of them out (like done above).

Technically, I am sure a maths person will be able to figure out using probability the chances of the pointer landing on a set of upper case, lower case or number, and be able to better guess at what a likely result would be.

Instead we could re-write the function above to use a array, that allows us to seperate out the character sets, and from there we could better balance the generation. We can also then write a more useful password generation function that will allow us to specify not only length, but strength (based on what sets of characters are included).

Generate a password using a array of allowed character set with 2 random pointers

/**
 * Generate a password based on sets of characters (levels)
 *
 * String getNewPassword(int $length, int $level);
 * Set level higher to include more character sets
 * 1 = lowercase alpha
 * 2 = mixed case alpha
 * 3 = mixed case alphanumeric
 * 4 = mixed case alphanumeric and special characters
 *
 * @param length int Length of password
 * @param level int Sets number of character sets to include
 * @return String New Password based on parameters
 * @author Cameron Manderson &lt;cameronmanderson@gmail.com&gt;
 */
function getNewPassword($length = 8, $level = 3) {
  // Our character Sets
  $characterSets = array();
  $characterSets[] = 'abcdefghijklmnopqrstuvwxyz';
  $characterSets[] = 'ABCDEFGHIJKLMNOPQSRTUVWXYZ';
  $characterSets[] = '01234567890';
  $characterSets[] = '`~!@#$%^&*()-_=+.'/\"';
 
  // Check we have a valid level
  if($level > count($characterSets)) $level = count($characterSets);
  else if($level < 1) $level = 1;
 
  // Generate the password
  $password = ''; // Out new password
  for($i = 0; $i < $length; $i++) {
    $xPointer = rand() % $level; // Get out set pointer
    $yPointer = rand() % strlen($characterSets[$xPointer]);
    $password .= substr($characterSets[$xPointer], $yPointer, 1);
  }

  // Return our new password
    return $password;
}

You will also want to consider how you are going to store your passwords. There are many different algorithms and approaches that can be taken. SHA and MD5 are very common.

April 7, 2006

PHP Encrypting using PKI/GnuPG

You will find other articles relevant to this document in these sections:
Cameron Manderson @ 2:33 pm

PKI (Public Key Infrastructure) is well known to security buffs. It involves the use of a public key to encrypt something, and can not be reused to decrypt. Instead, a private key kept secure by the intended recipient is used to decrypt. This allows the public key to be freely available online and useless for decrypting messages created with it. Originally (to my knowledge) it was first implemented by a guy who wrote PGP (Pretty Good Privacy). History asside, the PGP is a commercial application and GnuPG is an open source implementation. Both are interchangeable.
Because it is open source we often find it available on Linux hosting. This means that using GnuPG we can encrypt secure messages received by the server (not to the server, that can still be intercepted unless under HTTPS protocol). Keys can have varying strengths (2048bit for example) and have different types (e.g. RSA) with cipher/hash combinations (e.g. AES-256/SHA-2-256). Perfect for making some pretty damn secure messaging.

This requires you to have your public key added to your GnuPG Keychain that the webuser can access. A good example for getting GnuPG installed and having your keychain added is here. You typically can just send your public key chain in an email message to your hosting company and have them add it to their keychain. They will be friendly to add it.

You will need to know the directory to gpg bin on your hosting server, as well as the .gnupg keychain location to specify in your –homedir parameter. Your hosting company again will save you with this one.

So, as a simple example on the usage of GnuPG I will demonstrate by discussing a quick way of encrypting details received by form input:

$prefix = 'enc';
$command = '/usr/bin/gpg --always-trust --batch --no-secmem-warning --homedir /home/www/.gnupg -a -r "Cameron Manderson" -e';
$tmpFile = tempnam('/tmp', $prefix);
$pipe = popen("$command 2>&1 >$tmpFile", 'w');
if (!$pipe) {
unlink($tmpFile);
} else {
fwrite($pipe, $plainTxt, strlen($plainTxt));
pclose($pipe);
$fd = fopen($tmpFile, "rb");
$output = fread($fd, filesize($tmpFile));
fclose($fd);
unlink($tmpFile);
}

The idea behind the code above code is that we form a message assigned to the variable $plainTxt, and have it encrypted by the popen call, then have the encrypted details placed into $output. If you are using this to accept input from a user and encrypt it (such as encrypting credit card details and the like) you will want to ensure you are under a suffice level of HTTPS.
I have purchased a copy of PGP Desktop which allows me under a windows gui environment decrypt and view the contents of a message. This is great for end users because it allows them to easily decrypt a message using windows. It also can integrate into their mail application (such as Outlook or Thunderbird).

More on PHP and Access Control Lists (ACL)

You will find other articles relevant to this document in these sections:
Cameron Manderson @ 10:00 am

I thought I would discuss a quick overview on the structure to ACL for your applications. For initial background on ACL read this previous article first.

The implementation on ACL I have used in the past and appears in several different well known GNU applications is PHP Generic Access Control Lists (phpGACL). This library provides two main classes and an Administration Screen. The administration screen allows us a friendly way of managing our control lists, and the classes are used to check/modify them in our application. Overall I have found this package quite suitable for most situations.
Once installed, you will need to get familiar with the different terminology that is used.

First we must analyse the way that we need to set up our application. Typically we have many users with different group permissions. I like to use

- Developer
- Administrator
- Staff
- Public

These groups are groups of ARO or Access Request Objects. Therefore our 2Dimensional implementation is infact (ARO requests ACO). They are often the groups of system actors in your application, and represent the different objects/users making the requests. You can deal with groups of ARO’s or single ARO’s in your application. Your API calls will change slightly, my examples will explain as ARO groups.
How we manage the resources they wish to access can be either in a 2Dimensional (ARO requests this action) or 3D (ARO request this action on this object).

Both the ways of managing requires you to define our action/controlled object. These are called ACO or Access Controlled Objects. Typically I like to define a few sections of ACO’s, first being for the action being requested (in terms of MVC), and secondly any more fine-grained permissions, such as ‘Allow Edit’, ‘Allow Delete’, ‘Allow Hidden’ etc. Your ACO may end up being similar to:

Section: Actions
- login
- logout
- home
- documents
And another Section may manage specific more finegrained functionality on a particular operation:

Section: Documents
- edit
- add
- delete

In most situations this is more than enough for our small applications, and allows us to create well manageable applications, being able to create custom users/groups with specific permissions in our application, without requiring changes to our source code. As explained in my previous article, ACL allows us to make our security implementation extendable and manageable without requiring hundreds of updates to each of our source code files.

Now when we with to check a 2Dimensional request, we can do so with a simple ACL check; acl_check($resource, $group);

For our section ‘Actions’ I like to typically place this resource in our RequestProcessor, allowing us to have a ‘gatekeeper’ to whether the requested action can be performed by the current logged in user. This will ensure that every action is checked against the users permissions, before loading the Action to perform.

Our section ‘Documents’ would call specific checks to whether the user is allowed to perform a certain action in our Action class through again another set of ACL checks.

This situation becomes more complex when with have specific resources that the user wishes to manage, such as documents in a specific project. This becomes a 3Dimensional implementation that is when our ACO requests an ARO on a particular object. Yes I understand we are talking Object requests Object on an Object, and can come a bit complex, but the best is with an example. The 3rd Object is termed a AXO, or Access eXtension Object.

our AXO Section may look as follows:

Section: Projects
- project 1
- project 2
- project 3

This now allows us to further split down our requests so that our Document Management actions can be specific for a user in a particular project. Our ACL check becomes a little more complex, with having to specify a 3rd level.

Overall this implementation allows us to start to secure down what actions can be performed by our application users. We need to be conscious now to over-allow or over-complex our application for users as it will just mean more testing, training and explaining. Remember, just having ACL’s in your application does not make it more secure unless you use them correctly. You must be conscious of breaking down permissions, correctly verifying users and ensuring that you don’t just grant everything in your application.

April 4, 2006

PHP and Authentication Security

You will find other articles relevant to this document in these sections:
Cameron Manderson @ 10:10 am

A little while back I discussed the theory to how you can setup a Challenge/Response architecture using PHP and MVC pattern. This discussed ways of having the password hashed client side using a server issued “challenge” key to make a “response”. This allowed us to protect the password in clear text from being intercepted across a HTTP network.

Once we have the user we need to authenticate the details they have submitted. To do this the usual approach is to query a ‘user’ table in your database to check the corresponding username and password.

This is fine in most situations, but as systems scale we often find that maintaining this user table with current user/passwords can be a lot of trouble. Often in larger systems and organisations usernames and passwords are controlled centrally. This can be in the form of a directory service, such as LDAP. Some situations you may even use a RADIUS, SAMBA, PASSWD style or POP3.

Before we start worrying about connectivity to these servers, and overcoming the challenges of supporting all different protocols, we can look at a pre-written package written by the PEAR group.

PEAR::Auth

Pear Auth is a abstraction that allows us to connect to various authentication systems. It supports all of the above mentioned, as well as DB, IMAP, vpopmail and even SOAP (incase you already have a proprietory written authentication database - possibly even in a different language). It also allows us to extend and make our own driver, which can implement its own checking devices as required.

Using PEAR::Auth ensures that our authentication system stays abstract and scalable. It also overcomes issues of doubling up on username/passwords or the additional maintenance of our authentication DB. For those of you who wish to implement a HTTP style (like Apache .htaccess for your PHP) try checking out the PEAR::Auth_HTTP.

If your hosting service does not want to help you install PEAR into their include_paths of PHP, follow this guide to using libraries without requiring your hosting service to install. Remember, if you are using $_SESSION in your application, be careful of some of the security holes that are opened. Have a look at my discussion of Sessional Handling with PHP and read the resources I have linked to.

From here we need to correctly implement ACL to control the resources that the user accesses. (Updated: More on PHP and Access Control Lists)
To this point this has allowed us to create a fairly flexible and robust authentication system for your PHP application. You must still follow good security practise in your application to ensure that exploits are not openned. As mentioned in previous articles, PHP SEC is a good website on the discussion of PHP and Security. You should occasionally check out the articles posted to stay aware on the topic of security in your applications.

Next Page »