How to Ensure a Secure Connection Using PHP
When submitting sensitive information over the web it’s important to ensure that the requested page is being accessed via an HTTPS encrypted connection. I’ve come across some forms that don’t check whether a secure connection has been made or not. In other words, you can delete the S from HTTP and instead of redirecting the user back to the HTTPS connection the form is just displayed unsecured. This is a BIG NO NO… as a programmer you cannot rely on the visitor, or even other developers who would be linking to the form, to request a form securely. In this post I will review how you can ensure that your users are accessing certain pages using a secure connection.
The Server Superglobal
How can you tell if your user is requesting a certain page using a secure connection (HTTPS)? Enter the PHP server surperglobal.
“$_SERVER is an array containing information such as headers, paths, and script locations. The entries in this array are created by the web server.” - PHP Manual (http://www.php.net)
There are 2 elements within this array that you can check that will tell you whether the user has made a secure request or not: https and server_port.
Something to keep in mind is that each web server will provide or not provide certain information in the $_SERVER array depending on their configuration. The PHP manual also points this out:
“There is no guarantee that every web server will provide any of these; servers may omit some, or provide others not listed here.” - PHP Manual (http://www.php.net)
So I guess that brings us back to the original question: how can you tell if your user is requesting a certain page using a secure connection (HTTPS)? Of the 2 elements mentioned above, server_port is part of the CGI 1.1 specification so the chances are good that element will be available in most servers. You can check for the availability of the https element if you wish but you should also include a check of the server_port as a fallback.
There is a good code example in the comments of the PHP manual of a function that checks whether or not the user has made a secure request:
This example function makes use of both the https and server_port elements of the superglobal array and also takes into account the different values that might be provided based on the web server. The only thing I will mention about using the server_port element is to make sure you know what port your server is using for HTTPS connections. I believe 443 is the standard, but ports can be changed so you just want to make sure you are checking the correct port for your server.
What about CodeIgniter (CI)?
If your programming using CI, you could certainly put the function above in a helper and call it whenever necessary. Or, a technique I’ve used successfully in the past, is to put the check in a custom library and auto load it. When you do it this way the connection is tested every time a page is loaded automatically without you having to make any additional function calls. And instead of returning TRUE or FALSE you can simply redirect the user to the requested page using HTTPS instead of HTTP which truly automates the process.
One thing that can trip you up when making secure connections using CI is the address you’ve entered on line 14 of application/config/config.php. If you enter just a static address starting with HTTP then HTTP will be used when calling any URL helper function like site_url() or anchor(). To avoid this issue, you can replace line 14 with the following code from the CI wiki:
This code will automatically set the base_url config element so you don’t have to. This also comes in real handy when writing portable code that you want to distribute to other users or clients for installation on their own servers.
That’s a wrap
That does it for making sure your files are being accessed securely. If you have any questions or use a different technique for checking secure connections please share them by posting a comment.