Differentiate between Subdomains and Subdirectories - php

I've got a site that is pretty customized, set up on subdomains; sitename.domain.com and it's got some pages (that are the same for ALL subdomains) sitename.domain.com/this-page. Every single site has "/this-page".
We've got someone interested in using some of the stuff we've developed, but they are MARRIED to using subdirectories; domain.com/sitename which would, of course, have domain.com/sitename/this-page as well.
My question is, I've got some code
$sN = 'http://www.' . $_SERVER['HTTP_HOST'];
$PAGE = $sN . '/this-page/';
but of course this does not work for the subdirectory install (it looks for domain.com/this-page/ instead of domain.com/sitename/this-page
is there a way I can differentiate between subdomains and subdirectories?
$setup = "GET THE HOME PAGE, REGARDLESS OF SETUP"
if($setup ( CONTAINS www.X.X.com)) { //do the code above }
else if ($setup ( CONTAINS www.X.com/X)) { //do different code }

[EDIT] Tried the solution from http://www.php.net/manual/en/reserved.variables.server.php#100881 but didn't work for me, so I did this:
<?php
$sitename = 'sitename';
if (strpos($_SERVER['HTTP_HOST'],$sitename)!==false){
echo 'you are in http://'.$_SERVER['HTTP_HOST'] . '/';
// you are in http://sitename.domain.com/
} else {
$path = explode('/',$_SERVER['PHP_SELF']);
unset ($path[count($path)-1]);
echo 'you are in http://' . $_SERVER['HTTP_HOST'] . implode('/',$path) .'/';
// you are in http://www.domain.com/sitename/
}
?>

The answer from #elcodedocle is the better way of doing this. While they came up with that solution, I had ended up with a (yuckier) solution as well.
//Let's grab the current url for other uses
$cur = 'http://www.' . $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'];
//Is this subdomains or subdirectories?
$TYPE = explode('.', $cur);
if(isset($TYPE[3])){
//Yay! It's subdomains! not stupid subdirectories!
$this_root = 'http://www.' . $_SERVER['HTTP_HOST'];
} else {
//Boo.... It's stupid subdirectories.... ;o(
$chunks = explode('/', $TYPE[2]);
$this_root = 'http://www.' .$TYPE[1]. '.' .$chunks[0]. '/' .$chunks[1];
}
?>
This works as well, but it's a less graceful solution. I ended up using a slightly modified version of the code above, but for those of you wondering, this is how I got there before reloading SO. :)

Related

Trying to redirect to another page

Long story short, I am having an issue getting from one page to another. When I create a user, I am suppose to go to the login page. Instead I get https://localhost/TEST/ROOTlogin . Not entirely sure what I am doing wrong but may someone please lead me the right way?
if($result != "") {
echo "<div style='text-align:center;font-size:12px;color:white;background-color:grey;'>";
echo "<br>The following errors occured:<br><br>";
echo $result;
echo "</div>";
} else {
header("Location:". ROOT . "login");
echo header;
die;
}
<?php
ini_set("display_errors", 1);
function split_url() {
$url = isset($_GET['url']) ? $_GET['url'] : "home";
$url = explode("/", filter_var(trim($url,"/"), FILTER_SANITIZE_URL));
return $url;
}
$root = $_SERVER['REQUEST_SCHEME'] . "://" . $_SERVER['SERVER_NAME'] . $_SERVER['PHP_SELF'];
$root = trim(str_replace("index.php", "", $root), "/");
define("ROOT", $root . "/");
$URL = split_url();
if(file_exists($URL[0] . ".php")) {
require($URL[0] . ".php");
} else {
require("404.php");
}
You need to determine if your redirect is really what you think it is. So the first step is to print out the redirect string instead of redirecting.
$header = 'Location: ' . ROOT . ‘login';
die($header);
// header($location);
From here, you will know which way to go with your debugging.
If $header is not what you expect, use the same technique to debug where the mistake is being made.
If it is what you expect, but it’s redirecting somewhere else, you know it’s your server’s rewrite. (Hint: type in the redirect url directly into the browser to test)
TBH, I would just drop ROOT and use header(‘Location: /login');, assuming that your rewrite is doing the right thing.
You can try it this way:
<?php
ini_set("display_errors", 1);
function split_url($url = 'home') {
$url = explode("/", filter_var(trim($url,"/"), FILTER_SANITIZE_URL));
return $url;
}
$url = empty($_GET['url']) ? '' : $_GET['url'];
$URL = split_url($url);
$root = $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
$root = trim(str_replace("index.php", "", $root), "/");
define('ROOT', $root . '/');
if(file_exists($URL[0] . ".php")) {
require($URL[0] . ".php");
} else {
require("404.php");
}

Remove subdomain from URL/host to match domains in affiliate link array

I want to make a redirect file using php which can add Affiliates tag automatically to all links. Like how it works https://freekaamaal.com/links?url=https://www.amazon.in/ .
If I open the above link it automatically add affiliate tag to the link and the final link which is open is this ‘https://www.amazon.in/?tag=freekaamaal-21‘ And same for Flipkart and many other sites also.
It automatically add affiliate tags to various links. For example amazon, Flipkart, ajio,etc.
I’ll be very thankful if anyone can help me regarding this.
Thanks in advance 🙏
Right now i made this below code but problem is that sometimes link have extra subdomain for example https://dl.flipkart.com/ or https://m.shopclues.com/ , etc for these type links it does not redirect from the array instead of this it redirect to default link.
<?php
$subid = isset($_GET['subid']) ? $_GET['subid'] : 'telegram'; //subid for external tracking
$affid = $_GET['url']; //main link
$parse = parse_url($affid);
$host = $parse['host'];
$host = str_ireplace('www.', '', $host);
//flipkart affiliate link generates here
$url_parts = parse_url($affid);
$url_parts['host'] = 'dl.flipkart.com';
$url_parts['path'] .= "/";
if(strpos($url_parts['path'],"/dl/") !== 0) $url_parts['path'] = '/dl'.rtrim($url_parts['path'],"/");
$url = $url_parts['scheme'] . "://" . $url_parts['host'] . $url_parts['path'] . (empty($url_parts['query']) ? '' : '?' . $url_parts['query']);
$afftag = "harshk&affExtParam1=$subid"; //our affiliate ID
if (strpos($url, '?') !== false) {
if (substr($url, -1) == "&") {
$url = $url.'affid='.$afftag;
} else {
$url = $url.'&affid='.$afftag;
}
} else { // start a new query string
$url = $url.'?affid='.$afftag;
}
$flipkartlink = $url;
//amazon link generates here
$amazon = $affid;
$amzntag = "subhdeals-21"; //our affiliate ID
if (strpos($amazon, '?') !== false) {
if (substr($amazon, -1) == "&") {
$amazon = $amazon.'tag='.$amzntag;
} else {
$amazon = $amazon.'&tag='.$amzntag;
}
} else { // start a new query string
$amazon = $amazon.'?tag='.$amzntag;
}
}
$amazonlink = $amazon;
$cueurl = "https://linksredirect.com/?subid=$subid&source=linkkit&url="; //cuelinks deeplink for redirection
$ulpsub = '&subid=' .$subid; //subid
$encoded = urlencode($affid); //url encode
$home = $cueurl . $encoded; // default link for redirection.
$partner = array( //Insert links here
"amazon.in" => "$amazonlink",
"flipkart.com" => "$flipkartlink",
"shopclues.com" => $cueurl . $encoded,
"aliexpress.com" => $cueurl . $encoded,
"ajio.com" => "https://ad.admitad.com/g/?ulp=$encoded$ulpsub",
"croma.com" => "https://ad.admitad.com/g/?ulp=$encoded$ulpsub",
"myntra.com" => "https://ad.admitad.com/g/?ulp=$encoded$ulpsub",
);
$store = array_key_exists($host, $partner) === false ? $home : $partner[$host]; //Checks if the host exists if not then redirect to your default link
header("Location: $store"); //Do not changing
exit(); //Do not changing
?>
Thank you for updating your answer with the code you have and explaining what the actual problem is. Since your reference array for the affiliate links is indexed by base domain, we will need to normalize the hostname to remove any possible subdomains. Right now you have:
$host = str_ireplace('www.', '', $host);
Which will do the job only if the subdomain is www., obviously. Now, one might be tempted to simply explode by . and take the last two components. However that'd fail with your .co.id and other second-level domains. We're better off using a regular expression.
One could craft a universal regular expression that handles all possible second-level domains (co., net., org.; edu.,...) but that'd become a long list. For your use case, since your list currently only has the .com, .in and .co.in domain extensions, and is unlikely to have many more, we'll just hard-code these into the regex to keep things fast and simple:
$host = preg_replace('#^.*?([^.]+\.)(com|id|co\.id)$#i', '\1\2', $host);
To explain the regex we're using:
^ start-of-subject anchor;
.*? ungreedy optional match for any characters (if a subdomain -- or a sub-sub-domain exists);
([^.]+\.) capturing group for non-. characters followed by . (main domain name)
(com|id|co\.id) capturing group for domain extension (add to list as necessary)
$ end-of-subject anchor
Then we replace the hostname with the contents of the capture groups that matched domain. and its extension. This will return example.com for www.example.com, foo.bar.example.com -- or example.com; and example.co.id for www.example.co.id, foo.bar.example.co.id -- or example.co.id. This should help your script work as intended. If there are further problems, please update the OP and we'll see what solutions are available.

changing the wp-admin url-path, i have this function but it's not working like it should

I played around with this and I'm having trouble getting it to work. I've added it at the bottom of the functions.php file in my themes folder.. no dice.. It should be redirecting to mySecretString=foobar... When i go to wp-admin it just takes me to the admin page to login.. that page should be accessible anymore, it should only be accessible by whatever the variable $QS equals.
// Simple Query String Login page protection
function example_simple_query_string_protection_for_login_page() {
$QS = '?mySecretString=foobar';
$theRequest = 'http://' . $_SERVER['SERVER_NAME'] . '/' . 'wp-login.php' . '?'. $_SERVER['QUERY_STRING'];
// these are for testing
// echo $theRequest . '<br>';
// echo site_url('/wp-login.php').$QS.'<br>';
if ( site_url('/wp-login.php').$QS == $theRequest ) {
echo 'Query string matches';
} else {
header( 'Location: http://' . $_SERVER['SERVER_NAME'] . '/' );
}
}
add_action('login_head', 'example_simple_query_string_protection_for_login_page');
Can anyone help me get this working, it seems like it should be so easy but nothing is working for me.
Thanks in advance.
I'm not understood your requirements fully where you want to exactly redirect, it would always helpful to you when you use .htaccess files in root folder, where you can do necessary redirection instead of writing functions.
Redirect 302 /about http://www.example.net/our-company-info/
http://www.woothemes.com/2013/11/htaccess-url-redirects/

Secure Include php

Is this secure including? Or is it possible to use some RFI/LFI or what's it called?
$request_uri = explode('/', $_SERVER['REQUEST_URI']);
$script_name = explode('/', $_SERVER['SCRIPT_NAME']);
for ($i = 0; $i < sizeof($script_name); $i++) {
if ($request_uri[$i] == $script_name[$i])
{
unset($request_uri[$i]);
}
}
$command = array_values($request_uri);
if (file_exists('controllers/' . $command[0] . '.php')) {
include 'controllers/' . $command[0] . '.php';
}
update:
if (isset($_GET['p'])) {
$pages = array('home', 'login', 'register');
$page = filter_var($_GET['p'], FILTER_SANITIZE_URL);
if (in_array($page, $pages) && file_exists($page . '.php')) {
include ($page . '.php');
} else {
include ('404.php');
}
}
else {
include ('home.php');
}
Well, if you make sure that $command[0] only contains alphanumeric characters (and possibly underscores and hyphens), that could be made somewhat secure.
Something like the following might do the job:
if (!ctype_alnum($command[0])) {
// Hacking attempt!
exit;
}
But it's still a bad idea to include files based on user input. A better idea would be to use a lookup table that maps URIs to controllers, and use autoload to include the relevant files. That way, there's a strong separation between user input and the include.
Your code feeds any arbitrary string provided by the user to PHP's include; this is bad and pretty much a textbook example of https://www.owasp.org/index.php/Server-Side_Includes_(SSI)_Injection
What problem are you trying to solve that requires this?

Secure way to include page from GET parameter?

I'm working on a set up where the URLs will be along the lines of:
http://example.com/index.php?page=about
In reality they will rewritten to that from a simpler URL. index.php will include another page, using this code:
if ( isset( $_GET['page'] ) )
{
$page = $_SERVER['DOCUMENT_ROOT'] . '/pages/' . $_GET['page'] . '.php';
if ( is_file( $page ) )
include $page;
else
echo 'That page doesn\'t exist.';
}
Assuming everything in the pages folder is perfectly safe to be included, is this code secure? I've protected against the well-known directory hacks, i.e. using page=../../.passwd. Is there anything else I should be mindful of?
probably better to switch-case it
$page_name = $_GET['page'];
switch($page_name) {
case 'about':
$page = $_SERVER['DOCUMENT_ROOT'] . '/pages/about.php';
break;
case 'home': //fall through to default
case default:
$page = $_SERVER['DOCUMENT_ROOT'] . '/pages/home.php';
}
include $page;
This way, there isn't any injection problem.
Edit
Another solution would be to set up a class dedicated to handling the conversion of page name to address.
class Page {
static private $pages = array ("about", "home");
const DEFAULT_PAGE = "home";
static public function includePage($page_name) {
if (!in_array($page_name, self::$pages)) {
$page_name = self::DEFAULT_PAGE;
}
include ($_SERVER['DOCUMENT_ROOT'] . '/pages/'.$page_name.'.php';);
}
}
This way this is all managed inside a single class and future changes are easier to make without digging through other code
edited above to reflect request.
your code is ok, except that you should validate the parameter before use:
if(!preg_match("~^\w+$~", $_GET['page']))
die("page id must be alphanumeric!");
i won't recommend "switch" approach, because it decreases flexibility, which is the whole point of using dynamic includes.
You can also switch to a framework like CodeIgniter that will do it all for you and force you into adopting some coding standards which is always a good thing.
A very secure way to do this would be to first construct a list of directory contents, then match the user input to that list and use the value from the list for the include. Something in the lines of:
$sdir = $_SERVER['DOCUMENT_ROOT'].'/pages/';
$targetfile = $_GET['page'].'.php';
$filenames = scandir($sdir); // returns an array of directory contents
foreach ($files as $filename) {
if (($filename[0] != '.')
&& ($filename == $targetfile)
&& (is_file($sdir.$filename)) {
include $sdir.$filename;
break;
}
}
Or you could do it simply by:
$targetfile = $_GET['page'].'.php';
$sdir = $_SERVER['DOCUMENT_ROOT'].'/pages/';
$filenames = scandir($sdir);
if (in_array($targetfile,$filenames)) {
include $sdir.$filename;
}
But in the latter case you have to be really sure you get the check conditions right, and also use the regex check suggested in another answer. In the first case, you're only including from a list constructed from the directory contents, so it'll be safe even if the user manages to get some weird input through your checks.
When handling an arbitrary number of pages it might be best to ensure you have SEO friendly filenames. I would recommend alphanumeric filenames with hyphens or underscores:
define(DOCROOT, $_SERVER['DOCUMENT_ROOT']);
// assume you do not include file extensions in $_GET['page']
$page = trim(preg_replace('~[^\\pL\d]+~u', '-', $_GET['page']), '-');
if (is_file($page)) {
include DOCROOT . $page;
}

Categories