It’s been some time since I last posted, due a rather hectic schedule and today I fly off to Loret De Mar, Spain for a week with the lads and two weeks after that to Miami. I’m sure this will help to take my mind of things.

As with anything you constantly learn from your mistakes and encounter various challenges and I have found that there are some problems with PHP itself from a recent and ongoing project.

Serialized Objects, Heredoc, and strings. (PHP Version 4.3.2)
Writing a serialized object to a a flat published file can hold its benefits, however this can become exceptionally large. One of the fundamental issues I found was that a fairly large serialized object inside the Heredoc syntax, would halt execution of php. Apache would log memory limits in the apache logs, however using base64 encoding and decoding on a serialized object and placing it within string literals, would execute fine. From observation, the fault would incur directly during the closing chevron’s.

URL’s with double slashe at the beginning

A single slash at the root directory will point to the sites root directory. e.g.

<a href="/root_script.php">/root</a>

I’m quite surprised i’ve never encountered this issue before, however you can manage to get URL’s to point to http://directory_name/script_name.php when the target is actually pointing to http://www.thehistorychannel.co.uk//directory_name/script_name.php for example, (note the double slash at the root directory).

When the script’s action simply contains:


< ?php
print "<form action="{$_SERVER['PHP_SELF']}" method="post">";
?>

I’m not sure if anyone else has encountered this problem?

I wrote this a while ago, whilst playing with SQL Injection, however a little unfinished, the idea was to try to write out entire files, through an SQL Injection attack.

I thought I would expand, on my previous post Exceptions, Exceptions, Exceptions, and see what is possible with a simple a SQL Injection attack. I will base this on the assumption, that if you’ve managed to overlook an arbitry SQL Injection attack, I will assume that there will be vulnerable output somewhere.

  $id = ($_REQUEST['id'])? (int) $_REQUEST['id'] : 0;
  $SearchTerm = (isset($_REQUEST['q']))? $_REQUEST['q'] : null;

  if ( $id!=0 && !empty($SearchTerm) ) {
    $SQL = "SELECT id, StartDate, EndDate, Title FROM Table_One WHERE id={$id} AND Title='{$SearchTerm}';";
    $Query = mysql_query($SQL) or die('Query Error: '.mysql_error());
    $Row = mysql_fetch_array($Query, MYSQL_ASSOC);

    if(!empty($Row['Title'])) {
      print $Row['Title'];
    }
  }

A couple experiments with sql injection.

LOAD%20DATA%20INFILE%20'/home/httpd/vhosts/ajohnstone.com/httpdocs/index.php'%20INTO%20TABLE%20test.OUTRUN;
LOAD DATA INFILE '/root/.bash_profile' INTO TABLE test.OUTRUN;

string(96) "LOAD DATA INFILE '/home/httpd/vhosts/ajohnstone.com/httpdocs/index.php' INTO TABLE test(Output);"
Query Error: Access denied for user 'user@'localhost' (using password: YES)

After toying with some XPath’s and a fair amount of XSL lately (& getting lost in XPath), I feel it would be wise to place something here to look back on…

Marcus Tucker, introduced me to Stylus Studio of which I am very thankful as XmlSpy didn’t help me to deduce the problem with one of the XPaths, (infact ‘Select Previous Link’)

So heres some snippets.

Select Previous Link – Select First Preceding Node @id with with specified PathID
//project/article[@id=$PathID]/preceding-sibling::article[1]/@id
Select Next Link – Select Following Sibling @id with with specified PathID
//project/article[@id=$PathID]/following-sibling::article/@id

Also using the following are very handy for helping you know where abouts you are:
<xsl:copy-of select=”parent::*”>
<xsl:copy-of select=”position()”>

<xsl:template match="*" mode="namespace">
   <xsl:for-each select="namespace::*">
      <xsl:if test="not(../ancestor::*[namespace::*[name() = name(current()) and . = current()]][last()])">
         <xsl:value-of select="name(..)" /> defines <xsl:text />
         <xsl:choose>
            <xsl:when test="name()">xmlns:<xsl:value-of select="name()" /></xsl:when>
            <xsl:otherwise>xmlns</xsl:otherwise>
         </xsl:choose>
         <xsl:text />="<xsl:value-of select="." />"<xsl:text />
      </xsl:if>
   </xsl:for-each>
