Web Development and stuff…

Month of PHP Security 2010

without comments

After a successful experiment a while back Month of the PHP Bugs. Stefan Esser and SektionEins is at it again. This time with Month of PHP Security. A gathering for PHP and security gurus a like. The call for papers is open for submission.

There are some nice prices to walk away with. So what you waiting for?

  • New vulnerability in PHP [1] (not simple safe_mode, open_basedir bypass vulnerabilities)
  • New vulnerability in PHP related software [1] (popular 3rd party PHP extensions/patches)
  • Explain a single topic of PHP application security in detail (such as guidelines on how to store passwords)
  • Explain a complicated vulnerability in/attack against a PHP widespread application [1]
  • Explain a complicated topic of attacking PHP (e.g. explain how to exploit heap overflows in PHP’s heap implementation)
  • Explain how to attack encrypted PHP applications
  • Release of a new open source PHP security tool
  • Other topics related to PHP or PHP application security
del.icio.us Digg DZone reddit SlashDot StumbleUpon Technorati

Written by Thijs Lensselink March 9th, 2010 at 12:42 pm

Posted in Code, PHP, Security Tagged with , , ,

Zend Framework Bootstrapping Modules

with 9 comments

I am working on a small API for bluesignal and i wanted a modular architecture. I have done this before using the Zend Framework. But this time i wanted a bit more control while loading the modules. And adding a Bootstrap class would seem like a good option. The only example i could find involved loading all bootstraps on every request. Which doesn’t seem like a good idea. So after reading through the Manual and some blog posts. I decided to give it s shot my self.

The structure i want looks like this.

The application.ini file has the following contents:

includePaths.library = APPLICATION_PATH “/../library”
bootstrap.path = APPLICATION_PATH “/Bootstrap.php”
bootstrap.class = “Bootstrap”
resources.frontController.moduleDirectory = APPLICATION_PATH “/modules”
resources.modules[] = “default”
resources.modules[] = “admin”

includePaths
This sets the applications local library location. Any shared code for this application goes here.

bootstrap.path & class
Define the location and type of the Bootstrap class.

resources
Define the modules location and create a list of modules.

The main Bootstrap class

application/Bootstrap.php

class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{

Load the config parameters for this application and set some debugging settings if needed.

    protected function _initConfiguration()
    {
    	$app = $this->getApplication();
    	$config = $app->getOptions();

    	if (APPLICATION_ENV == 'development') {
	    	    error_reporting(E_ALL & E_STRICT);
	    	    if (isset($config['phpsettings'])) {
		    	        foreach ($config['phpsettings'] as $setting => $value) {
		    		        ini_set($setting, $value);
		    	        }
	    	    }
    	}
    }

We need autoloading here because we are using a class from the application library. Right now this causes a problem. A notice is thrown

Warning: include_once(FrontController.php) [function.include-once]: failed to open stream: No such file or directory in Zend/Loader.php on line 147

The application responds fine. And this problem seems to be a recurring issue (ZF-7224, ZF-7550) for the framework. Until now i have not find a graceful fix for this. besides a small patch reversion.

    protected function _initAutoload()
    {
		    $autoloader = Zend_Loader_Autoloader::getInstance();
		    $autoloader->setFallbackAutoloader(true);

		    return $autoloader;
    }

Setup the controller to register the Bluess_Modules_Loader plug-in. And set the prefixDefaultModule parameter so we can prefix the default module controllers as well. Just for the sake of consistency. The Bluess_ namespace is part of my API. And can be changed at will.

   protected function _initController()
    {
    	$this->bootstrap('FrontController');
    	$controller = $this->getResource('FrontController');
       $modules = $controller->getControllerDirectory();
       $controller->setParam('prefixDefaultModule', true);

        $controller->registerPlugin(
               new Bluess_Modules_Loader($modules)
        );

        return $controller;
    }

Now the last method. which is a bit weird. And i am probably missing a key factor here. But if this method resource is not declared only the default module functions. When declared empty all modules function as they should. This would indicate that this method could be used to load the modules. But i haven’t found a way to achieve this yet. Except for loading all modules in a row. Which makes no sense for this purpose. So we leave it empty.

protected function _initModules()
    {
		// Call to prevent ZF from loading all modules
    }

The most important part here is the controller plug-in. This will be the place where module bootstraps are called from.

application/../library/Bluess/Modules/Loader.php

class Bluess_Modules_Loader extends Zend_Controller_Plugin_Abstract
{
	protected $_modules;

Setup the plug-in by passing the applications module list.

	public function __construct(array $modulesList)
	{
		$this->_modules = $modulesList;
	}

The dispatchLoopStartup method will be called on every request and will do the magic. Based on the current module name we create a new Zend_Application with the current modules config file module.ini. And we bootstrap it.

	public function dispatchLoopStartup(Zend_Controller_Request_Abstract $request)
	{
		$module = $request->getModuleName();

		if (!isset($this->_modules[$module])) {
			throw new Exception("Module does not exist!");
		}

		$bootstrapPath = $this->_modules[$module];

		$bootstrapFile = dirname($bootstrapPath) . '/Bootstrap.php';
        $class         = ucfirst($module) . '_Bootstrap';
        $application   = new Zend_Application(
        	APPLICATION_ENV,
    		APPLICATION_PATH . '/modules/' . $module . '/configs/module.ini'
		);  

        if (Zend_Loader::loadFile('Bootstrap.php', dirname($bootstrapPath))
        	&& class_exists($class)) {
            $bootstrap = new $class($application);
            $bootstrap->bootstrap();
        }
	}
}

Now setup the default module. Once this is done it’s a nice example for further modules. Make sure the module has it’s own layout set.

application/modules/default/configs/module.ini

default.resources.layout.layout = “default”
default.resources.layout.layoutPath = APPLICATION_PATH “/modules/default/layout”

Setup the modules bootstrap and use it to set the modules model location.

application/modules/default/Bootstrap.php

class Default_Bootstrap extends Zend_Application_Module_Bootstrap
{
	protected $_moduleName = 'default';

