Is it possible for a client to modify PHP superglobal variables, especially $_SERVER, somehow - maybe not in a common way?
In other words, is this code secure:
if (($this->error->getCode()) == '404') {
ob_clean();
echo #file_get_contents("http://".$_SERVER['SERVER_NAME'].'/404.html');
}
This code is fine - SERVER_NAME can't be modified. The ones to be careful with are $_SERVER['PHP_SELF'] or $_SERVER['REQUEST_URI'], as a user could add some js to the address bar - if these are written out to the screen they should be carefully escaped.
Your code is fine though.
Yes, that's fine.
No user can change any variable of your code unless you leave it open to them using some sort of POST/GET/COOKIE etc
On a side note, if the file is on your server, why are you using file_get_contents()?
In this case, since the $_SERVER variable only contains data related to the web server that the script is being executed on, I don't see any potential security issues unless the web server itself has been compromised. In that case, you've got a lot bigger problem on your hands. The main exception to this rule is if you use PHP_SELF or REQUEST_URI since those values can be altered via user input in the URL bar.
Seems like such a simple problem but I'm out of options here...
So I want to set up a session variable that tells me the last page visited. I thought I could do this by declaring 2 session variables in a php include at the top of every page.
session_start();
if(!$_SESSION['this_url']){
// will only be declared once
$_SESSION['this_url'] = $_SERVER['REQUEST_URI'];
}
if($_SERVER['REQUEST_URI'] != $_SESSION['this_url']){ //dont update var on page refresh
$_SESSION['last_url'] = $_SESSION['this_url'];
$_SESSION['this_url'] = $_SERVER['REQUEST_URI'];
}
Simple enough right? But for an output it gives me this:
$_SESSION['this_url'] = /support/interactive.php (correct)
$_SESSION['last_url'] = /products/compatibility/blank.gif (right path, but blank.gif? wtf?)
it SHOULD be outputting "/products/compatibility/somepage.php" but it always replaces the page name with blank.gif.
I did a sitewide search on my site and nothing else is using my variable names. I even changed the var names and still same result. blank.gif is found in some jQuery scripts - so I suspect this may be where its coming from. But still... I'm declaring these things as the first piece of script on the page and outputting them immediately after declaring them. Is my Apache server messed up or what? this doesnt make sense.
Any ideas would be greatly appreciated, thanks!
Hmm, I remember trying to do something like this a while back, and I was having odd ghost problems much like you. What I ended up doing was using hidden inputs and assigning the variables to them.
I'm not saying use hidden form elements for production, I'm just making a suggestion in case the feature you are creating is a "need now" kind of feature.
I'm still looking as to why that may happen though, what version of Apache/PHP are you running?
I've been doing PHP for a while now, never needed assistance, but totally confused this time. I have a single line of code with one echo statement.
Problem: URL parameters are automatically assuming PHP variable values of the same name. For example, I have a URL with a parameter named var_name like this:
http://www.example.com?var_name=abc123
and a 1-line PHP script with a variable named var_name, like this:
echo $var_name;
then I get output on the page of: abc123
This is the only code in the PHP page! This behavior is exactly how I expect $_GET to work, but I'm not using it.
I am having this problem only on 1 specific server, which is running PHP 5.2. I have tested on 4 other servers, none have this behavior. I assume it's a PHP config issue, but running default config and can't find anything in config documentation.
This is called register globals. If a server has register globals turned on, then you can do this.
I would recommend not to have register globals on any server. Since it can introduce a security flaw in your system.
An example of a security flaw with this.
if($auth == true)
{
// sensitive stuff here
}
If auth is just a regular variable, then I can do this in the URL.
http://www.example.com/page.php?auth=true
And see the sensitive information.
You probably have register_globals enabled:
See the manual for info.
How do I make it so that I can make a thing at the end of the address where the .php is and then tell it to do certain things. For example pull up a page like this:
sampardee.com/index.php?page=whatever
Help?
Anything else I could do with this?
This is generally achieved with the global php array $_GET. You can use it as an associative array to 'get' whatever variable you name in the url. For example your url above:
//this gives the $page variable the value 'whatever'
$page = $_GET['page'];
if($page == 'whatever'){
//do whatever
}
elseif($page == 'somethingelse'){
//do something else
}
Check out the php documentation for more information:
$_GET documentation
and there's a tutorial here:
Tutorial using QUERY_STRING and _GET
A small improvement over Brett's code:
if (array_key_exists('page', $_GET) === false)
{
$_GET['page'] = 'defaultPage';
}
$page = $_GET['page'];
// ... Brett Bender's code here
$_GET is usually used if you are sending the information to another page using the URL.
$_POST is usually used if you are sending the information from a form.
If you ever need to write your code so that it can accept information sent using both methods, you can use $_REQUEST. Make sure you check what information is being sent though, especially if you are using it with a database.
From your question it looks like you are using this to display different content on the page?
Perhaps you want to use something like a switch to allow only certain page names to be used?
i.e.
$pageName=$_REQUEST['page'];
switch($pageName){
case 'home':$include='home.php';break;
case 'about':$include='about.php';break;
case default:$include='error.php';break;
}
include($include);
This is a really simplified example, but unless the $page variable is either home or about, the website will display an error page.
Hope it helps!
I'm not quite sure what you're asking, but I think you're asking how to use GET requests.
Make GET requests against any PHP page as follows:
www.mysite.com/page.php?key1=value1&key2=value2
Now, from within PHP, you'll be able to see key1 -> value1, key2 -> value2.
Access the GET hash from within PHP as follows:
$myVal1 = $_GET['key1'] #resolves to "value1"
$myVal2 = $_GET['key2'] #resolves to "value2"
From here, play with your GET variables as you see fit.
The system of adding page parameters to a URL is know as HTTP GET (as distinct from HTTP POST, and some others less commonly used).
Take a look at this W3 schools page about GET in PHP and ahve a play about in getting parameters and using them in your PHP code.
Have fun!
I have one of those "I swear I didn't touch the server" situations. I honestly didn't touch any of the php scripts. The problem I am having is that php data is not being saved across different pages or page refreshes. I know a new session is being created correctly because I can set a session variable (e.g. $_SESSION['foo'] = "foo" and print it back out on the same page just fine. But when I try to use that same variable on another page it is not set! Is there any php functions or information I can use on my hosts server to see what is going on?
Here is an example script that does not work on my hosts' server as of right now:
<?php
session_start();
if(isset($_SESSION['views']))
$_SESSION['views'] = $_SESSION['views']+ 1;
else
$_SESSION['views'] = 1;
echo "views = ". $_SESSION['views'];
echo '<p>Refresh</p>';
?>
The 'views' variable never gets incremented after doing a page refresh. I'm thinking this is a problem on their side, but I wanted to make sure I'm not a complete idiot first.
Here is the phpinfo() for my hosts' server (PHP Version 4.4.7):
Thanks for all the helpful info. It turns out that my host changed servers and started using a different session save path other than /var/php_sessions which didn't exist anymore. A solution would have been to declare ini_set(' session.save_path','SOME WRITABLE PATH'); in all my script files but that would have been a pain. I talked with the host and they explicitly set the session path to a real path that did exist. Hope this helps anyone having session path troubles.
Check to make sure you are not mixing https:// with http://. Session variables do not flow between secure and insecure sessions.
Had same problem - what happened to me is our server admin changed the session.cookie_secure boolean to On, which means that cookies will only be sent over a secure connection. Since the cookie was not being found, php was creating a new session every time, thus session variables were not being seen.
Use phpinfo() and check the session.* settings.
Maybe the information is stored in cookies and your browser does not accept cookies, something like that.
Check that first and come back with the results.
You can also do a print_r($_SESSION); to have a dump of this variable and see the content....
Regarding your phpinfo(), is the session.save_path a valid one? Does your web server have write access to this directory?
Hope this helps.
I had following problem
index.php
<?
session_start();
$_SESSION['a'] = 123;
header('location:index2.php');
?>
index2.php
<?
session_start();
echo $_SESSION['a'];
?>
The variable $_SESSION['a'] was not set correctly. Then I have changed the index.php acordingly
<?
session_start();
$_SESSION['a'] = 123;
session_write_close();
header('location:index2.php');
?>
I dont know what this internally means, I just explain it to myself that the session variable change was not quick enough :)
Check to see if the session save path is writable by the web server.
Make sure you have cookies turned on.. (I forget when I turn them off to test something)
Use firefox with the firebug extension to see if the cookie is being set and transmitted back.
And on a unrelated note, start looking at php5, because php 4.4.9 is the last of the php4 series.
Check who the group and owner are of the folder where the script runs. If the group id or user id are wrong, for example, set to root, it will cause sessions to not be saved properly.
Check the value of "views" when before you increment it. If, for some bizarre reason, it's getting set to a string, then when you add 1 to it, it'll always return 1.
if (isset($_SESSION['views'])) {
if (!is_numeric($_SESSION['views'])) {
echo "CRAP!";
}
++$_SESSION['views'];
} else {
$_SESSION['views'] = 1;
}
Well, we can eliminate code error because I tested the code on my own server (PHP 5).
Here's what to check for:
Are you calling session_unset() or session_destroy() anywhere? These functions will delete the session data immediately. If I put these at the end of my script, it begins behaving exactly like you describe.
Does it act the same in all browsers? If it works on one browser and not another, you may have a configuration problem on the nonfunctioning browser (i.e. you turned off cookies and forgot to turn them on, or are blocking cookies by mistake).
Is the session folder writable? You can't test this with is_writable(), so you'll need to go to the folder (from phpinfo() it looks like /var/php_sessions) and make sure sessions are actually getting created.
If you set a session in php5, then try to read it on a php4 page, it might not look in the correct place! Make the pages the same php version or set the session_path.
I spent ages looking for the answer for a similar problem. It wasn't an issue with the code or the setup, as a very similar code worked perfectly in another .php on the same server. Turned out the problem was caused by a very large amount of data being saved into the session in this page. In one place we had a line like this:$_SESSION['full_list'] = $full_list where $full_list was an array of data loaded from the database; each row was an array of about 150 elements. When the code was initially written a couple of years ago, the DB only contained about 1000 rows, so the $full_list contained about 100 elements, each being an array of about 20 elements. With time, the 20 elements turned into 150 and 1000 rows turned into 17000, so the code was storing close to 64 meg of data into the session. Apparently, with this amount of data being stored, it refused to store anything else. Once we changed the code to deal with data locally without saving it into the session, everything worked perfectly.
I know one solution I found (OSX with Apache 1 and just switched to PHP5) when I had a similar problem was that unsetting 1 specific key (ie unset($_SESSION['key']);) was causing it not to save. As soon as I didn't unset that key any more it saved. I have never seen this again, except on that server on another site, but then it was a different variable. Neither were anything special.
Thanks for this one Darryl. This helped me out. I was deleting a session variable, and for some reason it was keeping the session from committing. now i'm just setting it to null instead (which is fine for my app), and it works.
I know one solution I found (OSX with Apache 1 and just switched to PHP5) when I had a similar problem was that unsetting 1 specific key (ie unset($_SESSION['key']);) was causing it not to save. As soon as I didn't unset that key any more it saved. I have never seen this again, except on that server on another site, but then it was a different variable. Neither were anything special.
Here is one common problem I haven't seen addressed in the other comments: is your host running a cache of some sort? If they are automatically caching results in some fashion you would get this sort of behavior.
Just wanted to add a little note that this can also occur if you accidentally miss the session_start() statement on your pages.
Check if you are using session_write_close(); anywhere, I was using this right after another session and then trying to write to the session again and it wasn't working.. so just comment that sh*t out
I had session cookie path set to "//" instead of "/". Firebug is awesome.
Hope it helps somebody.
I had this problem when using secure pages where I was coming from www.domain.com/auth.php that redirected to domain.com/destpage.php. I removed the www from the auth.php link and it worked. This threw me because everything worked otherwise; the session was not set when I arrived at the destination though.
A common issue often overlooked is also that there must be NO other code or extra spacing before the session_start() command.
I've had this issue before where I had a blank line before session_start() which caused it not to work properly.
Adding my solution:
Check if you access the correct domain. I was using www.mysite.com to start the session, and tried to receive it from mysite.com (without the www).
I have solved this by adding a htaccess rewrite of all domains to www to be on the safe side/site.
Also check if you use http or https.
Edit your php.ini.
I think the value of session.gc_probability is 1, so set it to 0.
session.gc_probability=0
Another few things I had to do (I had same problem: no sesson retention after PHP upgrade to 5.4). You many not need these, depending on what your server's php.ini contains (check phpinfio());
session.use_trans_sid=0 ; Do not add session id to URI (osc does this)
session.use_cookies=0; ; ensure cookies are not used
session.use_only_cookies=0 ; ensure sessions are OK to use IMPORTANT
session.save_path=~/tmp/osc; ; Set to same as admin setting
session.auto_start = off; Tell PHP not to start sessions, osc code will do this
Basically, your php.ini should be set to no cookies, and session parameters must be consistent with what osc wants.
You may also need to change a few session code snippets in application_top.php - creating objects where none exist in the tep_session_is_registered(...) calls (e eg. navigation object), set $HTTP_ variables to the newer $_SERVER ones and a few other isset tests for empty objects (google for info). I ended up being able to use the original sessions.php files (includes/classes and includes/functions) with a slightly modified application_top.php to get things going again. The php.ini settings were the main problem, but this of course depends on what your server company has installed as the defaults.