</xsl:template>

  <!-- generate namespace declarations as needed for current
	element node and its attributes.
  -->
  <xsl:template name="findNamespace">
    <xsl:variable name="curnode" select="." />

    <xsl:for-each select=".|@*">
      <xsl:variable name="vName" select="substring-before(name(), ':')"/>
      <xsl:variable name="vUri" select="namespace-uri(.)"/>

      <xsl:variable name="vAncestNamespace">
        <xsl:call-template name="findAncNamespace">
          <xsl:with-param name="pName" select="$vName"/>
          <xsl:with-param name="pUri" select="$vUri"/>
          <xsl:with-param name="pNode" select="$curnode" />
        </xsl:call-template>
      </xsl:variable>

      <xsl:if test="not(number($vAncestNamespace))">
        <!-- not sure if "parent::*" should be "$curnode/parent::*" -->
        <xsl:if test="parent::* or namespace-uri() or contains(name(), ':')">
          <xsl:text> </xsl:text>
          <span>
            <xsl:value-of select="'xmlns'"/>
            <xsl:if test="contains(name(), ':')">
              <xsl:value-of select="concat              (':', $vName)"/>
            </xsl:if>
          </span>
          <span>="</span>
          <span>
            <xsl:value-of select="namespace-uri()"/>
          </span>
          <span>"</span>
        </xsl:if>
      </xsl:if>
    </xsl:for-each>
  </xsl:template>

  <!-- Return 1 if an ancestor of pNode (or an attribute thereof)
    has the same prefix (pName) and namespace-uri (pUri) as
    the current node, and there is no closer ancestor (or attribute
    thereof) that has the same prefix but a different namespace-uri. Return 0 otherwise. -->
  <xsl:template name="findAncNamespace">
    <xsl:param name="pNode" select="."/>
    <xsl:param name="pName" select="substring-before(name(), ':')"/>
    <xsl:param name="pUri" select="namespace-uri(.)"/>

     <xsl:choose>
      <xsl:when test="not($pNode/parent::*)">0</xsl:when>
      <xsl:otherwise>
        <xsl:choose>
          <xsl:when test="($pNode/.. | $pNode/../@*)
          [$pName = substring-before(name(), ':') and
          $pUri = namespace-uri()]">
            1
          </xsl:when>
          <xsl:when test="($pNode/.. | $pNode/../@*)
          [$pName = substring-before(name), ':')]">
          <!-- and $pUri !=namespace-uri() -->
            0
          </xsl:when>
          <xsl:otherwise>
            <xsl:call-template name="findAncNamespace">
              <xsl:with-param name="pNode" select="$pNode/.."/>
              <xsl:with-param name="pName" select="$pName"/>
              <xsl:with-param name="pUri" select="$pUri"/>
            </xsl:call-template>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:otherwise>
    </xsl:choose>

  </xsl:template>

I also wrote up some XSL to retreive parameters from XSL being parsed on the client, now I haven’t tested this although it may be beneficial to someone trying to extract parameters on the client-side.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:eg="http://schemas.example.com/"
>
<xsl:output
  omit-xml-declaration="yes"
  method = "html"
  indent = "no"
  encoding = "UTF-8"

/>
<msxsl:script language="JScript" implements-prefix="eg">
  function GetParam(name) {
    var start=location.search.indexOf("?"+name+"=");
    if (start<0) start=location.search.indexOf("&"+name+"=");
    if (start<0) return '';
    start += name.length+2;
    var end=location.search.indexOf("&",start)-1;
    if (end<0) end=location.search.length;
    var result=location.search.substring(start,end);
    var result='';

    for(var i=start;i<=end;i++) {
      var c=location.search.charAt(i);
        result=result+(c=='+'?' ':c);
      }
      return unescape(result);
    }
</msxsl:script>

<xsl:template match="/">
  <xsl:value-of select="eg:GetParam('Query')" />
</xsl:template>
<xsl:stylesheet>

Switching to Mac

In: General

25 Apr 2006

Well, I purchased a Mac Book Pro roughly a month ago and considering I have never used a Mac, i’m quite surprised as to how quickly I have adapted. Within a week I had a good grasp of the platform and now I have everything sync’d to or through my laptop, whether that be incoming phone calls on my mobile or syncronising data between multiple servers.

The fundamental aspects I like about Mac is the degree of control, you have over the OS with applescript or shell. As mentioned above, I am now making my Mac work for me with proximity detection via bluetooth, and/or trigger applescripts when motion is detected via the iSight. I find this extremely useful to actually log phone calls in iCal, or pause iTunes when on the phone. I’m also tempted to write some applescript to automatically log me onto the the intranet at work, and track my time keeping for me, with aspects such as this it just makes my life that little bit easier.

