Session issues after installing Coldfusion 9.01 update - OnRequestEnd behaviour change

Finally got to the bottom of an session problem we've been having with a heavily-trafficked live server since we installed the Coldfusion 9.01 update, Hotfix 1 (CHF1) for ColdFusion 9.0.1 and the hotfix for security bulletin APSB11-04

Essentially, users appeared to be losing session information in between requests. Now, there is a known issue with the fix for APSB11-04, to with the Session Fixation issue, so this part of the fix can be turned off using a JVM switch (see the technote above).

But even after implementing this workaround, we were having an issue with some sessions (fewer, but still a lot) appearing to being lost.

It took quite a while to get to a solution, as we thought we were dealing with the problem noted above, but we finally nailed this down to a change in Coldfusion's behaviour after cflocation, and in fact our problem was not with the session scope but with the request scope.

Ben Nadel has blogged about this change as a change from Coldfusion 8 to Coldfusion 9, but as far as we can see it is actually a change between 9 and 9.01.

Essentially, in versions prior to 9.01, the 'OnRequestEnd' method in application.cfc would not be called if a cflocation took place before the end of the request i.e. a request with a cflocation in it would never actually 'end' - just the new request indicated in the cflocation would start.

In Coldfusion 9.01, the OnRequestEnd method is always fired, whether you cflocation before it or not.

In our case the problem was caused by a cflocation to enforce the use of https on certain templates - if https was 'off', we would cflocation to a 'https' url. But, we were setting a request variable that the OnRequestEnd method expected to exist *after* we did the cflocation.

In the past, that didn't matter, as onRequestEnd never got fired. Now, all code after the cflocation is abandoned (as before), but onRequestEnd *does* fire. And doesn't find the request variable it expects, and then errors.

So the simple answer is... if your onRequestEnd expects a variable to exist, make sure you either cfparam it in onRequestEnd, or set it before you do any cflocations.

[If you dig far enough in the release notes for 9.01 you will find this mentioned as a 'fix' - but I personally would call it a change of behaviour rather than a 'fix'!]

Event Photography Website Development

Horisk have just completed web development on a bespoke e-commerce website for the specialist Scottish event photographers Xpressphoto.

As well as full information about the business, photography portfolios and a Search Engine Optimised blog, the site incorporates custom developed e-commerce galleries. The generous image sizes and number of images per page easily allows customers to quickly browse all photos of an event, add their chosen shots to a basket and pay online.

The back-end allows Xpressphoto to fully customise their product offerings e.g. pricing and descriptions. Preview images are uploaded by ftp, where they can be sorted into galleries and categories, with thumbnail images being auto-generated.

The site is currently integrated with Paypal for payment processing, but will soon be switching to integrate with Protx to process payments for Barclaycard Merchant Services.

The site uses a combination of Coldfusion and PHP to power the blog, images galleries and e-commerce functions.

When Filemaker Privileges are not enough

Normally adjusting Filemaker privileges for user groups is enough to embed the required security into your solution. You can achieve most things through the usual granular access to script, layout, record and value list privileges.

Sometimes this isn't enough though. What if you have an action that can only be performed by a user if they are a member of a given privilege set OR they conform to a rule that is based on the content of the record being viewed?

I recently had a request from a client to add a process into our Deadline solution for publishers that I just couldn't achieve with the privileges alone. Fortunately, as with most things Filemaker, the solution turned out to be pretty simple. The issue I was presented with relates to advertising sales orders. The client has a process whereby any salesperson can create an order in the software but all orders need to be passed by a sales manager before they can be issued to the client. In addition to this there is a rule that only the person who created the order or a sales manager can make alterations to any part of the order. Initially it seems straight forward...

1. Put the sales manager in a privilege set that allows access to an edit order screen

2. Put sales people in privilege set that does not allow access to the edit screen

The problem is though that this means the sales person who 'owns' the order can no longer edit it. The solution is really simple.

As moving to the edit screen will always require a button press I could create an authorization script to check that the user is allowed to edit that record.

The script (check_authorization) looks like this.

