CakePHP and the SSL connection
So, I’m currently doing a job (well Spire Software is but more on that later) where I’m building a registration form and payment gateway.
It has been a while since I’d done any payment gateways and I was looking forward to using the CakePHP frame work and it’s Security Component. But I’ve had a bit of a * forehead slap* moment which I thought might be worth sharing.
So basically the Security component protects against a range of of things like Cross Site Scripting (XSS – where someone tries to submit data to your site from another) and SQL injection. Being a payment gateway, I also wanted to use SSL.
So I found the Techno Geeks post which contains a very clever way of ensuring that all requests are forced to use SSL.
So I set up my beforeFilter method like this:
function beforeFilter() {
$this->Auth->allow('*');
$this->Security->blackHoleCallback = 'forceSSL';
$this->Security->requireSecure('confirmation', 'processing');
}
function forceSSL() {
$this->redirect('https://' . env('SERVER_NAME') . $this->here);
}
When I implemented it for the two pages that I wanted to use the Security Component I was getting my page, only with several undefined indexes.
Fundamentally, what I wasn’t understanding is what a ‘black hole’ was. Essentially what is meant by ‘Black Holed’ is the site kills the request and gives a 404 Error Page (or Page Not Found). This prevents any nastiness happening and gets rid of any annoying bots out there who just think the page doesn’t exist. So unless you meet the requirements of the Security Component (ie you’re not using SSL) you get black holed.
For the Security component to ‘ok’ a form submission it needs to meet a range of criteria, not least of which is that the request uses a Secure Server Licences (SSL – in other words the web address needs to start with https).
So what was happening is the form was being submitted from a page that was not using SSL and therefore did not meet the security requirements. Instead of just showing a 404 error as the Security Component would usually, it was calling the forceSSL() method which was redirecting me to the same page, only with a https URL. Instead of submitting a form to that page, I was now being redirected to it instead and all the form data that was submitted was being lost.
So to fix it I just changed the parameters I passed to the ‘requireSecure’ methor to an ‘*’ (so that all pages required it). So that line is changed to:
$this->Security->requireSecure('*');
By doing so, I ensure that the form is submitted from a page with SSL enabled (as it automatically redirects me) and the security component is happy, the redirection doesn’t happen and therefore our data is intact.
And we’re done.