With that said, i’m not a complete Mac convert, as I have got my windows machine at work & at home constantly shelled into the Mac, I’m finding that I am only using windows to test against IE 6 or as an extra keyboard. Despite some of its gains I am still yet to figure out how to get my Exchange account at work to work completely remotely with it using a reverse proxy, I guess thats simply time and patience I need to get that setup. I guess the key things now are finding out what else is possible, and making my development experience better.

Anyway, I found the following links useful.

www.kernelthread.com
www.opensourcemac.org
www.petermaurer.de

Well, i’ve been rather busy at work, which is nothing short of typical now, however I thought I would post up a script that I wrote to automate the installation of PHP on Windows. In general I’m a very lazy person, and found it irritating going to the PHP site, downloading and manually installing PHP in the same mundane fashion that I have described in the past. Oh, and that even means monitoring the PHP.net site for new releases.

The script I wrote uses a batch file, JScript on the client using WSH,WMI, and a few applications I have bundled with this quick distribution. Which copies, SVN, CVS, and an unzip package (located in the directory bin). It will then download a number of packages that I like to keep tabs on such as:

Simply execute “CVS.PHP.bat”

Whilst, I have only set this to download CVS phpweb, and extract each. Anyway, I realise that it does struggle with PHP4, however that simply requires some DLL’s into the SAPI dir for example, anyway I haven’t got time to do anymore on this, considering i’m now using a Mac Book Pro.

There are a couple things, I haven’t automated such as virtualhosts, and setting the hosts file, however if someone has some spare time, would be nice to get that working too…

Note: requires Apache 2 and I have this scheduled to run every day at 6.30pm.

download

Anyway for those lazy people enjoy ;)

Plesk API Error Resolved

In: PHP

14 Mar 2006

After upgrading to the very latest build of Plesk the API error seems to have been resolved, and no longer causes an API error of “Domain adding was failed. Error: Can`t resolve ID for IP ()“.

Previously:

[Server 3]# rpm -qa |grep -i psa-api | sort
psa-api-cli-7.5.2-rhel3.build75050130.17
psa-api-common-7.5.2-rhel3.build75050130.17
psa-api-rpc-7.5.2-rhel3.build75050130.17
psa-api-rpc-doc-7.5.2-rhel3.build75050130.17
psa-api-rpc-protocol-7.5.2-rhel3.build75050130.17

Now:

[Server 3]# rpm -qa |grep -i psa-api | sort
psa-api-cli-7.5.4-rhel3.build75051014.16
psa-api-common-7.5.4-rhel3.build75051014.16
psa-api-rpc-7.5.4-rhel3.build75050930.11
psa-api-rpc-doc-7.5.4-rhel3.build75050930.11
psa-api-rpc-protocol-7.5.4-rhel3.build75050930.11

Perhaps upgrading on windows too will also resolve this issue.

I found this a little amazing, but SWSoft don’t actually fully support their own software.

“Unfortunately, SWSoft does not fully support the API that is built in to Plesk and more than likely, they will request that we first perform an upgrade to the latest version of Plesk before they provide any further support.”, Rackspace.

The Fault:
“Domain adding was failed. Error: Can`t resolve ID for IP ()”

NOT Working Correctly
* Server 3 (Plesk 7.5.2)

Working Correctly
* Server 2 (Plesk 7.1.7)
* Server 1 (Plesk 7.5.4)

The IP Address does exist in the domains table, for all servers.

Working Servers:

* Server Name: Server 2

mysql> SELECT * FROM IP_Addresses;
+----+-----------------+-----------------+-------+-----------+--------------------+-------------------+
| id | ip_address | mask | iface | type | ssl_certificate_id | default_domain_id |
+----+-----------------+-----------------+-------+-----------+--------------------+-------------------+
| 2 | 212.100.254.166 | 255.255.255.0 | eth0 | shared | 1 | 47 |
| 3 | 10.230.166.4 | 255.255.255.192 | eth1 | exclusive | 1 | NULL |
| 4 | 192.168.1.20 | 255.255.255.0 | eth0 | exclusive | 1 | 22 |
| 5 | 10.230.166.8 | 255.255.255.192 | eth1 | exclusive | 1 | NULL |
+----+-----------------+-----------------+-------+-----------+--------------------+-------------------+
4 rows in set (0.00 sec)

—————-

Server Name: Server 1

mysql> SELECT * FROM IP_Addresses;

