Webtatic.com

Just another technical blog

PHP 5.2.10 on CentOS 5

Posted 20th June 2009 by Andy | 5 Comments

My previous articles on installing PHP on CentOS dealt with installing PHP 5.2.6. I have found this to have some bugs that kill the process without error information. One bug I found, which was on an x86_64 server, was that converting an object to a string did this.

So, I have compiled the latest PHP version, 5.2.10, and put it in my own repository for easy installation. I have compiled it for CentOS 5 i386 and x86_64, and provided the source RPMS in the repo, if anyone wants to compile it for another OS or architecture.

I have also included the same php extensions I mentioned in my other article, php-mcrypt, php-mhash, php-mssql and php-tidy

To install, first you must tell rpm to accept rpm’s signed by me:

rpm --import http://repo.webtatic.com/yum/RPM-GPG-KEY-webtatic-andy

Then add the yum repository information to yum:

cd /etc/yum.repos.d/
wget http://repo.webtatic.com/yum/webtatic.repo

Now you can upgrade php by doing:

yum --enablerepo=webtatic update php

Posted in category: Server Admin, Software | Tags: ,

mod_auth_mysql digest authentication patch

Posted 31st May 2009 by Andy | 2 Comments

Recently, I wrote a mod_perl module for using a database backend for basic and digest authentication in Apache, however I found it to be much slower than mod_auth_mysql. This would be due to using mod_perl and DBI. So I have written a patch for mod_auth_mysql which performs the same, which means its as fast.

The main reason why I chose to do this rather than use Webtatic::AuthDBI is because subversion checkouts were taking twice as long. A mod_perl authentication provider, even without performing authentication (just returning OK for any login details) seems to be the speed of the whole mod_auth_mysql without even establishing a mysql connection.

This patch seems to perform just as well as mod_auth_mysql.

Check it out here: /projects/mod_auth_mysql-auth/

Secure digest HTTP authentication using Webtatic::AuthDBI

Posted 24th May 2009 by Andy | No Comments

The HTTP protocol gives a standardised way to provide authentication. This is supported via two modes:
Basic - transmit the username and password in a reversable base-64 encode
Digest - transmits complex MD5 hash of the username, realm, password, a server generated nonce, request method and request uri

Basic HTTP authentication suffers from a very easy man-in-the-middle attack, where the attacker can simply reverse the base-64 encode to get the user’s password. This is preventable if switching to HTTPS, where a man-in-the-middle is not possible.

Digest HTTP authentication however uses a complex series of MD5 operations on data provided by the server and client variables. This, depending on the server implementation, can prevent the man-in-the-middle from decyphering the password, and prevent replay attacks.

Digest HTTP authentication is relatively new, but is supported fully in all the latest browsers. Internet Explorer 6 however does not support the standard correctly, but there is an Apache server workaround to allow it.

I have written a mod_perl module which will provide a database backend to this method, called Webtatic::AuthDBI. It is similar to that of mod_auth_mysql, which only supports Basic auth.

I have published a project page for this at /projects/webtaticauthdbi/. It is free to use, and uses the same licensing terms as Perl. Installation and use instructions are on that page.

In theory, digest authentication will be more secure than cookie sessions, as once the session id is captured by the attacker, the attacker could then use that session themselves. Digest authentication always sends a different authorization header every request, so if the server can prevent replay attacks, the attacker wouldn’t be able to use the header again.

Posted in category: Server Admin, Software | Tags: , , ,

Installing PHP 5.2.6 on CentOS 5 - extra extensions

Posted 19th May 2009 by Andy | 6 Comments

Update 20th June 2009 - I found a bug in PHP 5.2.9, so I have compiled 5.2.9 rpms, including the ones that this article talks about, check out the article here.
Update 23rd May 2009 - It appears dbase, readline, json and filter were included either compiled into php or as a shared module in php-common, so I’ve removed them from the spec.

In using the installation of PHP 5.2.6 on CentOS, I noticed that there were a few modules missing from the repository that are included as part of CentOS’s extras repository. They are nowhere to be found in the testing repository.

I found an easy way to build the RPM’s by downloading both the testing php source RPM (SRPM), and the extras php-extras-5.1.6 SRPM, rewriting the php-extras spec file so it incorporated the same patches, and building it as the php-5.2.6 version.

The php-extras include the dbase, readline, mcrypt, mhash, tidy and mssql extensions. In my spec file, I have removed dbase and readline, as they have moved to php-common. I have also included the newly added extensions to php 5.2; json and filter. In future versions of CentOS, these should hopefully be updated in the extras or the base repository.
Continue reading Installing PHP 5.2.6 on CentOS 5 - extra extensions »

