Archive for the ‘PHP’ Category

Parse and Clean Query Strings with PHP

Tuesday, March 23rd, 2010

I wrote a quick, useful function in PHP to parse a query string, strip out dirty key(s), and return the cleaned query string.

The function expects two parameters

  1. $dirty – a string, or an array of strings. These are the names of the variables that will be stripped out.
  2. $qs – OPTIONAL – The source to use as the query string. If not provided, the $_SERVER['QUERY_STRING'] variable is used

The function returns a string in the format

var1=value1&var2=value2…

function clean_query_string($dirty, $qs = false) {
    //default to the server query string if none is provided
    $qs = ($qs) ? $qs : $_SERVER['QUERY_STRING'];

    // parse the query string as an array, writing it
    // down as a string as we go
    $clean = "";
    foreach(explode("&", $qs) as $var) {
        $t = explode("=", $var);
        if( !in_array($t[0], (array)$dirty) ) {
            $clean .= "{$t[0]}={$t[1]}&";
        }
    }

    //trim the trailing ampersand
    return trim($clean, "&");
}

Variable variables in PHP

Tuesday, March 2nd, 2010

Well, after a couple month hiatus, I guess it is time to throw up another post. I was up working on a project, and came across a completely valid usage of variable variables, and felt it might be worth making a post, because it is kind of fun.

At first glance, “variable variables” seemed pretty pointless to me. Surely they had a place somewhere, but I guess that’s just not how I write code. The best use I could think of was a pointless, but stupid-fun script, like this:

$a = "hello world";
$b = "a";
$c = "b";
$d = "c";
$e = "d";
$f = $$$$$e;

Perhaps, for this example I’m about to use, there is a better way of accomplishing the task (I can think of other methods, but can argue which is “better”). My task was to feed a function the numerical representation of a month, and spit back the textual representation, adhering to preferred formatting. So I wrote a function that has a couple hard-coded lookup arrays, named after the $format parameter. The function is pretty well self-explanatory:

function getMonth($i, $format = 'F') {
    $F = array(
        1 => "January",
        2 => "February",
        3 => "March",
        4 => "April",
        5 => "May",
        6 => "June",
        7 => "July",
        8 => "August",
        9 => "September",
       10 => "October",
       11 => "November",
       12 => "December",
    );

    $M = array(
        1 => "Jan",
        2 => "Feb",
        3 => "Mar",
        4 => "Apr",
        5 => "May",
        6 => "Jun",
        7 => "Jul",
        8 => "Aug",
        9 => "Sep",
       10 => "Oct",
       11 => "Nov",
       12 => "Dec",
    );

    $format = strtoupper($format);

    if($format != 'F' && $format != 'M') {
        $format = 'F';
    }

    if($i > 12 || $i < 1) {
        return false;
    }

    $source = $$format;
    return $source[$i];
}

just another php hacker

Wednesday, December 23rd, 2009

After reading about the Just Another Perl Hacker code snippets on Wikipedia, I was pretty intrigued. The only problem is, I hate Perl. So, here is my version: just another php hacker.

I cleaned the code up a little bit here for readability (which is against the point, I guess).

foreach(explode("2","1152117298211521162114") as $z) {
	$h .= chr($z);
}

$f = (string)(2*19*227*11489);

$q = chr($h($f,(int)$f[3],(int)$f[2]+1)).chr($h($f,(int)$f[2]+1,(int)$f[0]/3)).chr($h($f,(int)$f[strlen($f)-1]+1,(int)$f[0]/3));

$z = eval("\$u=".$q."(".str_replace("3",").$q(","117311031153101311431053973108310531223101").");");

$w = "a:23:{i:0F106F1F11F2F-2F3F1F4F-84F5F65F6F13F7F1F8F5F9F-12F10F-3F11F13F12F-82F13F80F14F-8F15F8F16F-80F17F72F18F-7F19F2F20F8F21F-6F22F13;}";

$b = str_replace("F",";i:", $w);

foreach($u($b) as $c) {
	echo($q($s+=$c));
}

Here is the more obfuscated text:

