I'm writing code in PHP that requires including a config.php file depending on the website URL.
I've the website URL in the variable $site, and the config for $site is in the directory configs/$site/config.php.
How can I require this file dynamically in PHP?
Is it safe to do include "configs/$site/config.php";?
If you limit $site to a set of values, yes.
$sites = array(
'siteA',
'siteB'
);
if (isset($sites[$site])) {
include "configs/$site/config.php";
} else {
throw new Exception("Unknown site");
}
But remember: Never trust anything from outside, always validate values, that come from a client (browser).
That is fine. Just make sure the $site variable cannot be changed by the user! If the user can change it, he can make it include any file.
Related
I try to read a constant from a file and be able to change this constant on demand.
So when this constant need to be written (for this example through a GET), right after I would like to reload the page to have the correct value.
But after the reload, even if my file contains the new value, it seems that the constant is still defined to the old one.
If I put a sleep before the header(Location) everything works fine. Is there a solution without the sleep, and why?
Here is the example file:
<?php
include_once 'toto.php';
if (isset($_GET['test'])) {
$file = "<?php const TOTO = '$_GET[test]'; ?>";
file_put_contents('toto.php', $file);
// sleep(3);
header('Location: index.php');
exit;
}
echo TOTO;
?>
I tried to replace the file_put_contents by fopen+fwrite+fflush+fclose without more success.
The above code working fine for me.
What your index.php contains?
Concept breaking
The concept of a constant is that throughout the application it doesn't change its value. You're breaking the principle of a constant.
Insecure
Also, since the constant is defined with user input, and written to a file, we can very easily hijack your server with any malicious code we want. Ie:
http://localhost/index.php?test=42%27;eval($_GET[%27hack%27]);%3F>
Then we can append to the query string anything we want executing.
http://localhost/index.php?hack=echo%20shell_exec(%27cat%20%2Fetc%2Fpasswd%27)
And viola, we have your /etc/passwd file. From there, we could get your /etc/shadow file and hijack your entire server. We could create more backdoors to your server - pretty much do anything to your server by passing our commands to the hack query string parameter.
The fix
To modify your script so that it doesn't break this concept, or you have no race condition on writing the new value to the file and reading, consider using a cookie or a session (both are unique to the client; cookies are editable by the client, sessions generally aren't (the session ID is, but the value bound to that session ID isn't)).
<?php
session_start();
include_once 'toto.php'; //or put session_start(); at the top of this file
if (isset($_GET['test'])) {
$_SESSION['TOTO'] = $_GET['test']; //Do some sanitation here since it's user input.
header('Location: index.php');
exit;
}
Now to read this, simply use $_SESSION['TOTO'];.
Though, since you've mentioned this should be a global configuration (ie: throughout the entire application and for all users), then use an ini file or database.
You can try putting this code -
<?php
include_once 'toto.php';
if (isset($_GET['test'])) {
$file = "<?php const TOTO = '$_GET[test]'; ?>";
if (file_put_contents('toto.php', $file)) {
// sleep(3);
header('Location: index.php');
exit;
}
}
echo TOTO;
?>
With this code the header function will be called only if the constant is written to your file properly.
Also your issue may be occurring because the page is redirected before the write to toto.php is in progress.
Question
I want to make $associate_name and $app_key global variable so I can access them on any page I want. Below is the code from my header file and the get variables are coming to index page. It works fine on index page as the $_GET data is available but when a user moves onto next page but with the same header file included it throws an error saying Undefined index. Please let me know how can I make this variable available on all pages. Thanks!
Code
$associate_name = $_REQUEST['an'];
$app_key = $_REQUEST['key'];
define('associate_name',$associate_name);
define('app_key',$app_key);
//echo "Sorry but there seems to be a problem in your code. We can't find one of the following: App name or App key";
$select_associate = "SELECT * FROM associate_account WHERE associate_name='".associate_name."' and app_key='".app_key."'";
$assoc_result = mysql_query($select_associate) or die($select_associate.mysql_error());
if(mysql_num_rows($assoc_result)<=0){
echo "Oops there seems to be a problem in your iFrame code. Please login into your Associate panel and copy/paste the link again.";
}else{
$row_assoc = mysql_fetch_assoc($assoc_result);
$associate_name=ucwords($row_assoc['associate_name']);
$app_logo=$row_assoc['app_logo'];
$app_intro_content=$row_assoc['app_intro_content'];
$bg_color=$row_assoc['bg_color'];
}
Put those variables you want as session or cookie data. Otherwise, you would have to resort to the global keyword, which is a very bad way of doing things in modern PHP applications.
It would be like this (for session):
$_SESSION["myvar"] = <value>;
It's a bit more complicated with cookies, but this should get you going ;)
Have all your variables/constants in a separate file may be constants.php
Include that constants.php wherever you want to access that variable.
Use $_SESSION
Sessions are your choice in case the value is modified. Otherwise (the value is constant from your configuration and not from user's modification, go for Constants
Say I have two html files called html1 and html2. html1 contains an embedded swf file.
Now what I want is that the user can not go to html2 directly via url. He has to click it through the link in the swf in html1. Is there a way to achieve this?
If not possible in html, is it possible with php?
Thanks
EDIT:
After answer from John, I went ahead and tried his advice, but I can never access the file2.php, even if I have been to file1.php before. It keeps redirecting me back to file1.php, even when it should not.
My code from file1.php
//file1.php
<?php
session_start();
$_SESSION['enableAccessTill']=strtotime("+5 minutes");
?>
Here is file2.php
//file2.php
<?php
session_start();
if(!isset($_SESSION['enableAccessTil'])||$_SESSION['enableAccessTil']<time())
{
header("Location: indexFLA.php");
exit;
}
?>
what am I possibly doing wrong?
found it, it was due to a misspelling - "enableAccessTil" and "enableAccessTill"
professional solution:
create protected directory and make .htaccess file in directory and copy all embedded and partial files into directory.
this directory not accessible whit get url.
but you can include file whit php include and require method.
.htaccess content:
deny from all
This wont be possible in just plain html.
An easy way to do this is php is by setting a session variable in file 1, and test in file 2 it the users has been to file 1.
file1:
<?php
session_start();
$_SESSION['enableAccessTill'] = strtotime("+5 minutes"); //set the time here till when the user has access
[...]
file2
<?php
session_start();
if(!isset( $_SESSION['enableAccessTill'] ) || $_SESSION['enableAccessTill'] < time() ){ //If time is expired
header("Location: file1.php"); //redirect user to the first file
exit;
}
[...] //continue your script here.
Things with referrer check do usually fail (some browsers/firewalls blocking that variable).
Based on the options you described, it would sound most reasonable to make the html2 a php script and check that the referrer is the html1 file. The script should display the normal html1 content if that is the case, or an error message otherwise.
A sneaky user could still get around this if they knew what was going on, but it should be fine for the majority of your audience.
Possible with php.
At index.php you must write
<?php
define('START', true);
include 'file.php';
At file.php need write
<?php defined('START) or die('Direct access!!'); ?>
<embed> your swf file embed
This way you will prevent direct access
You could do it with PHP by using session variables. Start the session in html1. Check for the session in html2. If it exists, display html2. If it does not, don't display html2. In either case, destroy the session in html2.
well is posible with html you has two options one is cookies and the other is local storage in html5
localStorage.hasClick = true;
alert(localStorage.hasClick);
http://www.html5rocks.com/en/features/storage
but obviously the straightforward solution is php / c# / ruby / etc...
//when I said html i refer to use only client side html/javascript
I have a form in a template which is posted to a PHP script. This script sets some variables in the $_SESSION array, then redirects back to the same page using the standard:
header("Location: index.php?page=enquiry-form");
The problem is that whenever the page loads after refirection, the session only contains the following three variables:
cmsuserkey
cms_admin_user_id
cms_admin_username
...all of mine have disappeared.
I'm calling session_start(); in my php script
I've set the config option: $config['use_smarty_php_tags'] = true;
The user doesn't need to be logged in to use the form (in fact the site doesn't use logins at all).
Can anyone suggest anything I'm not doing/doing wrong?
Thanks,
Rich
I had the same problem once and fixed it by addin exit() after the redirection to save the session:
header("Location: index.php?page=enquiry-form");
exit();
I've had a similar problem (though I wanted to use data from the CMS Made Simple session in another php-file). For me the cause was the following (as stated in my comment on the question):
CMS Made Simple (CMS from now on) does makes its own session name. This means that when you run session_start() in a separate php-file, it will not have the same session name. Therefore, the php-file won't be able to access CMS's session data, and CMS won't be able to access the php-file's session data.
The solution logically follows from the cause, you need them both to use the same session name.
CMS sets its session name in include.php which should be in the app's root folder.
$dirname = dirname(__FILE__);
...
$session_key = substr(md5($dirname), 0, 8);
#Setup session with different id and start it
#session_name('CMSSESSID' . $session_key);
So, in your php file you will need to do the following (before calling session_start();):
//Substitute the string $dirname for the result of __FILE__ in **include.php**!!!
$dirname = '/data/web/somefolder/someotherfolder/'
$session_key = substr(md5($dirname), 0, 8);
#session_name('CMSSESSID' . $session_key);
//Now you can call session_start();
Doing this lets your php-file access CMS's Session. If you use any plugins that put essential data in the session, you'll want to be careful not to erase any of that data.
NOTE: I use CMS version 1.8.2, this solution may not work if you use a different version.
I'm currently working on a site where I'm trying to make use of the session variables.
I have a controller script (index.php) that begins with session_start(); and has two different HTML files included within if statements. Everything works all groovy when I go to /quote/index.php, the session variables that I've set are echoed on the page as expected, however if I remove 'index.php*' from the URL so it points to just /quote the page loads however none of the session variables show up.
I'm not using session_destroy anywhere in my scripts and the session variables aren't echoing '0' so I'm fairly sure they aren't being unset, it seems as though they are just ignored without the filename in the URL!
Any insight as to why this is occuring would be awesome,
Thanks
/quote/index.php (with extraneous bits removed):
<?php
session_start();
if (isset($_GET['form']))
{
include 'form.html.php';
exit();
}
if (isset($_GET['fetchquote']))
{
$width = mysqli_real_escape_string($link, $_POST['width']);
$height = mysqli_real_escape_string($link, $_POST['height']);
$_SESSION['height'] = $height;
$_SESSION['width'] = $width;
}
include 'quote.html.php';
?>
The session variables are echoed in quote.html.php
what are the two file names?
seems that one of the file that you are including is named index.html and resides in the mysite.com/quote/ itself. And if I am not wrong, if in a directory there are index.html and index.php then the index.html is loaded by default unless the file is explicitly specified in the url. So it seems in your case when you are not specifying the index.php explicitly,the index.html is being loaded.Of course this is the case only if there is an index.html there in the directory.
Make sure you are also using session_start() at the top of the PHP pages where you want to echo the session variable. And make sure index.php is the only index in your root.
You are checking if an option is set via the GET method. Where is your form using the GET method?
Post your entire script and you'll get much better answers.
This has probably something to do with the validity scope of the session ID cookie. Because if the cookie path is set to /quote/, the cookie will only be available in /quote/ and beyond.