Jump to content

Archived

This topic is now archived and is closed to further replies.

ecartz

Regenerating the session when linked from an external source

Recommended Posts

Currently, if someone has cookies turned off and copies and pastes a link from osCommerce, the link will include a session ID. If the person sends the link to other people, all of them will share the same session. If the original person was logged in at the time, then they all will be logged in to that person's account.

 

Now, if the store is configured to Recreate Session on log in or account creation, then anyone who chooses to do those things will get a new session. Unfortunately, log in is not required again once you are logged in, so this would require someone to manually choose to log off and log back in again. This setting helps but does not solve the problem.

 

So what are the parameters of the problem? The concern is that someone will choose to share a link with others. The person may do this through email, IM, twitter, a blog, or whatever. The one place that we know they will not be is on the site. We want to allow sessions to persist from page to page with or without cookies. However, if someone is coming from outside osCommerce with a link that has a session ID in it, we would like to replace the session ID with a new value.

 

In includes/application_top.php, find (around lines 233-245):

// verify the IP address if the feature is enabled
 if (SESSION_CHECK_IP_ADDRESS == 'True') {
$ip_address = tep_get_ip_address();
if (!tep_session_is_registered('SESSION_IP_ADDRESS')) {
  $SESSION_IP_ADDRESS = $ip_address;
  tep_session_register('SESSION_IP_ADDRESS');
}

if ($SESSION_IP_ADDRESS != $ip_address) {
  tep_session_destroy();
  tep_redirect(tep_href_link(FILENAME_LOGIN));
}
 }

Add after it:

// only trust a session ID from the URL if refered 
// from this site
 if ( isset($HTTP_SERVER_VARS['HTTP_REFERER']) || tep_session_is_registered('first_referred_by') ) {
$referrer = parse_url($HTTP_SERVER_VARS['HTTP_REFERER']);
if ( ( HTTP_COOKIE_DOMAIN != substr('.' . $referrer['host'], -1 * strlen(HTTP_COOKIE_DOMAIN)) )
  && ( HTTPS_COOKIE_DOMAIN !=  substr('.' . $referrer['host'], -1 * strlen(HTTPS_COOKIE_DOMAIN)) )
  && ( $SID == tep_session_name() . '=' . $HTTP_GET_VARS[tep_session_name()] )
   ) 
{
  if ( function_exists('session_regenerate_id') ) {
	session_regenerate_id();
	$SID = (defined('SID') ? SID : '');
	if ( isset($HTTP_GET_VARS[tep_session_name()]) ) unset($HTTP_GET_VARS[tep_session_name()]);
	$_SESSION = array();
  }
}

if ( isset($HTTP_SERVER_VARS['HTTP_REFERER']) && ! tep_session_is_registered('first_referred_by') ) {
  tep_session_register('first_referred_by');
  $first_referred_by = $HTTP_SERVER_VARS['HTTP_REFERER'];
}
 }

Note that this code requires PHP 4.3.2 or above. Otherwise, the session_regenerate_id function will not exist and the code will do nothing. The code also requires that both the HTTP_COOKIE_DOMAIN and the HTTPS_COOKIE_DOMAIN be non-empty and set to correct values (if SSL is not used, the HTTPS setting can just be set the same as the HTTP setting). This code will not work properly in cases where two domains share sessions and customers can switch between them.

 

The code checks to see if the HTTP_REFERER is set. If it is currently set or if it was set earlier in the session, it compares the referrer's domain to the acceptable cookie domains. If it does not match either domain and the session ID was set in the URL, then we regenerate an empty session. Finally, if the HTTP_REFERER is set and it is not saved in the session, we save it to the session so as to be available for future checks (e.g. if this person sends a link with a session ID in it).

 

If the referrer is blank (what happens when someone copies and pastes a link), then it will not match the cookie domains, so the session will be regenerated. If the referrer is from an external site, it will not match the cookie domains, so the session will be regenerated. If someone clicks a link on the osCommerce site, then the referrer should be set and should match the cookie domains. If the person's browser does not send a referrer, then the referrer will never get registered in the session and will not be set for the current request, so the code gets skipped. If the current session ID does not match one from the URL, then the code doesn't apply (if the cookie is set, we assume that it was done by osCommerce and we trust it to be correct).

 

Note that this code is not really intended for security purposes. It might catch some XSS attempts, but it would be possible to bypass it. It's real target is not malicious action but simple mistakes. It allows people to share links without sharing sessions.


Always back up before making changes.

Share this post


Link to post
Share on other sites

I have this problem with sessions getting mixed up when urls containing sessionIds get published, I tried the above code and now the session id always gets recreated even when a single user is navigating around the site. I must have missed something but have no idea where to begin looking. Has anyone else experienced the same?

Share this post


Link to post
Share on other sites

Hi ecartz,

Works for Credit Card Order but not PayPal as they leave the site to pay and upon return from completion with PP screens the customer is dropped ...his PP account was charged but no order was (is) pinged back to vendor.


define('PROJECTS', 'Something that goes on forever!');

Share this post


Link to post
Share on other sites

×