+----+---------------+-----------------+-------+-----------+--------------------+-------------------+
| id | ip_address | mask | iface | type | ssl_certificate_id | default_domain_id |
+----+---------------+-----------------+-------+-----------+--------------------+-------------------+
| 1 | 70.85.198.202 | 255.255.255.248 | eth0 | shared | 1 | NULL |
| 2 | 70.85.198.203 | 255.255.255.248 | eth0 | shared | 1 | NULL |
| 3 | 70.85.198.204 | 255.255.255.248 | eth0 | exclusive | 1 | 65 |
| 4 | 70.85.198.205 | 255.255.255.248 | eth0 | shared | 1 | NULL |
| 5 | 70.85.198.206 | 255.255.255.248 | eth0 | exclusive | 7 | 15 |
+----+---------------+-----------------+-------+-----------+--------------------+-------------------+
5 rows in set (0.00 sec)

—————

Failed Server

Server name: Server 3

mysql> SELECT * FROM IP_Addresses;

+----+---------------+-----------------+-------+-----------+--------------------+-------------------+
| id | ip_address | mask | iface | type | ssl_certificate_id | default_domain_id |
+----+---------------+-----------------+-------+-----------+--------------------+-------------------+
| 4 | 10.230.166.7 | 255.255.255.192 | eth1 | exclusive | 1 | 0 |
| 5 | 192.168.1.22 | 255.255.255.0 | eth0 | shared | 1 | 0 |
| 6 | 192.168.1.223 | 255.255.255.0 | eth0 | shared | 1 | 0 |
+----+---------------+-----------------+-------+-----------+--------------------+-------------------+
3 rows in set (0.00 sec)

——-

One fundamental aspect that I noticed from observation is that Server3 had the columns default_domain_id default value set to 0 where as on all other installations had the value set to NULL. The assumption was that the record 0 for the default IP ID against the domain. Although ALTER’ing the table and testing against each resulted without sucess.

Testing against all IP’s in the waidev6 table results in the following.

* 1. [10.230.166.7] – Domain adding was failed. Error: IP address ‘10.230.166.7′ is not present in client ip pool.
* 2. [192.168.1.22] – Domain adding was failed. Error: Can`t resolve ID for IP ()
* 3. [192.168.1.223] – Domain adding was failed. Error: Can`t resolve ID for IP ()

The XML response for this is…

<?xml version="1.0" encoding="UTF-8"?>

