Archive for the ‘Scripts’ 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, "&");
}

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 />";
}

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