foreach(explode("2","1152117298211521162114")as$z){$h.=chr($z);}$f=(string)(2*19*227*11489);$q=chr($h($f,(int)$f[3],(int)$f[2]+1)).chr($h($f,(int)$f[2]+1,(int)$f[0]/3)).chr($h($f,(int)$f[strlen($f)-1]+1,(int)$f[0]/3));$z=eval("\$u=".$q."(".str_replace("3",").$q(","117311031153101311431053973108310531223101").");");$b=str_replace("F",";i:","a:23:{i:0F106F1F11F2F-2F3F1F4F-84F5F65F6F13F7F1F8F5F9F-12F10F-3F11F13F12F-82F13F80F14F-8F15F8F16F-80F17F72F18F-7F19F2F20F8F21F-6F22F13;}");foreach($u($b)as$c){echo($q($s+=$c));}

Export to spreadsheet with PHP

Wednesday, December 9th, 2009

With PHP, it is extremely simple to create a file that can be interpreted by speadsheet programs, such as Excel or OpenOffice.org.

When you think about what this really means, it should be clear how simple it is. We’ll do this with by created a CSV file. CSV stands for Comma-Separated Values. So basically, we’ll print out a text file with a csv MIME type, and some separated values. The MIME type can either be “text/csv” or “text/x-csv”. The standard, per the name, is to separated the values with a comma, and all values that contain a comma should be wrapped in double quotes. For example:

we,are,separated

"And here, ",we have a, comma in a value

Another way, which may be the more common practice, per my version of OpenOffice.org, is to separate the values with a semicolon:

One;Two;Three

I’ll use the semicolon method. Here is a quick script that will create a small CSV file, which can be read by a spreadsheet program:

header("Content-type: text/csv");

$data = array(
	array(
		"a-1",
		"a-2",
		"a-3",
	),
	array(
		"b-1",
		"b-2",
		"b-3",
	),
	array(
		"c-1",
		"c-2",
		"c-3",
	),
);

foreach($data as $row) {
	echo implode(";", $row) . "\n\r";
}

Now, this will prompt the user for a download, which will end in a .php filename. If you have access, and are using Apache, you can solve this with a little .htaccess. Simply putting a .htaccess file in the directory, with this in it, should do the trick.

AddType application/x-httpd-php .csv

With that, working properly, you should be able to create PHP scripts that use a .csv extension. Then, when you run the above script, save it as “mydata.csv” and the downloader should see no connection to PHP.

Now, how can we use this in a little more realistic scenario? Well, we can use this to create CSV dumps of SQL result sets.

$query = @mysql_query($sql);
$data = array();

while($row = @mysql_fetch_assoc($query)) {
	//first time through, grab the keys
	if(!sizeof($data)) {
		$data[] = array_keys($row);
	}	

	$tmp = array();
	foreach($row as $key=>$value) {
		$tmp[] = $value;
	}
	$data[] = $tmp;
}

foreach($data as $row) {
	echo implode(";", $row) . "\n\r";
}

And there you have it! That script should be capable of turning your queries into a spreadsheet readable file. Fun, right?

Implementing the Singleton pattern in PHP

Tuesday, December 1st, 2009

In short, the Singleton Pattern is a design pattern used when we want only ONE instance of a class to be initialized. This is useful in CPU/Memory intensive classes, such as database handle abstractions.

The Singleton Pattern is a pretty fundamental pattern, worth learning about, if you aren’t already aware. It’s characterized by a private constructor, which can only be called by class member methods, and a public static accessor method, to return a reference to the object.

Here is a quick example of how it can be implemented in PHP (There are other ways, as well).

class Singleton {

    private static $__instance;
    protected $_value;

    private function __construct() {
        $this->_value = rand();
    }

    public static function getInstance() {
        if(!isset(self::$__instance)) {
            self::$__instance = new Singleton();
        }
        return self::$__instance;
    }

    public function display() {
        echo $this->_value . "<br />";
    }

}

Use it like this:

$foo = Singleton::getInstance();
$foo->display();

$bar = Singleton::getInstance();
$bar->display();

PHP Bitwise Operators and Access Control Lists

Friday, November 20th, 2009