<packet version="1.3.1.0">
  <domain>
    <add>
      <result>
        <status>error</status>
        <errcode>2307</errcode>
        <errtext>Domain adding was failed. Error: Can`t resolve ID for IP ()</errtext>
      </result>
    </add>
  </domain>
</packet>

The payload of the XML document sent across via the XMLRPC request.

<packet version="1.3.1.0">
<domain>
  <add>
    <gen_setup>
      <name>testgen8.com</name>
      <client_id>1</client_id>
      <status>0</status>
      <ip_address>192.168.1.223</ip_address>
      <vrt_hst>
        <ftp_login>catalina0</ftp_login>
        <ftp_password>057177a</ftp_password>
        <ftp_quota>0</ftp_quota>
        <fp>false</fp>
        <fp_ssl>false</fp_ssl>
        <fp_auth>false</fp_auth>
        <fp_admin_login>miaumiaul
        </fp_admin_login>
        <fp_admin_password>lalalalallaa<fp_admin_password>
        <ssl>false</ssl>
        <shell>/bin/false</shell>
        <php>true</php>
        <ssi>false</ssi>
        <cgi>false</cgi>
        <mod_perl>false</mod_perl>
        <mod_python>false</mod_python>
        <asp>false</asp>
        <asp_dot_net>false</asp_dot_net>
        <coldfusion>false</coldfusion>
        <webstat>awstats</webstat>
        <errdocs>false</errdocs>
        <at_domains>true</at_domains>
      </vrt_hst>
      <htype>vrt_hst</htype>
    </gen_setup>
    <hosting>
      <vrt_hst>
        <ftp_login>catalina0</ftp_login>
        <ftp_password>057177a</ftp_password>
        <ftp_quota>0</ftp_quota>
        <fp>false</fp>
        <fp_ssl>false</fp_ssl>
        <fp_auth>false</fp_auth>
        <fp_admin_login>miaumiaul</fp_admin_login>
        <fp_admin_password>lalalalallaa
        </fp_admin_password>
        <ssl>false</ssl>
        <shell>/bin/false</shell>
        <php>true</php>
        <ssi>false</ssi>
        <cgi>false</cgi>
        <mod_perl>false</mod_perl>
        <mod_python>false</mod_python>
        <asp>false</asp>
        <asp_dot_net>false</asp_dot_net>
        <coldfusion>false</coldfusion>
        <webstat>awstats</webstat>
        <errdocs>false</errdocs>
        <at_domains>true</at_domains>
      </vrt_hst>
      <htype>vrt_hst</htype>
    </hosting>
    <prefs>
      <www>true</www>
    </prefs>
   </add>
  </domain>
</packet>

I have also been told that this error also occurs on Windows.

Here are a few snapshots of Internet Explorer 7 Beta 2. Interestingly enough ASP.NET does not display correctly in Internet Explorer 7 Beta 2. I can’t say i’m keen on the new design or see any feature that particularly appeals to me, however it may grow on me. Also memory usage whilst using a single tab seems very low, however opening multiple tabs soon crept upto 120k.

Admittedly I don’t know too much about XAML, however its interesting to see some permissions mapped into Internet Explorer, already. As mentioned in my previous post, I now have “Microsoft Expression Interactive Designer” installed, so, I can dabble with XAML.

Firstly, with the RSS integration you cannot distinguish whether you have read an individual post, as it marks the entire feed as read when selecting a feed, you also cannot mark the entire feed as un/read, and it does not allow you to customise the RSS feed with XSL or CSS. I’m sure some of these short comings will be resolved in new’er versions.

Lately i’ve been playing with a number of beta’s from Microsoft.

Firstly was Microsoft MAX, after watching a fairly recent cast on channel9 and installing WinFX Runtime Components September CTP, I received the following error in Outlook 2003 “Could not initialize CLR MANAGED MAPI SERVICE CATASTROPIC FAILURE, Unknown error”. After finding out that The WinFX Runtime Components September CTP relies on a pre-release version of .NET Framework 2.0 and if you install it after you have installed the release version of .NET 2.0, it will completely mess up the CLR (This is easily fixed by uninstalling/installing the .NET Framework). So it looks like I will have to wait for the next release from the MAX team.

Also Microsoft have been busy adding new services to live.com, one of the most over due is distributing your favourites online. Just remember to add “favorites.live.com” to your popup blocker. Despite it being as simple as it is, I wonder, how this will compare to del.icio.us? As it is only a band object embeded, with html and I assume to be utilizing Ajax, and sending it through to an ASHX handler. Although my favourite line in the source of the html is this:
<script language="JavaScript" src="http://favorites.live.com:80/js/omniture.js?exp=11.0.1123.2"></script>

Also, a rather obscure service is Windows Live Custom Domains, although I can’t say i’ll be using this service, it may appeal to those with Shared Hosting.

I must admit I am fairly fond of MSN Messenger 8.0 Beta, from what i’ve seen so far, its not differed very much besides its user interface. Some of the key changes are Shared Folders, and storing Contact details for users. Although one thing that is missing is allowing you to move your favourite groups in a custom order.

ideas.live.com

I haven’t played with Sparkle yet, and i’ve also noticed “Microsoft Prerelease Software WinFX Runtime Components – January 2006 Community Technology Preview (CTP)“, so I will give it a try shortly. Hopefully this will fix, Max, so I can get that working too.

Usability

In: General

22 Jan 2006

I started writing this a while back, and I figured I might as well publish it, despite being some what incomplete…

I always find that usability is a difficult topic to cover and as such, there are very limited resources that solely address this issue separate to the notion of accessibility. As the two topics are usually discussed both in context with each other, I have included and brief description of their distinctions.

Usability

Usability is a term used to denote the ease with which people can employ a particular tool or other human-made object in order to achieve a particular goal. Usability can also refer to the methods of measuring usability and the study of the principles behind an object’s perceived efficiency or elegance.

Web Accessibility

Web accessibility refers to the practice of making pages on the Internet accessible to all users, especially those with disabilities.

From experience, I have noticed a number of aspects that can aid in usability, although these may seem rather trivial, the number of headaches I have had explaining these to apparently IT literate people is an uphill struggle.

  • Selecting Options from a drop down menu
    • Always predefine a default value, to purge users to select a value.
  • Removing string literals from a text box.
    • This may seem rather silly, however from observation, some people cannot distinguish that removing an string literal they have entered into a text box is removed by holding the backspace and the delete button.

Heres some interesting analysis with labels and form alignment and why you should right align form labels?

Figure5 – Eye Movement in a Left Aligned Form. Triangular Pattern. Figure6 – Eye Movement in a Right Aligned Form.Triangular Pattern.



About this blog

I have been a developer for roughly 10 years and have worked with an extensive range of technologies. Whilst working for relatively small companies, I have worked with all aspects of the development life cycle, which has given me a broad and in-depth experience.