SetVariable[$priv; Value:Get(PrivilegeSetName)]
SetVariable[$user; Value:Get(AccountName)]
If[PatternCount(Get(ScriptParameter);$priv) or PatternCount(Get(ScriptParameter);$user)
SetVariable [$auth;Value:"Yes"]
Else
SetVariable [$auth;Value:"No"]
Show Custom Dialog ["Access Denied";"You are not allowed to do this"]
End If
Exit Script [Result:$auth]

The first two lines (SetVariable) identify the current user account and the privilege set they belong to. Not strictly necessary to do this here but I like to set up variables with more sensible names to use inside a script, at the very least I find it makes the script easier to read.

The next statement (the If) is where the decision is made. The button the user clicked to activate the script has a parameter attached and that parameter contains the account names and or privilege set names in a return separated list of individuals who are allowed to perform this action. In this case it contains

Sales_manager
ileslie

i.e. the privilege set name that is allowed to perform the action and the contents of the 'sold_by' field on the current order form being viewed. The script then compares the variables I set for $priv and $user with the script parameter and if there is a match it sets the result to 'Yes'. If there is no match it sets the result to 'No' and displays a dialog.

On exit the script returns the parameter $auth (either 'Yes' or 'No').

The reason for this is to allow this script to be called from within another script and return it the result before proceeding.

A simple example would be

Perform Script ["check_authorization";Parameter:Get(ScriptParameter)
If[Get(ScriptResult) = "Yes"]
Go to Layout ["edit_order"]
End If

So I now have a simple script that can check a users authorization to run any script or action even when the authorization depends on the content of the record being viewed.

Wedding Photography Website

Horisk have just put a new website live for Scottish wedding photographer Rhoddy Stewart.

Scottish Wedding PhotographerThe site uses a Wordpress backend for which Horisk designed new templates to best display Rhoddy's powerful images. As well as weddings, Rhoddy also produces beautiful lifestyle portraits and has a separate event photography business.

We are currently working on a Coldfusion-based print ordering system, so wedding guests can view the images in password protected galleries and order wedding photographs online.

New plant database for landscaping professionals

Horisk recently completed some behind-the-scenes work linking Filemaker Pro and MySQL databases on a new website ilexplants.co.uk for Ilex Creative Solutions.

Ilex Plants WebsiteThe website consists of an extensive database of plants for Garden Designers and Landscape Architects. This will help professionals in the industry search for and select plants based on their suitability for the conditions or situation required by their Landscape Project, whether that be design considerations (plant size, flower colour, leaf type) or site conditions such as soil structure, pH, location (coastal or urban) etc.

The database of plants was originally developed in Filemaker Pro, and Horisk's initial job was to setup a hosted version of this database so that a number of experts around the country could collaborate on preparing the initial data. Then we developed scripts to link the Filemaker database with the online MySQL database which runs the Ilex website - this means that Ilex staff can maintain the database behind the scenes using the Filemaker tools with which they are familiar, and then instantly synchronise their changes to the live website. Effectively, Filemaker Pro is acting as an easy-to-use Content Management System (CMS) for the website.

The site is a great example of how to effectively use the External SQL Data Sources (ESS) tools in Filemaker Pro to seamlessly connect Filemaker databases to other systems. Horisk are currently using this technique to quickly build complex backend CMS for a number of websites.

Modifying Wordpress to send email if your host requires the -f parameter

To increase security on email sent by websites, some web hosts (e.g. streamline.net) require that all mail sent via PHP scripts use the "-f" parameter to ensure that the sending email address is from a domain registered with that host.

This "-f" parameter is used to set the envelope sender address when using sendmail.

Wordpress does not seem to support the appending of this type of parameter by default. As a workaround, you can edit the Wordpress emailing code directly.

You can do this by modifying the function MailSend in the file wp-includes/class-phpmailer.php (search for 'function MailSend').

There is a line in here:

$rt = @mail($to, $this->EncodeHeader($this->Subject), $body, $header);

Change this to:

$rt = @mail($to, $this->EncodeHeader($this->Subject), $body, $header, "-f me@mydomain.com");

replacing the dummy email address there with one registered with the host in question.

If you are using a plugin to generate emails (such as the cforms II plugin) you will also need to edit the mailing functions there. In cforms, the functions you need to change are in lib_nonajax.php or lib_ajax.php (depending on whether you are using AJAX forms or not). In this case, the lines you need to change are the ones that read

$sentadmin = @mail($to, encode_header($vsubject), $fmessage.$attached, $headers);
   
to

$sentadmin = @mail($to, encode_header($vsubject), $fmessage.$attached, $headers, "-f me@mydomain.com");

and

$sent = @mail($field_email, encode_header(stripslashes($t[1])), $fmessage, $headers2);
   
to

$sent = @mail($field_email, encode_header(stripslashes($t[1])), $fmessage, $headers2, "-f me@mydomain.com");

As always, there may be a better way to do this - if you know one, let me know!

5 Things to consider when making the 15% VAT Rate Change

Well that's put the cat among the pigeons.

5 working days for every retailer in the UK to change their databases, accounting systems and e-commerce websites to reflect a new VAT rate.

We've already had a couple of new customers phone us for help, either with updating their Filemaker Pro databases or Coldfusion websites to reflect the VAT rate change.

If the system has been well designed in the first place, this should be relatively straightforward. But with the VAT rate not having changed since 1991, there is always the chance that a developer has taken a shortcut and hardcoded it somewhere.

The VAT rate should be stored in one global variable that can be simply changed. Hopefully this is in a database field that the system administrator can access - but it may be buried in a preferences or application file in the code somewhere only a developer can find it. Or worse, it may have been hardcoded into calculations all over the place (as we found in one case today).

A few things to be aware of if you are about to embark on the task of changing the VAT rate yourself:

  1. If the VAT rate is stored globally, make sure the VAT rate in use at the time has been stored with historical transactions (or at least the VAT charged has been stored) - and that changing the global rate will not affect reporting of existing transactions.
  2. If the VAT rate is stored globally and is easy to change, your prices will all change appropriately. But you may decide you don't want this - what about all those £9.99s becoming £9.77 ? In this case you may not want to pass the VAT cut on to your customers. You may be able to get round this issue by doing a global search directly in your database for net prices affected and replace them with net prices multiplied by the appropriate fraction to avoid the gross price changing - a bit complicated, but definitely preferable to changing hundreds of prices by hand.
  3. If you are having to change Coldfusion or PHP code, you might just be able to do a search and replace for everywhere the existing rate is mentioned. But remember to search for all the possible variations - 17.5, 0.175, 1.175, 117.5 etc - there are lots of ways to calculate VAT... (oh yeah, and just in case your developer was particularly obtuse, 85.10638297872340425531914893617 - the fraction to work out the net price from a gross price).
  4. Before you change anything, BACKUP, BACKUP, BACKUP, and after you've made the changes, TEST, TEST, TEST.
  5. Keep a note of the changes you've made, cause you're going to need to change it all back in 13 months time...

If you think you might need a hand with any of this for a Coldfusion or PHP e-commerce website, or a Filemaker Pro database, please get in touch or leave a comment below. It looks like it's going to be a busy weekend for everybody...

Cross-site Scripting Attacks

A number of our sites have come under cross-site scripting attacks in the last few days. From reading other blogs this seems to be a pretty widespread wave of automated attacks, not specifically targeted at any of our sites.

Cross-site scripting is a technique used to either compromise the databases that lie behind many modern websites or trick the website into displaying some malicious code. These attacks are pretty easy to carry out, as they only require changing some parts of the URL that visitors use to access your site.

The URL is often used to pass parameters which carry information between parts of the site - for example in a Content Management System, the url might carry a parameter like 'articleid' to indicate the page to be displayed e.g.

www.mycms.com/showpage.cfm?articleid=12367

Because the URL can be so easily changed, web developers need to validate all the data that comes from the URL to make sure it is what they expect before they start using it. In this case, to confirm that 'articleid' is a number - unfortunately this can sometimes be overlooked in the heat of development.

An attacker could alter this URL parameter to include an additional database command or link to a potentially dodgy site, e.g.

www.mycms.com/showpage.cfm?articleid=12367';DELETE FROM articles;

If the articleid parameter is not just a number, we can assume that someone is fiddling with the URL and take appropriate action.

Fortunately we develop our sites using industry standard security techniques so none of our websites seems to have been penetrated, but if you have a site developed elsewhere, it may be worth checking with your developers that they are aware of the issue and have taken appropriate steps.

This series of attacks was a good reminder to us though to go back and re-confirm that our code wasn't vulnerable - and also confirmed to us that the time spent securing sites is never time wasted.

Making folders writable for PHP when using a Windows IIs server

Many people come across problems using content management systems like Wordpress and Joomla on Windows Servers. One of the problems is folder permissions when you try to upload images or other content.

There are thousands of tutorials out there on how to fix this on Linux servers - chmod the properties of the folder to '777' - but what can you do when you are using a Windows server running IIs?

The error message I was getting in Wordpress was:

Unable to create directory C:\Inetpub\vhosts\mydomain.com\httpdocs/wp-content/uploads/2008/04. Is its parent directory writable by the server?

You may get a similar message from Mambo, Joomla or other content management systems.

In the case of Wordpress, the wp-content folder needs to be writable to IIs - or more specifically the internet user on your server. So how do you do this on Windows? Like all these things, its only easy when you know how.

Assuming you have access to the server e.g. by remote desktop:

  1. Navigate to the wp-content directory. This will most likely be in inetpub/wwwroot/yourdomain or a similar folder in the main web root.
  2. Right-click on the folder, select Properties, and then the 'Security' tab.
  3. This will show a list of the users with rights on your machine. You need to determine which one is used by the IIs process to serve web pages - usually the name in brackets after the username will be prefixed IUSR. In our case, as we are running Plesk to manage our server, the username is Plesk IIS User (ServerName/IUSR_mydomain)

  4. Folder Permissions for IIs user
  5. The only permissions set for this user will probably be the 'List Folder Contents'. You need to add the 'Write' permission, by clicking that box.
  6. Click 'Apply'.
  7. You're done (hopefully).

If you have the Plesk Control Panel, you can set these permissions directly in Plesk without having to remote desktop to the server:

  1. Click Domains, then the relevant domain, then File Manager. Navigate through the folders so you can see the appropriate directory name
  2. Click on the yellow padlock icon ('Change Permissions for Directory')
  3. Padlock

  4. Again choose the appropriate IIs user (the one with IUSR_ in the name)
  5. Click the 'Write' option
  6. Click OK.
  7. Permissions

Please let me know if you found this useful.

URL issues running Wordpress with Plesk SitePreview

If you are having trouble setting up a Wordpress installation with Plesk's Sitepreview, the following may help (and may also apply to other systems that give you a temporary URL to test sites before they go live).

Plesk is a piece of software which provides a straightforward front-end to manage a webserver, and is used by many ISPs to allow customers to manage their own servers. SitePreview is a function of the Plesk control panel which allows you to view a site via a temporary URL before it goes live. This way you and your clients can view and tweak the site before you release it to the wild by putting it on a published URL.

The normal URL format which Plesk uses for SitePreview is of the form:

http://xxx.xxx.xxx.xxx/$sitepreview/mydomain.com/

where xxx.xxx.xxx.xxx is the IP address of the server, and mydomain.com is the name of the site in Plesk (and the ultimate permanent URL).

The problem with viewing a Wordpress site at a SitePreview URL is that Wordpress strips out the $ (dollar) sign, and other special characters, from URLs. This is normally sensible behaviour as the dollar sign would normally not appear in URLs, but it breaks SitePreview, as it begins to return URLs like

http://xxx.xxx.xxx.xxx/sitepreview/mydomain.com/

(note no $ sign), which will give you a 404 Page Not Found error.

The first place I noticed this was when saving the main settings page.

When you save this page, Wordpress strips out the $ from the two URL fields. I haven't looked for the code which does this, but it is easily fixed by using PHPMyAdmin to edit the wp_options table in your Wordpress database (the wp_ may be something else depending on the table prefix you set for your tables in the wp-config.php file). The two records in this table which you have to correct are the ones where - option_name = 'home' - option_name = 'siteurl'

The second place you may have a problem is when using the admin screens. When Wordpress creates the URLs for the javascript files which are required for the 'Visual' mode of the page editor to work, it again strips out those dollar characters.

This issue can be resolved by editing the function clean_url, currently found in wp-includes/formatting.php

Early on in this function is the line:

$url = preg_replace('|[^a-z0-9-~+_.?#=!&;,/:%@()]|i', '', $url);

Just change this to:

$url = preg_replace('|[^a-z0-9-~+_.?#=!&;,/:%@()$]|i', '', $url);

i.e. add the $ sign just before the closing square bracket - the characters enclosed in this set of brackets will not be replaced in URLs.

This may have other implications I haven't discovered yet, so I would advise this as a temporary fix which should be removed when your site goes live.

If you discover any other issues or solutions with using Wordpress and Plesk's SitePreview, please leave a comment below.

BlogCFC was created by Raymond Camden. This blog is running version 5.9.002. Contact Blog Owner