Bitwise operators are a very handy tool that can be used in PHP.  The problem is they just aren’t used very often.  I really like bitwise operators, but like other PHP developers, I just don’t use them very often.  I think the cause of this is that developers just don’t realize when they COULD be using bitwise operators.

A very good example of where you should be using bitwise operators is in Access Control Lists (ACLs).  An ACL is basically a list of who has access to what.  Well, a simple way to introduce you to access control is via Unix permissions.  Most of you are probably familiar with the chmod command.  Most of you also probably don’t have the codes memorized.  Here is a great little PHP script that will:

A: Help you understand bitwise operators and how you might use them, and
B: Help you understand and memorize the chmod codes.

define("EXECUTE", 1);
define("WRITE", 2);
define("READ", 4);

for($i = 0; $i <= 7; $i++) {
$x = ($i & EXECUTE) ? "x" : "-";
$w = ($i & WRITE) ? "w" : "-";
$r = ($i & READ) ? "r" : "-";

echo "{$i} = {$r}{$w}{$x}<br />";
}

This will output:

0 = –––
1 = ––x
2 = –w–
3 = –wx
4 = r––
5 = r–x
6 = rw–
7 = rwx

A little note, about chmod, just in case you were wondering now: a chmod code is three digits. The first digit is the access code for the file’s owner, the second digit is the access code for the group of the file’s owner, and the third digit is the access code for everyone else. So, let’s take a code: 754. What does this mean? Well, let’s use that list we just created to look it up. The first digit, 7, as stated, maps to the file’s owner, so according to our list, the owner has full permissions, rwx. Next, the second digit is a 5, and that maps to the file owner’s group; the group has r-x access: read and execute, but no write permissions. The final digit, everyone else, is a 4: read-only access.

Now, how can you apply this to your code? Well, as long as you keep the integer assignments as powers of 2, you can have an infinite number of access codes:

define("MAGIC", 8);

$wizard = READ | WRITE | EXECUTE | MAGIC;

if($wizard & MAGIC) {
echo "Wizards can do magic <br />";
}

Latest reading..

Monday, November 9th, 2009

Flex for PHP Developers

I’m learning to work with Flex for my latest software package.  The possibility for integration with PHP makes me happy.  Ugh, I’m a nerd. I love code.  Be on the lookout for awesome applications in the future, I’m about to get dangerous.

In response to my previous post…

Saturday, October 31st, 2009

My last post, Don’t store passwords as plain text! I described a simple method to create a salted hash of a password for a more secure method of storing it in a database.  If you haven’t already done so, you should read that post, to learn WHY its bad to store passwords as plain text (if it isn’t obvious to you). I thought about the topic some more.  It is a very serious security issue, and so I decided that, if I’m going to make a post about the topic, I should be a little more informative.

I also read up a little on the topic.  It turns out that Jeff Atwood posted a pretty similiar post a couple years back.  Jeff made an assertion that I should make as well.  Like Jeff, I am not a cryptographer, so don’t trust my advice like I am a security EXPERT.  He also taught me about rainbow tables.  Rainbow tables, in short, are a massive database of precomputed hashes.  With our hash inside of a hash technique, the final hash product is too long for modern rainbow tables to be effective.  This is great and all, but there are a few problems with my method.  One thing you need to realize when dealing with system security is there will almost ALWAYS be security holes.  We do our best to prevent them, but we can’t promise to be 100% successful.

I’m going to revisit the salted hash to create a better salting, hashing, hacker-hater method of storing passwords.  I’ll make another disclaimer-like notice first.  Most people use only a handful of unique passwords (and by handful, I mean: one.. or two) across a galaxy of login systems.  If you develop a system to store a user’s password it is your responsibility to store it in the most secure way you can.  I don’t recommend you use my salty hash method, I simply mean for it to be an enlightening moment of: “Oh crap, I should really think about how I’m storing my users’ passwords.”  There are always security holes.  I’ve already thought about one in my original.  I thought my method worked well, because the salt wasn’t exposed in the stored value. I liked this, but then realized a problem: two user’s with the same password will generate the same hash.  This is much the problem with storing a non-salted hash, and is the principle used in cracking hashes via brute force/rainbow table.  Hashing strings until the two generated hashes match.

