It would obviously be great to have it implemented into the main branch of OpenCart, after being hacked to death by more experienced PHP programmers of course .
I've included diff patches in the archive if you want to compare the changes - there are only 10 lines of code added or modified across all files though!
Installation
Either use the files in the 'Modified Files' folder (with the exception of the configuration and diff files) or install it manually as explained below.
Modified Files
/system/engine/url.php
/system/library/session.php
/config.php
/index.php
URL Class Changes (/system/engine/url.php)
It's probably easier to just replace this file than for me to detail it here. It will detect whether you are using a shared SSL configuration and if so append your current session ID to the URL when switching between non-secure and secure links.
A new Boolean function isSSL() has also been added to the bottom which also allows you to test for SSL in your controllers using $this->url->isSSL() should you require it for something else.
Find:
Code: Select all
public function http($route) {
return HTTP_SERVER . 'index.php?route=' . str_replace('&', '&', $route);
Code: Select all
public function http($route) {
return HTTP_SERVER . 'index.php?route=' . str_replace('&', '&', $route) . ((HTTPS_IS_SHARED_SERVER == 1 && $this->isSSL()) ? '&sid=' . session_id() : '');
Code: Select all
if (HTTPS_SERVER != '') {
$link = HTTPS_SERVER . 'index.php?route=' . str_replace('&', '&', $route);
Code: Select all
if (HTTPS_SERVER != '') {
$link = HTTPS_SERVER . 'index.php?route=' . str_replace('&', '&', $route) . ((HTTPS_IS_SHARED_SERVER == 1 && !$this->isSSL()) ? '&sid=' . session_id() : '');
Code: Select all
public function isSSL() {
return (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == "on") ? true : false;
}
Session Class (/system/library/session.php)
This class now accepts an optional session ID as a parameter to allow OpenCart to manually specify what it should be so that we can it can keep the same ID between the non-secure and secure sites.
Find:
Code: Select all
public function __construct() {
Code: Select all
public function __construct($sid = null) {
Code: Select all
session_set_cookie_params(0, '/');
session_start();
Code: Select all
if (strlen($sid = preg_replace('/[^a-zA-Z0-9\s]/', '', $sid)) > 0)
session_id($sid);
Index File Changes (/index.php)
Here we simply read the session ID from the URL if we've been given it and pass it to the session class to use.
Find:
Code: Select all
$session = new Session();
Code: Select all
$session = (isset($request->get['sid'])) ? new Session($request->get['sid']) : new Session();
Configuration File Changes (/config.php)
Find:
Code: Select all
define('HTTPS_IMAGE', 'https://127.0.0.1/opencart/image/');
Code: Select all
define('HTTPS_IS_SHARED_SERVER', '1');
I did originally modify the configuration to allow different paths to the non-secure and secure files, but having tested it on a live site it seems they are the same; if anyone needs this I can re-add it.
How it Works
It's essentially a very simple approach. Whenever a link exists which will transfer a user from a non-secure to a secure URL (i.e. from viewing a product to adding it to your basket) the URL includes the user's session ID (sid) within the query string; this is done automatically with modifications to /system/engine/url.php.
If the user is now on the secure domain all other HTTPS links will omit this session ID parameter because it is assumed to have already been saved by PHP and avoids cluttering up the URLs.
URLs leading back to the non-secure domain will include the session ID (this ensures a users' sessions will stick if they access the site using the HTTPS address initially); but likewise once at the non-secure domain all links to other non-secure URLs will omit the session ID.
TL;DR: The session ID parameter will be used every time a link takes you between a secure and non-secure URL to ensure your session data persists .
With the intention of this being added to the main release of OpenCart, setting 'HTTPS_IS_SHARED_SERVER' to 0 (or anything other than 1) in the configuration file assumes you are using a proper SSL certificate and so bypasses appending the session ID - as if this mod never existed.
Security Information
Whilst searching for information on Shared SSL support on the OpenCart forums I did find some posts from Daniel stating that Shared SSL support has not yet been included because of the security issues.
Whilst I admit I'm not completely proficient in the ins-and-outs of PHP security I don't believe this modification has any security flaws which aren't already present in sessions or OpenCart itself.
Yes it does allow users to modify the URL and set any session ID they want (the input is however escaped to alpha-numeric characters only); but this is nothing which can't already be achieved by editing your browser's cookies. Infact, if you set non-alphanumeric characters in the cookie PHP will generate a warning which if not turned off will reveal the location of OpenCart on your server.
If you use Firefox install the 'Add N Edit Cookies' extension (https://addons.mozilla.org/en-US/firefox/addon/573) and you can change your PHP Session ID cookie (called PHPSESSID as standard) to whatever you want. Anyone who is looking to break into your site will likely already know about this anyway.
I assume a more secure approach would be for OpenCart to store session IDs in the database and validate them against users' IP addresses or other such check.
The length of this post feels like my dissertation all over .