Hi all

I have a custom thickbox contact form for users, I want to make the return after the form submit to be a little smarter.

I'm currently looking at using the http referer, which I know isn't always reliable but may be good enough for what I want.

Below is what I have so far :

	$referer = getenv("HTTP_REFERER");


        if($referer == "") {
            return 'page1';
        } else {
            return $referer;
        }

What I want to do is get the referer, confirm the referer is from the current site, which would include any subdomains as well *.site.com and return that referer, if the referer isn't set or is not from the current site I would like it to return to a generic page "page1".

Payment will be made to the first suitable / working answer via paypal in USD.

Thanks

Comments

JohnForsythe’s picture

Should have something for you in a minute...

JohnForsythe’s picture

function check_referer() {
  $host_domain = $_SERVER['HTTP_HOST'];
  $referer = $_SERVER['HTTP_REFERER'];
  
  // get domain from url
  preg_match('#^https?://(.*?)[:/]#i', $referer, $matches);
  $referer_domain = strtolower($matches[1]);
  
  // strip subdomains
  $referer_array = explode('.', $referer_domain);
  $referer_domain_suffix = end($referer_array);
  $referer_root_domain = strtolower(prev($referer_array) . '.' . $referer_domain_suffix);

  // check referer
  if ($referer_root_domain != $host_domain) {
    return 'page1';
  } else {
    return $referer;
  }
}

--
John Forsythe

mooffie’s picture

// strip subdomains
$referer_array = explode('.', $referer_domain);
$referer_domain_suffix = end($referer_array);
$referer_root_domain = strtolower(prev($referer_array) . '.' . $referer_domain_suffix);

won't work when there's a country-code TLD.

if ($referer_root_domain != $host_domain) {

and what if $host_domain contained a subdomain, such as 'www.' ?

JohnForsythe’s picture

This code assumes you're not using a split suffix domain like .co.uk. It will work fine with any normal domain (example.us, example.ca, example.com), and so on. There's two ways around this: modify the code for use with your specific country code. Or build some kind of white-list library of every known country code and all their various split suffixes (not worth it and unreliable, IMO).

The above code also doesn't strip the subdomains from the host domain. Here's a fix:

function check_referer() {
  $host_domain = $_SERVER['HTTP_HOST'];
  $referer = $_SERVER['HTTP_REFERER'];
  
  // get domain from url
  preg_match('#^https?://(.*?)[:/]#i', $referer, $matches);
  $referer_domain = strtolower($matches[1]);
  
  // strip subdomains from referer
  $referer_array = explode('.', $referer_domain);
  $referer_domain_suffix = end($referer_array);
  $referer_root_domain = strtolower(prev($referer_array) . '.' . $referer_domain_suffix);

  // strip subdomains from host
  $host_array = explode('.', $host_domain);
  $host_domain_suffix = end($host_array);
  $host_root_domain = strtolower(prev($host_array) . '.' . $host_domain_suffix);

  // check referer
  if ($referer_root_domain != $host_root_domain) {
    return 'page1';
  } else {
    return $referer;
  }
}

--
John Forsythe

paulnem’s picture

Great, looks like this is working for me.

Just for the record, this is a .com domain so I can't comment on anything else. However, using www or other random subdomains such as test.site.com does the job.

I did however have to change $host_domain to the actual domain, otherwise it always sent me to the default page, no subdomain in $host_domain though or it didn't work either.

I'll drop you a note about details for payment.

Thanks