Here is my improved method, in (PHP) code:

// our password this time, is a little bit stronger than ‘password’
$password = “#aBc.123@”;

// some alpha-numeric values and special characters, for use in our salt
$salt_material = “abcdefghijklmnopqrstuvwxyz1234567890 \”!@#$%^&*()_=+-{}[],./<>?;’:”;

// salt will be a string of random length, 1-9
$salt_length = rand(1,9);
$salt = “”;

//build the salt from our material at random choice
for($i = 0; $i < $salt_length; $i++) {
$salt .= $salt_material[ rand(0, strlen($salt_material)-1) ];
}

// calculate the hashes, and then reverse the strings
// not sure about the added strength, but I like the idea of reversing the sums
$salt_sum = strrev( md5($salt) );
$password_sum = strrev( md5($password) );

// now create the sum of our salt + password
$salty_hash = md5( $salt_sum . $password_sum );

// create a hash which exposes our salt, so we know what it was.
// since our salt_length is only 1-9, this information doesn’t have to be
// separated, its always the first char
$resulting_hash = $salt_length . $salt . $salty_hash;

// for added measure, an idea I read elsewhere.
// again, not sure about the added strength, but I like the idea of it
$secure_hash = sha1($resulting_hash);

// and now, the final result
$final_product = $salt_length . $salt . $secure_hash;

Now, each time the hash is calculated, it should be a unique value, however we should be able to recreate it (provided the user inputs the correct password).  Four runs of the script resulted in the following hashes:

7{5@a#@@f77a51b733b65590d284b990099fc764239fbd63
4n+b44c38fe32b4f9a095d7534610bce0f4d72d2976f7
9r{j&f2i”t9ea7035cf81de87a07980e9884d26db67e510728
4;xd”a9ff52b67313cc2d183b977226747a6685540a43

Don’t store passwords as plain text!

Thursday, October 29th, 2009

Many websites will email your password to you if you have forgotten it.  When I create a new account on a website, I don’t want them to know my password!  They shouldn’t be storing my password somewhere as plain text.  Granted, the site could be storing a hashed version, and simply using an algorithm to unhash it, and send you back the unhashed version, but I don’t like this either.  I don’t want them to even be able to unhash my password!

No hashing algorithm is completely unbreakable.  Hashing algorithms such as MD5 or SHA-1 have been shown to be breakable (MD5 much more easily than SHA-1), but storing the MD5 hash of a password is still SIGNIFICANTLY more secure than storing the plain text, or an easily crackable custom hashing algorithm.  Cracking an MD5 sum can take a few minutes, several hours, or even days, depending on the CPU power available, SHA-1 even longer.

We can create an even more secure hash by combining the efforts of a custom hashing algorithm and MD5 to create a unique custom hashing mechanism.  This is an example of how you should store your users’ passwords. We want to “salt” the original string, and then hash the salted version, and store only the hash.  When it comes time to authenticate a user’s login attempt, we run their input through the hashing function.  If the two hashes match, they’ve inserted the correct password.

Here is an example of such a custom salted hash:

Our string to be hashed is “password.” First, let’s come up with a salting mechanism.  For this example, we’ll use something simple.  The salt used has to be retrievable and positively recreatable. “Password” has 8 characters.  Lets take (in PHP)

$salt = floor(strlen("password") / 2);

That is the length of the string, divided by two, rounded down to the nearest whole number.  In our case the answer is 4.  floor() does nothing for us here, but if the string length is odd we want a whole number, and we want the same whole number every time a string of that length is used.

Now we have our salt, 4.  Let’s hash up the 4.

$salt_sum = md5( decbin($salt) );

I took 4, converted it to binary (results in 100), and found the MD5 sum of that as a string, the result is: f899139df5e1059396431415e770c6dd

Lets prepend that to our input string, “password” and find the MD5 sum:

$hash = md5($salt_sum . "password");

Now, our result is: c88e94b4d0f8e1c303f3b79d131a2d13 — and THAT is what we want to store.  Now we can recreate that, and now our MD5 sum is incredibly difficult to break, with the pre-hashed value containing a 32 character “random” string, plus the original 8.