Posted in category: Server Admin, Software, Web Development | Tags: ,

Installing PHP 5.2.6 on CentOS 5

Posted 17th May 2009 by Andy | 9 Comments

Update 20th June 2009 - I found a bug in PHP 5.2.6, so I have compiled 5.2.10 rpms and provided a repository from which to install them, check out the article here.
Update 19th May 2009 - I have written an article here detailing how to build RPMs and install some additional php extensions, which although part of the PHP source distribution, is not included in this installation (extensions mcrypt, mhash, tidy, mssql)

Update 13th June 2009 - I’ve made the guide easier by using yum options to install the testing RPMs rather than using yum-priorities.

Redhat-based distributions tend to supply out of date releases of software. This isn’t technically a bad thing. They extensively test their updates before releasing out to the public, and upstream security fixes from the latest versions, meaning that they can be extremely stable when compared to some other distributions such as Debian-based Ubuntu.

However, this means that you rarely get new features added, until there is a new major release. Again this isn’t all bad, as new features add new bugs, which affect stability.

PHP 5.1.6, which is part of the base CentOS repository, was released 24-Aug-2006, almost 3 years ago. Since then, PHP 5.2 has been released, gone through 9 release builds since, and is considered stable for production environments.
Continue reading Installing PHP 5.2.6 on CentOS 5 »

Posted in category: Server Admin, Software, Web Development | Tags: , ,

Generating a random PHP identifier

Posted 2nd May 2009 by Andy | 5 Comments

Update 1st June 2009 - Added a note mentioning about case-insensitive comparisons in MySQL.

I’ve been looking at generating random identifiers in PHP, and making sure they are random enough. Looking at the PHP function uniqid(), and its suggested better token, I don’t think this is an adiquate enough way:

$better_token = md5(uniqid(rand(), true));

Md5 is a 128 bit hash algorithm. Looking at the data inside the function, there doesn’t appear to be enough data (i.e. entrophy) for the 128 bits, so at best, the uniqueness of the resulting string will be less than the capacity of the md5.

uniqid(), this alone generates 13 hexadecimal characters, which is the equivallent of 52 bits,
rand(), generates a random integer number, which would fill 32 bits
uniqid(”, true), this appends additional entropy to the string, 9 decimal numbers and a dot, less than 20 bits of randomness

Adding these all up, 52+32+20 = 104 bits.

So what happens when you md5 a value that has 104 bits of randomness? You get at most 2^104 possible random values back in a md5 that has 2^128 values. Hashing algorithms can have multiple input values which generate the same output value, causing collisions, so the actual randomness would be less.

A better way

*nix systems (including Solaris, Linux, OSX and FreeBSD) have special device files usually /dev/random, which can generate as much randomness as required by reading in the number of bytes needed. /dev/urandom is a non-blocking version which sacrifices entrophy in order for the file to not lock.

$uniqueId = bin2hex(file_get_contents('/dev/urandom', 0, null, -1, 16));

This will return a random 32 character hexadecimal (128 bits). You shouldn’t need to md5 this.

Generating a shorter (yet just as random) string suitable for urls

The hexadecimal format consists of the numbers 0-9 and a-f, 16 symbols in total, yet there are many more acceptable acceptable characters available in a url.

You can have a shorter identifier if you encode the binary data as base 64 instead, which as its name suggests, has 64 symbols. However, the standard ascii symbols used in this encoding include + and /, which have special meaning in URLs. You can convert these to - and _ respectively to make them more compatible.

Also, base-64 encoding pads the end with = if there isn’t enough bytes in a block. These are not needed by an identifier, so can be stripped.

If the data string is already in binary, you can just do the following to convert it to base 64:

$base64encodedString = str_replace(
    array('+','/','='),
    array('-','_',''),
    base64_encode(md5($data, true)));

If however the data was in hexadecimal, you can convert it to binary using the php function pack() beforehand:

$base64encodedString = str_replace(
    array('+','/','='),
    array('-','_',''),
    base64_encode(pack('H*', md5($data))));

Doing this will shorten a 32 character hexadecimal into a 22 character base-64 encoded string.

Please note that when doing MySQL comparisons, your text field’s collate will most likely be case-insensitive. Comparing a base64 string against one in the database when the collation is case-insensitive (e.g. latin1_*_ci, utf8_*_ci) will dramatically increase the chance of collisions as 26 of the 64 characters will match the other 26 case ones, giving a significant reduction in bits.

Posted in category: Web Development | Tags: