knightly

Monthly Archives: March 2009

Disable skype icons on a website

My boss today showed me one of our websites. And the layout was not displayed how it should be. On my development station however there was no problem with viewing the same page. And my boss pointed me to the Skype icon on the contact page. Because he had Skype installed. And with the Skype toolbar for browsers enabled a small icon is inserted in pages that have data that looks like a phone number.

egypte_phone

And although we all like Skype here. This is not what customers should see when they have Skype installed. My boss proposed to create an image instead of a text based phone number. This should work. But i did some Googling first. And found a post on the Skype website. There seems to be a meta tag that disabled the Skype icons from being displayed on a website. So that was an easy fix.

<meta name=”SKYPE_TOOLBAR” content =”SKYPE_TOOLBAR_PARSER_COMPATIBLE”>

I think it’s great that the Skype people provide a way to disable the icons. But i would like to have a bit more control over this.

WordPress and NO-WWW rewrite

On almost all of my domains i rewrite the WWW sub domain to the no-WWW version. This however went wrong on my own site. And i didn’t even notice it. My friend Alex pointed out that he couldn’t post any comment to the site anymore. So what went wrong?

Normally i use the following lines to do the rewrite.

RewriteCond %{HTTP_HOST} ^www\.lenss\.nl$ [NC]
RewriteRule ^(.*)$ http://lenss.nl/$1 [R=301,L]

My own site however still runs WordPress and this package comes with it’s own set of rewrite rules. And i just dropped my new lines under the WordPress rewrite rules.

RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^.*[^/]$
RewriteCond %{REQUEST_URI} !^.*//.*$
RewriteRule . index.php [L]

The result was that the WWW sub domain got rewritten to the no-www version. But everything after the trailing slash got dismissed. So rewrites for blog posts didn’t work. And all request would land on the main index. So i did some testing and combined the two sets of rewrite rules. This seems to function properly :)

RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^www\.lenss\.nl$ [NC]
RewriteRule ^(.*)$ http://lenss.nl/$1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^.*[^/]$
RewriteCond %{REQUEST_URI} !^.*//.*$
RewriteRule . index.php [L]

Next time i just need to check my changes more thoroughly. And thank you Alex for point that out to me.

XSS vulnerability on Dutch bank websites

My wife just send me a link to security.nl. Pointing to an article about XSS vulnerability in Dutch banking websites. And since i am from the Netherlands. I thought to check this out a bit.

security.nl states that a “security researcher” found XSS bugs in most of Dutch websites. With a link that seems to point to the “researchers” blog. I don’t know about you. But i personally don’t trust websites that i never seen before. Let alone “researchers” that have absolutely no credibility in the scene. However the XSS bugs are real. But is this really something to write about? Showing an alert box on a screen shot seems very lame to me. I wonder if this is even exploitable at all?

One good point is that at least one bank responded in time and fixed the bug.

Checking website status with PHP and Curl

I have to admit this is probably not the best way to things like this. But it was fun to write the small bit of code. And it’s useful as well. For one of my sites i use a small script to check the status every 30 minutes. I’m doing this because the server the site is running on sometimes chooses to stop serving web pages. It’s a managed server so not much i can do about it.

So to check the status of the website / web server i wrote a small class that is triggered from a CRON job that runs every 30 minutes.

The CRON script looks like this:

require_once "/full/path/to/class/siteStatus.php";

try {
	siteStatus::check(array(
		'sites' => array(
			'http://siteurl1.tld',
			'http://siteurl2.tld'
		),
		'agent' => 'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)',
		'email' => 'some+email.address'
	));
} catch (Exception $e) {
	echo $e->getMessage();
}

And the class that does the actual checking:

/**
 * siteStatus
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license
 *
 * @package    siteStatus
 * @copyright  Copyright (c) 2009 Thijs Lensselink. (http://lenss.nl)
 * @license    http://lenss.nl/license/bsd.txt     New BSD License
 */

/**
 * Class for checking the status of a website
 *
 * @package    siteStatus
 * @copyright  Copyright (c) 2009 Thijs Lensselink. (http://lenss.nl)
 * @license    http://lenss.nl/license/bsd.txt     New BSD License
 */
Class siteStatus
{
	/**
     * @var resource
     */
	static private $_curl;

	/**
     * @var string
     */
	static private $_reportEmail;

	/**
     * @var string
     */
	static private $_curlErrors;

	/**
     * This method loops through the lis tof sites provided by the
     * config array. And calls self::checkSite to do the actual checking.
     *
     * A config array will look something like this:
     *
     * array(
	 *	'sites' => array(
	 *		'http://siteurl1.tld',
	 *		'http://siteurl2.tld'
	 *	),
	 *	'agent' => 'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)',
	 *	'email' => 'report+email.tld'
	 * );
     *
     * @param  array  $config   The config array
     * @return void
     */
	static public function check(array $config)
	{
		self::setReportAddress($config);
		self::createCurlResource();

		foreach ($config['sites'] as $site) {
			$checkDateTime = date('Y-m-d H:i:s');
			if (!self::checkSite($site, $config['agent'])) {
				self::sendReport($site, $checkDateTime);
			}
		}

		curl_close(self::$_curl);
	}

	/**
     * Sets the address to which the report has to be emailed.
     *
     * @param  array  $config   The config array
     * @return void
     */
	static private function setReportAddress(array $config)
	{
		if (!isset($config['email']) || (strlen($config['email']) <= 4)) {
			throw new Exception("No report email address is set in the config.");
		}

		self::$_reportEmail = $config['email'];
	}

	/**
     * Try to create a curl resource.
     *
     * @return void
     */
	static private function createCurlResource()
	{
		self::$_curl = curl_init();
		if (!self::$_curl) {
			throw new Exception("Could not create a curl resource.");
		}
	}

	/**
     * Preform a call to the webserver. And check the status code provided by it.
     *
     * @param  string  $siteUrl   The site URL.
     * @param  string  $agent     Browser agent string.
     * @return boolean
     */
	static private function checkSite($siteUrl, $agent)
	{
	    curl_setopt(self::$_curl, CURLOPT_URL,            $siteUrl);
	    curl_setopt(self::$_curl, CURLOPT_USERAGENT,      $agent);
	    curl_setopt(self::$_curl, CURLOPT_RETURNTRANSFER, 1);
	    curl_setopt(self::$_curl, CURLOPT_VERBOSE,        false);
	    curl_setopt(self::$_curl, CURLOPT_TIMEOUT,        5);

	    if (curl_exec(self::$_curl) === false) {
	    	self::$_curlErrors = curl_error(self::$_curl);
	    }
	    $httpcode = curl_getinfo(self::$_curl, CURLINFO_HTTP_CODE);

	    if($httpcode >= 200 && $httpcode < 300) {
	        return true;
	    }

	    return false;
	}

	/**
     * Send a report after checking sites is done.
     *
     * @param  string $site     Site URL.
     * @param  string $dateTime DateTime the check was preformed.
     * @return void
     */
	static private function sendReport($site, $dateTime)
	{
		$reportSubject = "Status report for {$site}\n\n";

		$reportBody = "Site : {$site}\n";
		$reportBody .= "Date : {$dateTime}\n";

		if (strlen(self::$_curlErrors) > 0) {
			$reportBody .= "Errors : " . self::$_curlErrors . "\n";
		}

		mail(self::$_reportEmail, $reportSubject, $reportBody);
	}
}

Like i said this is probably not the best way of doing this. To make it more solid it’s probably better to use some sort of SMS gateway to send out reports. But for now this suits my needs. It’s runs from my local workstation. Which is on 24/7 anyway.

Animated loader on form submit

In one of our sites we load content of a third party travel organization. And some of these calls can take some time. But when the pages are loading nothing really happens to the browser state. This is confusing for the users of the website. So i decided to add some animated preloader images. Just to show the users the site is still doing stuff.

This however confronted me with a small problem. The preloader images are supposed to show up when a form is submitted. And this is exactly what’s causing the problem. In my first attempt i created the image object when the form was submitted. On submit a JavaScript function was called. This function created the image object and displayed it.

function loader() {
	var loaderImg = new Image();
        loaderImg.src = 'some/image/url/';
}

This however resulted in an image displayed that had no active animation. This happens i think because the image is not fully loaded when the user hits submit on the form. So to fix this i had to load the images before the page was completely rendered.

var loaderImg = new Image();

window.onload = function() {
        loaderImg.src = 'some/image/url';
}

CentOS PHP5 and mcrypt

For some strange reason (i didn’t investigate) CentOS 5 does not come with a pre build mcrypt extension for PHP. This is pretty weird if you ask me. And building this extension from source is no option for me. There are way to much dependencies missing. And i don’t really like installing *dev packages on my server. So how to fix this?

Luckily there are some rpm files floating around the net. So i just used rpmfind to find a fedora 5.2.6 version of the mcrypt extension. After downloading it’s a one line command to install. And a apache reboot to get it working.

Constantin was so nice to comment on the fact that the mcrypt library needs to be installed before installing the mcrypt PHP extension.

$ wget ftp://rpmfind.net/linux/fedora/updates/7/i386/php-mcrypt-5.2.6-2.fc7.i386.rpm
$ rpm -ivh –nodeps php-mcrypt-5.2.6-2.fc7.i386.rpm
$ /etc/init.d/http restart

PHP CLI bad interpreter: Permission denied

This question came up on the php.general list today. And i have seen it before when writing an shell script in PHP.

#!/usr/local/bin/php
passthru("printenv");

If you are sure the PHP executable can be found in that location. And the file is executable. But it still returns this error:

/usr/local/bin/php: bad interpreter: Permission denied

Big change the file you are trying to execute is on a filesystem with the noexec flag set.
To fix this either set the exec flag for the filesystem or move the script to a place where it can be executed.

Stop ACTA