note 43228 added to language.variables.predefined
| From: | kaseyatcornerspeeddowtcom at rn2 dot php dot net | Date: | Mon, 14 Jun 2004 21:33:04 +0000 |
| Subject: | note 43228 added to language.variables.predefined | ||
| Groups: | php.notes | ||
| Request: | Send a blank email to php-notes+get-71065@lists.php.net to get a copy of this message | ||
I have a few points to note to (debabratak at softhome dot net). Firstly, extracting all your
variables from the global variable arrays is rather cumbersome and possibly unsafe. This causes
longer run times, and wastes more memory. Then, your script is starting the session before it
parses the superglobals. Bad things can happen because of this:
<?php
// user sent a GET header with key = secret_access, val = true, so
echo $_GET["secret_access"]; // output: true
echo $secret_access; // output:
session_start();
// in previous logic, you set session variable $secret_access = false
echo $_SESSION["secret_access"]; // output: false
echo $secret_access; // output: false
extract_globals(); // Globals put into "normal" variables
echo $_GET["secret_access"]; // output: true
echo $_SESSION["secret_access"]; // output: false
echo $secret_access; // output: true
// VARIABLES ARE COMPROMISED!
// DO NOT USE $secret_access !
// USE $_SESSION["secret_access"] instead !!!
?>
Secondly, I would like to point out the fact that all $_POST, $_GET, and $_COOKIE variables are
intrinsically unsafe anyway. Users can create their own scripts in the language of their choosing
(PHP, ASP, JSP, etc.) that generate those headers to send to your PHP program via socket
connections. PHP cannot determine that these headers are any less valid than the ones sent by a web
browser, so it parses them and places them in the $_POST, $_GET, or $_COOKIE variables.
The best practice is to use $_SESSION variables to validate the user before making any decisions
based on form data. e.g.:
<?php
session_start();
if (isset($_SESSION["valid"]))
{
// all your program decisions and database interactions can go here
if (isset($_POST["button_name"]))
{
...
}
...
}
elseif (isset($_POST["submit_login"]))
{
if (($_POST["username"] == "foo") AND ($_POST["password"] ==
"bar"))
{
$_SESSION["valid"] = true;
...
}
else
{
session_unset();
session_destroy();
$error_msg = "Invalid username or password";
$result_page = "login.php";
}
}
elseif (isset($logoff))
{
session_unset();
session_destroy();
$success_msg = "You have logged off successfully";
$result_page = "login.php";
}
else
{
session_unset();
session_destroy();
$result_page = "login.php";
}
require ($result_page);
?>
Session variables are orders of magnitude harder to compromise than POST, GET, and COOKIE data,
since the server keeps track of session id's, and the session id is unique to each client and
somewhat randomly generated. If security is an ultimate concern, then you need to use SSL in case
your traffic can be sniffed (since the session cookie is passed plain text to the client).
In summary, extracting out all the superglobals to normal variable names is not a good idea for
reasons of security and ambiguity, not to mention wasted CPU cycles. For private applications (ones
that you don't want just anyone to be able to access), the only ways you can prevent malicious
access is to 1) use sessions to ensure that the user is valid (for that page), and 2) use
SSL-encryption to prevent session-hijacking.
Kasey
in reply to:
--------------------------------------------------------------
debabratak at softhome dot net
14-Mar-2003 12:59
After having register_globals = off, I am using the following piece of code to get all the variables
created for me. I have put this code in a separate file and just make it require_once() on top of
every page.
session_start();
$ArrayList = array("_GET", "_POST", "_SESSION", "_COOKIE",
"_SERVER");
foreach($ArrayList as $gblArray)
{
$keys = array_keys($$gblArray);
foreach($keys as $key)
{
$$key = trim(${$gblArray}[$key]);
}
}
This pulls out all the possible variables for me, including the predefined variables, so I can keep
coding the old style. Note that, this code does not handle the $_FILE.
Hope this helps someone.
----
Manual Page -- http://www.php.net/manual/en/language.variables.predefined.php
Edit -- http://master.php.net/manage/user-notes.php?action=edit+43228
Delete -- http://master.php.net/manage/user-notes.php?action=delete+43228&report=yes
Reject -- http://master.php.net/manage/user-notes.php?action=reject+43228&report=yes
Search -- http://master.php.net/manage/user-notes.php