	protected function _initConfiguration()
    {
		$options = $this->getApplication()->getOptions();

    	set_include_path(implode(PATH_SEPARATOR, array(
		    realpath(APPLICATION_PATH . '/modules/' . $this->_moduleName . '/models'),
		    get_include_path(),
		)));

		return $options;
    }
}

That’s all. Now make sure your layout is set correctly and the controllers are prefixed

application/modules/default/layout/default.phtml

echo $this->layout()->content;

application/modules/default/controllers/IndexController.php

class Default_IndexController extends Zend_Controller_Action
{

It took me a while to get this working like i had it in my mind. But it’s going the right way. If your interested in a working copy. You can download one here.

del.icio.us Digg DZone reddit SlashDot StumbleUpon Technorati

Written by Thijs Lensselink February 6th, 2010 at 9:04 pm

Posted in Code, PHP Tagged with , , , , ,

Finally no more IE6

without comments

Something all Web developers wish for is the fact that Internet Explorer 6.0 disappears from the face of this planet. And after some good initiatives like IE6 no more It now seems the biggest in the field is phasing out support for older browsers. Sometimes its good to have so much influence i guess? :)

Good move!

http://googleenterprise.blogspot.com/2010/01/modern-browsers-for-modern-applications.html

del.icio.us Digg DZone reddit SlashDot StumbleUpon Technorati

Written by Thijs Lensselink February 1st, 2010 at 8:36 pm

Posted in Code, Tech Tagged with , ,

Fixing wp-e-commerce for iDEAL payments

without comments

Last Friday a friend approached me with a problem he was having. He was trying to setup a small webshop in a existing Wordpress site. For the webshop he was using a plug-in called wp-e-commerce. He chose this plug-in because it is one of few that supports iDEAL payments. Because this shop only serves Holland the only payment option they need is iDEAL.

The iDEAL plug-in seemed to function properly. But the bank portal didn’t respond as expected. The first error i spotted was the mis configured referrer. The error code for this was.

unknown order/0/r

This didn’t solve the problem though. The message change from the previous to

unknown order/1/s

So i spend the next hours reading the manual he got from his bank. And came to the conclusion they do it just a bit different then for what this plug-in was written. The bank expects a hash to be send along each order made. This hash is build up from parts of the order and a secret string. This combined is hashed with the SHA-1 algorithm And added to the form as a hidden field. I wrote a small function to create hash and changed a few other small things in the order form.

The original form looks like this:

<script type="text/javascript">
var Amount = ;
var PSPID = "";
var AM;
if (isNaN(Amount)) {
	alert("Amount not a number: " + Amount + " !");
	AM = "";
} else {
	AM = Math.round(parseFloat(Amount)*100);
}
</script>
<form method='post' action='' id='ideal_form' name='ideal_form'>
<script type="text/javascript">
document.write("
");
document.write("
");
</script>
<INPUT TYPE="hidden" NAME="SHASign" VALUE="4FF8C2FB03B0AA45EA5DE9503AEACB6B603DCFCC">
<input type="hidden" NAME="orderID" value="" />
<input type="hidden" name="currency" value="" />
<input type="hidden" name="language" value="" />
<input type="hidden" name="accepturl" value="">
<input type="hidden" name="cancelurl" value="">
<!--customer information starts-->
<input type="hidden" name="CN" value="">
<input type="hidden" name="EMAIL" value="">
<input type="hidden" name="ownerZIP" value="">
<input type="hidden" name="owneraddress" value="">
<input type="hidden" name="ownercty" value="">
<input type="hidden" name="ownertown" value="">
<input type="hidden" name="ownertelno" value="">
<!--customer information ends-->
<input type="hidden" name="PM" value="iDEAL" />

I didn’t really understand why some values were written by JavaScript. So i removed the JavaScript lines and added the fields to the form. And after adding the hash function statement it looks like this.

<form method='post' action='' id='ideal_form' name='ideal_form'>

<input type="hidden" NAME="PSPID" value="" />
<input type="hidden" NAME="orderID" value="" />
<input type="hidden" NAME="amount" value="" />
<input type="hidden" name="currency" value="" />
<input type="hidden" name="language" value="" />
<input type="hidden" name="accepturl" value="">
<input type="hidden" name="cancelurl" value="">
<!--customer information starts-->
<input type="hidden" name="CN" value="">
<input type="hidden" name="EMAIL" value="">
<input type="hidden" name="ownerZIP" value="">
<input type="hidden" name="owneraddress" value="">
<input type="hidden" name="ownercty" value="">
<input type="hidden" name="ownertown" value="">
<input type="hidden" name="ownertelno" value="">
<!--customer information ends-->
<input type="hidden" name="PM" value="iDEAL" />
echo createSHA1Hash(array(
		$purchase_log[0]['id'],
		($amount*100),
		get_option('ideal_currency'),
		get_option('ideal_id'),
		'[SHA1-IN-HASH]'
	));
</form>

The function i can be placed anywhere in the page. Or a include file. Here’s the code. The only thing that has to be done is replace [SHA1-IN-HASH] with the Hash configured in the bank’s ideal admin.

function createSHA1Hash($hashOptions) {
        $str = implode('', $hashOptions);

        return '
';
    }

While doing some searches i noticed there are more people having issues with this plug-in. So maybe this will save somebody a bit of time.

del.icio.us Digg DZone reddit SlashDot StumbleUpon Technorati

Written by Thijs Lensselink January 30th, 2010 at 4:03 pm

Posted in Code, PHP, Tech Tagged with , ,

Cache data with Zend Framework and Memcached

with one comment

Last week i had the chance to work with memcache. Something i hadn’t done before. For caching i mostly rely on APC for bytecode. And file based caching for content. Using memecache extension for PHP and de memcached service gives a whole range of features for caching data. And an easy way to manage all this cached data.

The project i am working on is based on Zend Framework. And there for this post will reflect working with memcache in ZF only. With ZF and memcache it’s possible to do frontend and backend caching. I will focuse on the backend side for now. But will setup the frontend as well.

If you don’t have memcache installed do it now. It’s not that hard. On my debian box it went somethign like this:

$ aptitude install memcached
$ aptitude install php5-memcache

Now a days evrything seems to go automatic. So no need to edit the php.ini or anyhting. To check if PHP loaded the memcache extension you can do:

$ php -m | grep memcache
memcache

Memached is automatically started after install. So let’s check if everything went ok.

$ ps -aux | grep memcached
nobody 20965 0.0 0.5 42900 23072 ? S Jan28 0:01 /usr/bin/memcached -m 64 -p 11211 -u nobody -l 127.0.0.1
root 22393 0.0 0.0 87940 776 pts/0 R+ 12:06 0:00 grep memcached

$ netstat -an | grep 11211
tcp 0 0 127.0.0.1:11211 0.0.0.0:* LISTEN

Looking good. Now it’s time to do some configuration in ZF.

First of the frontend settings. With ‘type’ we set the cache method for the frontend. We chose the standard Core class for this. With ‘lifetime’ we set the time for which a cached entity is valid. The ‘cache_id_prefix’ is a nice way to group for instnace cache data by controller. So just give it a name.

cache.frontend.type = Core
cache.frontend.options.lifetime = 600
cache.frontend.options.automatic_serialization = true
cache.frontend.options.cache_id_prefix = [some string]
cache.frontend.options.cache = true

Now it’s the backends turn to get configured. For ‘type’ we choose Memcached. More types are available. For more info read the ZF manual. The rest of the settings are basic memcached settings like host, port and persitance.

cache.backend.type = Memcached
cache.backend.options.servers.1.host = 127.0.0.1
cache.backend.options.servers.1.port = 11211
cache.backend.options.servers.1.persistent = true
cache.backend.options.servers.1.weight = 1
cache.backend.options.servers.1.timeout = 5
cache.backend.options.servers.1.retry_interval = 15

Finally we can do some PHP code. To get the cache instance setup we add a _initCache() method to the bootstrap class. Inside this method we retrieve the config options by calling getOptions(). And setup the cache object. Which is then stored in the Registry for later use.

protected function _initCache()
{
        $options = $this->getOptions();

        if (isset($options['cache'])) {
            $cache = Zend_Cache::factory(
                $options['cache']['frontend']['type'],
                $options['cache']['backend']['type'],
                $options['cache']['frontend']['options'],
                $options['cache']['backend']['options']
            );

            Zend_Registry::set('cache', $cache);
            return $cache;
        }
}

That’s all set. I used the caching for some REST service responses. So i will stick to that in this post as well. The class has a method for adding a cache object.

public function setCache(Zend_Cache_Core $cache) {
    $this->cache = $cache;
}

So fetching the cache instance and passing it to the REST client will look something like this:

$cache = Zend_Registry::get('cache');
$cache->setLifetime(86400);

$client = new Client();
$client->setCache($cache);

The first thing we do inside the calling method is set a unique key for the cache entry.

$cache_id = 'getPage_' . $this->getDomain()
            . $this->getPageName()
            . $this->getCountry();

Then we check if the cache object is set. If that’s the case we check to see if the unique key is already available in the cache.

if (!isset($this->cache) || !($ret = $this->cache->load($cache_id))) {

If a value is returned from the cahce we will return it. If not then we will do the webservice call and store the return data in cache.

 $ret = $this->restClient->call('getPage', array());

if (isset($this->cache)) {
    $this->cache->save($ret, $cache_id);
}

The complete method looks something like this.

protected function getPageFromWebservice()
{
        $cache_id = 'getPage_' . $this->getDomain()
            . $this->getPageName()
            . $this->getCountry();

        if (!isset($this->cache) || !($ret = $this->cache->load($cache_id))) {
            $ret = $this->restClient->call('getPage', array());

            if (isset($this->cache)) {
                $this->cache->save($ret, $cache_id);
            }
        }
        return $ret;
}

That’s all. It’s pretty basic stuff. But so cool!

del.icio.us Digg DZone reddit SlashDot StumbleUpon Technorati

Written by Thijs Lensselink January 29th, 2010 at 12:26 pm

Posted in Code, PHP, Tech Tagged with , , ,

Drag & drop Uploads with XMLHttpRequest2 and PHP

with one comment

I finally had some time to read through my ever growing list must read items and play with some new software. While reading up on the new Firefox 3.6 i noticed it came with the new XMLHttpRequest [2] object based on the new file API. And according to the new specs. This would allow for easy file uploads. Now there’s been some examples [2] on the web already. But i just wanted to get my hands dirty.

The new XMLHttpRequest object makes is possible to send files in a few different formats. The most important being the binary format. The code for sending a request with XMLHttpRequest2 looks the same as the previous version. Except for sendAsBinary() in this case.

var xhr = new XMLHttpRequest();

fileUpload = xhr.upload,
fileUpload.onload = function() {
    console.log("Sent!");
}

xhr.open("POST", "upload.php", true);
xhr.sendAsBinary(file.getAsBinary());

So let’s set things up for drag & drop. We need a div that will be the main drop point. And we need some event listeners to catch the drag * drop events. Let start by creating the drop zone. For this we use two simple divs. The outer div will listen for the drag & drop events. And the inner will catch the files.

Now let’s create our upload code.

var upload = {
    setup : function() {},
    uploadFiles : function() {event}
}
window.addEventListener("load", upload.setup, false);

The setup method will set all event listeners for drag & drop. And register the upload handler.

var container = document.getElementById('container');
var drop = document.getElementById('drop');

container.addEventListener("dragenter", function(event) {
        drop.innerHTML = '';
        event.stopPropagation();
        event.preventDefault();
    },
    false
);

container.addEventListener("dragover", function(event) {
        event.stopPropagation();
	event.preventDefault();
    },
    false
);

container.addEventListener("drop", upload.uploadFiles, false);

As you could see above. the uploadFiles() method gets a event returned from the drag & drop action. This is where the new file APi comes in play. To get to the file property we access the dataTransfer object.

var files = event.dataTransfer.files;

The actual uploading is easy as cake.

for (var x = 0; x < files.length; x++) {

    var file = files.item(x);
    var xhr = new XMLHttpRequest();

     fileUpload = xhr.upload,
     fileUpload.onload = function() {
         console.log("Sent!");
    }

    xhr.open("POST", "upload.php", true);

    xhr.setRequestHeader("Cache-Control", "no-cache");
    xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
    xhr.setRequestHeader("X-File-Name", file.fileName);
    xhr.setRequestHeader("X-File-Size", file.fileSize);
    xhr.setRequestHeader("Content-Type", "multipart/form-data");

    xhr.sendAsBinary(file.getAsBinary());
}

That's it for the client side. There is however a small problem on the receiving side. When handling uploaded files in PHP we expect the $_FILES array to be populated. This is not the case when streaming files from the client to the server. To get the needed file information we set some headers on the client side X-File-Name and X-File-Size. And since the $_FILES are is empty. We need an other way to get the file contents. So we will use php://input streams for that.

The contents of upload.php look like this:

require_once('Streamer.php');

$ft = new File_Streamer();
$ft->setDestination('data/');
$ft->receive();

With setDestination() the destination path for the uploaded files is set. And recieve() listens for any incoming files. Most of the magic is done in the recieve() method. So here's the code.

public function receive()
{
    if (!$this->isValid()) {
        throw new Exception('No file uploaded!');
    }

    file_put_contents(
        $this->_destination . $this->_fileName,
        file_get_contents("php://input")
    );

    return true;
}

I am impressed! This promises a lot of good. And offers some interesting options. Let's hope all browsers implement this gem. I still have one issue though. I can't get this to work in firefox under linux. The drag & drop events do not seem to function properly with files being dragged from the desktop. anybody know why?

If you interested in the complete code. you can find it here

del.icio.us Digg DZone reddit SlashDot StumbleUpon Technorati

Written by Thijs Lensselink January 25th, 2010 at 12:02 am

end year notice

without comments

Have been working hard this week on kremermakelaars.nl. And managed to finish it right before the end of this year. The old website was one of those left overs from the early 90’s. The only thing missing was a spinning @ sign. But i think i managed to give it a nice visual boost. For the back-end i created s nice CMS to manage all objects and page content. The whole thing is build with ZF, Mysql, and some javascript libraries.

The customer is happy. I’m happy. Now it’s time for some fun!

So that’s all for 2009. I wish everybody a good and happy new year.

del.icio.us Digg DZone reddit SlashDot StumbleUpon Technorati

Written by Thijs Lensselink December 31st, 2009 at 10:38 am

Posted in /home, Freelance

A new hobby

with one comment

A few months ago i got stranded on adda’s website. This stuff looks so interesting. But thinking about building my own gives me sweaty hands. I love to build computers from scratch. But building a motherboard… i don’t see me doing that anytime soon. Even though i have null knowledge of the subject. I decided to give it shot anyway. And ordered the Russian Tube Clock. It arrived pretty fast. But occupied some closet space for at least 3 weeks. I however managed to push my self into building this thing. So here goes.

When you unpack the whole thing and lay it out on a table it looks pretty impressive. And at this point i got the feeling i would never get this to work. But thank god for the internet. I quickly found some nice hand held guides to guide me through it.

IMG_0550

I will not bother you with all specifics. because i can’t :) And for that you should read here and here Or just order the kit and give it a shot. it’s great. So after burning my self i managed to get the first set of components mounted properly on top of the PCB.

IMG_0555

The only problem i encountered (and it spoiled most of the project) was the soldering iron. Which was a mess to start of with. And it was way to big for this delicate work. The result was my soldering didn’t look that proper as you can see in the image below.

IMG_0557

The hardest part was to get the tube mounted correctly. One end of the tube is a spring of wires that need to be attached to a jack on the smaller PCB. It’s a time consuming and tedious job to do. But i think i managed. Although not all wires are as straight as they should have been.

img_0611

It finally starts to look like something. After hooking it up to some power and running some tests. I was ready to build the outer casing.

img_0609

The outer casing is a simple design. Done in Plexiglas. It looks simple. But it was a struggle to get the thing assembled.

IMG_0563

After my struggle with the casing i switched the tube on. And was greeted by a nice blue/greenish color and a beep. The color is a bit different from what is shown on the main site. But that has something to do with the tubes i read. The brightness is adjustable so that’s no problem. As you can see i still miss one time delimiter. And the menu is still not function 100%. But the clock works. And i can set the alarm.

img_0608

I had so much fun building this thing. that i ordered a new soldering iron. And will be doing a new attempt soon!

del.icio.us Digg DZone reddit SlashDot StumbleUpon Technorati

Written by Thijs Lensselink December 20th, 2009 at 9:46 pm

Posted in /home, Tech Tagged with ,

A new adventure part II

without comments

This post is a recap of a post i made earlier this month. Normally i would leave it as it is. But i wasn’t really happy with the outcome. And it didn’t really reflect the current situation. So here goes.

As the technological challenge in my current day to day job started to decline. I started to think this was not the right position for me. So i decided it was time to search for something new. And at that time i could not find anything interesting that didn’t include relocating my self to an other part of this world. This left me with a hard choice to make. But i left AddMissions anyway. With a good feeling though. I had have a great year there. Now was just time for a change.

All that was about two months ago. And for the past time i have been doing some freelance projects to pay my bills. And although i enjoyed the time working from home. I feel it is time again to go and search for a new opportunity. I learned a lot from the past two months but freelance work is not something i tend to do full time. I need people around me. Even though i don’t talk that much while i work :)

I have some things cooking at the moment. Let’s see what the new year has to offer.

del.icio.us Digg DZone reddit SlashDot StumbleUpon Technorati

Written by Thijs Lensselink December 20th, 2009 at 9:10 pm

Posted in /home, Freelance

0x.vc URL shortener service

without comments

Having a hard time getting to sleep tonight. And was browsing my domain list. when i realized i still have this very short domain name that is just sitting there collecting dust. And since these URl shortener services are so hot lately i decided to roll my own.

So three hours, a bit of code and a short domain name later i present : 0x.vc (it’s shorter) It’s probably still full of holes and prone to XSS attacks. So be careful!

del.icio.us Digg DZone reddit SlashDot StumbleUpon Technorati

Written by Thijs Lensselink December 17th, 2009 at 3:14 am

Posted in Code, Freelance, Javascript, PHP, Tech Tagged with