How do I create a dynamic PHP includes, that is secure? for example I have an index.php file with header.php and footer.php included inside of it and then grab other pages inbetween using
index.php?page=about
If possible it would need to be dynamic so using arrays and case would be time consuming and require modifications.
I also want to be able to change the title of website as well depending on what page was included.
I currently have this in place:
<?php
require_once 'includes/config.php';
//Set values for page
$page_title = 'home page';
$current_page = 'home';
require_once 'includes/header.php';
?>
CONTENT
<?php
require_once 'includes/footer.php';
?>
Thanks
Would this be a safe way to include my pages?
if( isset( $_GET[ 'page' ] ) )
{
if( strpos( $_GET[ 'page' ], "/" ) )
{
$dir = substr( str_replace( ’’, ”, $_GET[ 'page' ] ), 0, strpos( $_GET[ 'page' ], "/" ) ) . "/";
$file = substr( strrchr( $_GET['page' ], "/" ), 1 );
if( file_exists( $dir.$file.".php" ) )
{
include( $dir.$file.".php" );
} else {
include( "home.php" );
}
} else {
if( file_exists( basename( $_GET[ 'page' ] ).".php" ) )
{
include( basename( $_GET[ 'page' ] ).".php");
} else {
include( "404.php" );
}
}
} else {
include( "home.php" );
}
To prevent errors and unauthorized file access (secure) to pages outside of your web directory or invalid pages you should do the following.
Validate $_GET['page'] by checking for periods. While periods may be valid in file names, it looks like you would be constructing the filename from the value and a period could indicate a breakout attempt to gain access to a root directory.
From there I would construct the filepath for the include, and then use file_exists to make sure it exists before including it.
As for the changing title for the page include I would do something like this:
<?php
$page_title = 'Default Title';
$page_to_include = 'default';
if( strpos($_GET['page'], '.') !== false ){
//throw/display error - could be a breakout attempt
}
if( !file_exists(sprintf('page_includes/%s.php', $_GET['page'])) ){
//requested page does not exists, throw or display error
}else{
$page_to_include = sprintf('page_includes/%s.php', $_GET['page']);
}
//do page validation here with file_exists
ob_start();
include $page_to_include;
$included_page = ob_get_clean(); //gets contents and cleans the buffer and closes it
require_once 'includes/header.php';
echo $included_page;
require_once 'includes/footer.php';
?>
This way the page is included first and stored in a buffer rather that output. It allows you included page to modify $page_title, and then that modified $page_title is available to the header.php script for output within the tags.
Just to change the title? Add this to your header.php
<title>
<?php
if(isset($_GET['page']) {
echo $_GET['page'];
} else {
echo 'My Site';
}
?>
</title>
Related
I make some function in php, but I am getting stuck
if (isset($_GET['page']) )
{
$open = __DIR__.'/../view/html/'.$_GET['page'].'.php';
if (file_exists($open)){
include $open; //<<<<can i//
}
else {
"echo "The file not found";
}
}
If true, I want to include that file in another place, but how?
I am trying to put the code in where I want, but the __DIR__ is not working as I expected. I don't know how to fix it to become right. Solution cannot be found in the tutorial.
I would use:
if( isset( $_GET['page'] ) ) {
switch( strtolower( $_GET['page') ) ) {
case 'download':
include '../download.php';
break;
case 'blog':
include '../blog.php';
break;
// ... And so on
default:
echo 'File not found';
}
} else {
echo 'No file specified';
}
This way you have full control over which files can be included!
You have to do like this.
Use file_get_contents()
if (file_exists($open)){
file_get_contents($open);
}
The answer to your question is yes, that will work. Whether or not you should use readfile(), file_get_contents() or include depends on the contents of the file. If you have php code in that file, you need either include or require. But this actually brings up another problem.
As mentioned in the comments by #anonymous, you are exposing yourself to an LFI attack. To resolve this, pages should be defined as a whitelisted array. You should then check if the page is in the whitelisted array. If it is not, do not attempt to open that file.
$pages = array(
'page1',
'page2'
);
Then you can make a reference and check if it exists.
if(in_array($_GET['page'], $pages)){
//now check for the file
$open = __DIR__.'/../view/html/'.$_GET['page'].'.php';
if(file_exists($open)){
include $open;
}
} else {
//page does not exist, redirect them elsewhere.
header('Location: http://example.com/404.php');
}
I am not very advanced in php.
I found function that i can use in WP header - then when login from "small green box" in header user stay on page from that he try to login.
Here is my page with WP: http://www.computers-and-control.com/service/manuals/
Now i have other issue, i copied file /wp-login.php to /wp-logincc.php this new file is used for login in my template WP-Download Manager - when click file - that need login before download than is used /wp-logincc.php for function login.
Problem is that after login from wp-logincc.php i am redirected to "Dashboard/Admin Panel" - i would go back to the subpage i come from.
I use different subpages for downloading files with required login and allways need come back to this one i come from.
I try in my wp-logincc.php code:
<?php
/**
* WordPress User Page
*
* Handles authentication, registering, resetting passwords, forgot password,
* and other user handling.
*
* #package WordPress
*/
/** Make sure that the WordPress bootstrap has run before continuing. */
require( dirname(__FILE__) . '/wp-load.php' );
// dankam tu cos ewentualnie zmienic ---- Redirect to https login if forced to use SSL
$dankam_aaa = apply_filters( 'fromwhereyoucame', $fromwhereyoucame );
function fromwhereyoucame( $link ) {
$currenturl = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
if ( !is_user_logged_in() )
$link = str_replace( '">', '?redirect_to=' . urlencode( $currenturl ) . '">', $link );
else
$link = str_replace( '">', '&redirect_to=' . urlencode( $currenturl ) . '">', $link );
return $link;
}
if ( force_ssl_admin() && ! is_ssl() && $dankam_aaa ) {
if ( 0 === strpos($_SERVER['REQUEST_URI'], 'http') ) {
wp_redirect( set_url_scheme( $_SERVER['REQUEST_URI'], 'https' ) );
exit();
} else {
wp_redirect( 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] );
exit();
}
}
But this do nothing in /wp-logincc.php
(But this enclosed function "function fromwhereyoucame" works in "green box")
Please help to modify wp-logincc.php
why you not using plugin for this https://wordpress.org/plugins/theme-my-login/
there is a setting to set after login same page or dashboard redirect..
or
To achieve this redirect after login, add the following code to the functions.php file for your theme:
> if ( (isset($_GET['action']) && $_GET['action'] != 'logout') ||
> (isset($_POST['login_location']) && !empty($_POST['login_location']))
> ) {
> add_filter('login_redirect', 'my_login_redirect', 10, 3);
> function my_login_redirect() {
> $location = $_SERVER['HTTP_REFERER'];
> wp_safe_redirect($location);
> exit();
> } }
another solution to make changes by editing in core
wp-login.php
Line 424 - 426...
} else { $redirect_to = admin_url(); }
Change to...
} else { $redirect_to = $_SERVER[HTTP_REFERER]; }
My Hompeage is loading the sites with this script:
<?php
if(!isset($_GET['id'])) $id = 'home';
else $id = $_GET['id'];
include($id.'.php');
?>
Does anybody of you have an idea, how to connect a 404 error page with it?
Means, if Php can't find the page it will send the user to a 404 page.
Thanks for your help!
If you want to redirect the user because of non-existent file, you should uses directives of the server, in Apache it is in the .htaccess file.
If you want to redirect the user because of the non-existing id so it would like non=existent file you can redirect him:
if($_GET['id']) ... is not existent ){ // type your criteria here
header('Location: your_404_page.php');
die();
}
Something like this maybe?
<?php
if( !isset( $_GET['id'] ) )
{
$id = 'home';
}
else
{
$id = $_GET['id'];
}
if ( is_file( $id . '.php' ) )
{
include( $id . '.php' );
}
else
{
include( '404.php' );
}
?>
My redirect process is showing some crazy stuff. The first part of the whole loop works just fine (if only the first element is typed in).
Possible url's look like:
www.site.com/category
www.site.com/category/product
But also:
www.site.com/cart
Using site.com/jeans works just fine. But when you click on a product, something strange happens.
The categorie.php file (used to display categories) is STILL included and after that one, the product.php file is included.
Same story with the cart page (http://www.site.com/winkelwagen/).
So my includes are wrong at some point. Winkelwagen is a folder on my site which has an index file. It should include http://www.site.com/winkelwagen/index.php and not categorie.php as well.
The route code :
<?php
$mult = Array();
if( ! empty( $_SERVER[ 'REQUEST_URI' ] ) ) {
$mult = explode ( '/', substr ( $_SERVER[ 'REQUEST_URI' ], 1 ) );
} else if( ! empty( $_SERVER[ 'ORIG_PATH_INFO' ] ) ) {
$mult = explode ( '/', substr ( $_SERVER[ 'ORIG_PATH_INFO' ], 1 ) );
} else if( ! empty( $_SERVER[ 'PATH_INFO' ] ) ) {
$mult = explode ( '/', substr ( $_SERVER[ 'PATH_INFO' ], 1 ) );
}
if(empty($mult[0]))
{
include("comingsoon/index.html");
}
if(!empty($mult[0]) && empty($mult[1]))
{
$file = "$mult[0].php";
if($mult[0] == "index2")
{
include("index2.php");
die;
}
// if file exists include file
if(file_exists($file))
{
include($file);
}
else
{
$file2 = "/$mult[0]/index.php";
// if folder index file exists include that file
if(file_exists($file2))
{
include($file2);
}
else {
// if folder index file doesn't exist, send to category page
$_GET['q'] = $mult[0];
include("categorie.php");
}
}
}
if(!empty($mult[0]) && !empty($mult[1]))
{
if($mult[0] == "add")
{
$_GET['addid'] = $mult[1];
include("addtocart.php");
}
elseif($mult[0] == "remove")
{
$_GET['removeid'] = $mult[1];
include("deletefromcart.php");
}
// check if folder exists (first part of the url)
elseif(is_dir($mult[0]))
{
// check if file .php (second part of the url) exists
$filenew = "$mult[0]/$mult[1].php";
if(file_exists($filenew))
{
// include that file
include("$mult[0]/$mult[1].php");
}
else
{
// second file does not exist, do something
}
}
else
{
// folder does not exist so redirect to product page
$_GET['c'] = $mult[0];
$_GET['p'] = $mult[1];
include("product.php");
}
}
?>
I tried removing the categorie.php file but it still shows up (like, how on earth ?!)
I'm excited for the answer - I have absolutely no idea what I'm doing wrong.
Also nice to know: when I comment out the include(categorie.php) part in the route code, the file is STILL included...
Ok... Welcome to Stack Overflow. I'll start by saying you are allowed to post links, trying to disrupt links by using "dot" actually feels more like spam, to me at least.
I'll continue by advising you to not go with your site and that code public. It has various security vulnerabilities, to which I am not going to go into detail. But, let's just say I'm curious why your user is called d284h1 and why your site/home is on a mount point /mnt/home/d284h1...
Heed my words. You just posted your routing logic and your site on a very public site.
Regarding your code. I really hope that's SO destroying your indentation and not your actual source code.
You are missing some control logic. Some of them might have been leading to the file inclusions you were experiencing. I also noticed a possible bug, where you were testing and including a file from the root directory, instead of relatively to your site path.
Update: Actually looking back at your original code, absolutely referencing the file $file2 = "/$mult[0]/index.php"; was causing categorie.php to load. And not having proper control logic, was causing multiple inclusions to occur in the file.
Took the liberty of revising your code, mildly. The below code, should not continue to include any random files. Unless included files themselves do it.
$mult = array();
if( ! empty( $_SERVER[ 'REQUEST_URI' ] ) ) {
$mult = explode ( '/', substr ( $_SERVER[ 'REQUEST_URI' ], 1 ) );
} else if( ! empty( $_SERVER[ 'ORIG_PATH_INFO' ] ) ) {
$mult = explode ( '/', substr ( $_SERVER[ 'ORIG_PATH_INFO' ], 1 ) );
} else if( ! empty( $_SERVER[ 'PATH_INFO' ] ) ) {
$mult = explode ( '/', substr ( $_SERVER[ 'PATH_INFO' ], 1 ) );
}
if (empty($mult[0])) {
include("comingsoon/index.html");
die; #missing
}
# no need to test for !empty($mult[0]), if it were empty, the above die would fire
if (empty($mult[1])) {
$file = "$mult[0].php";
if($mult[0] == "index2") {
include("index2.php");
die;
}
// if file exists include file
if (file_exists($file)) {
include($file);
die; # missing die
} # no need for else, you just die'd
# renamed $file2 to $file, don't use temporary variable names in global scope. It clutters your application
$file = "$mult[0]/index.php";# are you sure you meant to include from the root level?
// if folder index file exists include that file
if (file_exists($file)) {
include($file);
die;# missing die
} # no need for else, you just die'd
// if folder index file doesn't exist, send to category page
$_GET['q'] = $mult[0];
include("categorie.php");
die;# missing die
}
# don't do succesive if/elseif on the same variable, use a switch!
switch($mult[0]) {
case'add':
$_GET['addid'] = $mult[1];
include('addtocart.php');
break;
case'remove':
$_GET['removeid'] = $mult[1];
include('deletefromcart.php');
break;
}
if (is_dir($mult[0])) {
// check if file .php (second part of the url) exists
$filenew = "$mult[0]/$mult[1].php";
if(file_exists($filenew)) {
// include that file
include("$mult[0]/$mult[1].php");
die; # missing die
}
} else {
// folder does not exist so redirect to product page
$_GET['c'] = $mult[0];
$_GET['p'] = $mult[1];
include("product.php");
}
My updates are commented with # and this is in no way the final form it should look like. Take a look at PSR1 for a mild idea, on what coding standards are. They are meant to help and make you more proficient in your quest for the ultimate code, despite initially feeling cumbersome.
Other things I'd continue on doing are:
swapping !empty($var) with isset($var[0]), if $var is a string
swapping include($file);die; with return include $file;, if you're in the main scope
swapping if/elseif blocks with ternary operators
Actually regarding #3, here's an example:
$mult = isset($_SERVER['REQUEST_URI'][0])
? $_SERVER['REQUEST_URI']
: isset($_SERVER['ORIG_PATH_INFO'][0])
? $_SERVER['ORIG_PATH_INFO']
: isset($_SERVER['PATH_INFO'][0])
? $_SERVER['PATH_INFO']
: false
;
$mult = $mult
? explode('/', substr($mult, 1))
: array();
P.S. I did not fix the security issues you were having, as I believe the code you are using should not be used. Consider using a framework or at least learning from one. Routing is the corner stone of good MVC, you're on the right path, go one step beyond.
Can you please test this also and send your feedback, I just re-structured the code (I made the conditions more strict using if elseif else)
<?php
$mult = Array();
if( ! empty( $_SERVER[ 'REQUEST_URI' ] ) ) {
$mult = explode ( '/', substr ( $_SERVER[ 'REQUEST_URI' ], 1 ) );
} else if( ! empty( $_SERVER[ 'ORIG_PATH_INFO' ] ) ) {
$mult = explode ( '/', substr ( $_SERVER[ 'ORIG_PATH_INFO' ], 1 ) );
} else if( ! empty( $_SERVER[ 'PATH_INFO' ] ) ) {
$mult = explode ( '/', substr ( $_SERVER[ 'PATH_INFO' ], 1 ) );
}
if(empty($mult[0]))
{
include("comingsoon/index.html");
}
elseif(!empty($mult[0]) && empty($mult[1]))
{
$file = "$mult[0].php";
if($mult[0] == "index2")
{
include("index2.php");
die;
}
else{
// if file exists include file
if(file_exists($file))
{
include($file);
}
else
{
$file2 = "/$mult[0]/index.php";
// if folder index file exists include that file
if(file_exists($file2))
{
include($file2);
}
else {
// if folder index file doesn't exist, send to category page
$_GET['q'] = $mult[0];
include("categorie.php");
}
}
}
}
elseif(!empty($mult[0]) && !empty($mult[1]))
{
if($mult[0] == "add")
{
$_GET['addid'] = $mult[1];
include("addtocart.php");
}
elseif($mult[0] == "remove")
{
$_GET['removeid'] = $mult[1];
include("deletefromcart.php");
}
// check if folder exists (first part of the url)
elseif(is_dir($mult[0]))
{
// check if file .php (second part of the url) exists
$filenew = "$mult[0]/$mult[1].php";
if(file_exists($filenew))
{
// include that file
include("$mult[0]/$mult[1].php");
}
else
{
// second file does not exist, do something
}
}
else
{
// folder does not exist so redirect to product page
$_GET['c'] = $mult[0];
$_GET['p'] = $mult[1];
include("product.php");
}
}
?>
I am doing some tests, just to learn (normally i do this in ajax way). I am trying change the page when the url is something like http://xxx/?se=page&members=11
<?php
if (isset($_GET['se'])){
switch ($_GET['se']){
case "page&members":
include "members.php";
break;
default:
include "in.php";
}
}
?>
The problem is that code will redirect to in.php even with this url http://xxx/?se=page&members=11
Assuming 11 is the id, then you should change the behaviour to this:
Link: http://xxx/?page=members&id=11
if ( isset( $_GET['page'] ) )
{
$file = "{$_GET['page']}.php";
if ( file_exists( $file ) )
include( $file );
else
include( 'in.php' );
}
Do this
<?php
if (isset($_GET['se']) && isset($_GET['members'])){
include (($_GET['se']=="page") ? "members.php" : "in.php");
}
?>
in the example you show: $_GET['se'] == 'page' and $_GET['members'] == '11'
You'll want to change your case statement:
switch ($_GET['se']){
case "11":
include "members.php";
...
You have 2 variables there where se holds the value 'page' and members holds the value '11' so your case will always default as se never holds the value '{page&members}'