|
|
 |
CXIII. Session Handling Functions
Session support in PHP consists of a way to preserve certain data
across subsequent accesses. This enables you to build more
customized applications and increase the appeal of your web site.
A visitor accessing your web site is assigned an unique id, the
so-called session id. This is either stored in a cookie on the
user side or is propagated in the URL.
The session support allows you to register arbitrary numbers of
variables to be preserved across requests. When a visitor accesses
your site, PHP will check automatically (if session.auto_start
is set to 1) or on your request (explicitly through
session_start() or implicitly through
session_register()) whether a specific session
id has been sent with the request. If this is the case, the prior
saved environment is recreated.
| Caution |
If you do turn on
session.auto_start then you cannot put objects into
your sessions since the class definition has to be
loaded before starting the session in order to recreate the
objects in your session.
|
All registered variables are serialized after the request
finishes. Registered variables which are undefined are marked as
being not defined. On subsequent accesses, these are not defined
by the session module unless the user defines them later.
| Warning |
Some types of data can not be serialized thus stored in sessions. It
includes resource variables or objects with circular
references (i.e. objects which passes a reference to itself to another
object).
|
Note:
Session handling was added in PHP 4.0.
Note:
Please note when working with sessions that a record of a session
is not created until a variable has been registered using the
session_register() function or by adding a new
key to the $_SESSION superglobal array. This
holds true regardless of if a session has been started using the
session_start() function.
External links: Session fixation
The session module cannot guarantee that the information you store
in a session is only viewed by the user who created the session. You need
to take additional measures to actively protect the integrity of the
session, depending on the value associated with it.
Assess the importance of the data carried by your sessions and deploy
additional protections -- this usually comes at a price, reduced
convenience for the user. For example, if you want to protect users from
simple social engineering tactics, you need to enable
session.use_only_cookies. In that case,
cookies must be enabled unconditionally on the user side, or
sessions will not work.
There are several ways to leak an existing session id to third parties.
A leaked session id enables the third party to access all resources which
are associated with a specific id. First, URLs carrying session ids. If
you link to an external site, the URL including the session id might be
stored in the external site's referrer logs. Second, a more active
attacker might listen to your network traffic. If it is not encrypted,
session ids will flow in plain text over the network. The solution here
is to implement SSL on your server and make it mandatory for users.
No external libraries are needed to build this extension. Note:
Optionally you can use shared memory allocation (mm), developed by
Ralf S. Engelschall, for session storage. You have to download
mm and install it. This option is not
available for Windows platforms. Note that the session storage module
for mm does not guarantee that concurrent accesses to the same session
are properly locked. It might be more appropriate to use a shared memory
based filesystem (such as tmpfs on Solaris/Linux, or /dev/md on BSD) to
store sessions in files, because they are properly locked.
Session support is enabled in PHP by default. If you would
not like to build your PHP with session support, you should
specify the --disable-session
option to configure. To use shared memory allocation (mm) for session
storage configure PHP --with-mm[=DIR] .
The windows version of PHP has built in
support for this extension. You do not need to load any additional
extension in order to use these functions. Note:
By default, all data related to a particular session will be stored in
a file in the directory specified by the session.save_path INI option.
A file for each session (regardless of if any data is associated with
that session) will be created. This is due to the fact that a session
is opened (a file is created) but no data is even written to that file.
Note that this behavior is a side-effect of the limitations of working
with the file system and it is possible that a custom session handler
(such as one which uses a database) does not keep track of sessions
which store no data.
The behaviour of these functions is affected by settings in php.ini.
Table 1. Session configuration options | Name | Default | Changeable | Changelog |
|---|
| session.save_path | "" | PHP_INI_ALL | | | session.name | "PHPSESSID" | PHP_INI_ALL | | | session.save_handler | "files" | PHP_INI_ALL | | | session.auto_start | "0" | PHP_INI_ALL | | | session.gc_probability | "1" | PHP_INI_ALL | | | session.gc_divisor | "100" | PHP_INI_ALL | Available since PHP 4.3.2. | | session.gc_maxlifetime | "1440" | PHP_INI_ALL | | | session.serialize_handler | "php" | PHP_INI_ALL | | | session.cookie_lifetime | "0" | PHP_INI_ALL | | | session.cookie_path | "/" | PHP_INI_ALL | | | session.cookie_domain | "" | PHP_INI_ALL | | | session.cookie_secure | "" | PHP_INI_ALL | Available since PHP 4.0.4. | | session.use_cookies | "1" | PHP_INI_ALL | | | session.use_only_cookies | "0" | PHP_INI_ALL | Available since PHP 4.3.0. | | session.referer_check | "" | PHP_INI_ALL | | | session.entropy_file | "" | PHP_INI_ALL | | | session.entropy_length | "0" | PHP_INI_ALL | | | session.cache_limiter | "nocache" | PHP_INI_ALL | | | session.cache_expire | "180" | PHP_INI_ALL | | | session.use_trans_sid | "0" | PHP_INI_ALL | PHP_INI_ALL in PHP <= 4.2.3. PHP_INI_PERDIR in PHP < 5. Available since PHP 4.0.3. | | session.bug_compat_42 | "1" | PHP_INI_ALL | Available since PHP 4.3.0. | | session.bug_compat_warn | "1" | PHP_INI_ALL | Available since PHP 4.3.0. | | session.hash_function | "0" | PHP_INI_ALL | Available since PHP 5.0.0. | | session.hash_bits_per_character | "4" | PHP_INI_ALL | Available since PHP 5.0.0. | | url_rewriter.tags | "a=href,area=href,frame=src,form=,fieldset=" | PHP_INI_ALL | Available since PHP 4.0.4. |
For further details and definitions of the
PHP_INI_* constants, see the Appendix H.
The session management system supports a number of configuration
options which you can place in your php.ini file. We will give a
short overview.
- session.save_handler
string
session.save_handler defines the name of the
handler which is used for storing and retrieving data
associated with a session. Defaults to
files. See also
session_set_save_handler().
- session.save_path
string
session.save_path defines the argument which
is passed to the save handler. If you choose the default files
handler, this is the path where the files are created. Defaults to
/tmp. See also
session_save_path().
There is an optional N argument to this directive that determines
the number of directory levels your session files will be spread
around in. For example, setting to '5;/tmp'
may end up creating a session file and location like
/tmp/4/b/1/e/3/sess_4b1e384ad74619bd212e236e52a5a174If
. In order to use N you must create all of these
directories before use. A small shell script exists in
ext/session to do this, it's called
mod_files.sh. Also note that if N is
used and greater than 0 then automatic garbage collection will
not be performed, see a copy of php.ini for further
information. Also, if you use N, be sure to surround
session.save_path in
"quotes" because the separator (;) is
also used for comments in php.ini.
| Warning |
If you leave this set to a world-readable directory, such as
/tmp (the default), other users on the
server may be able to hijack sessions by getting the list of
files in that directory.
|
Note:
Prior to PHP 4.3.6, Windows users had to change this variable in order
to use PHP's session functions. A valid path must be specified, e.g.:
c:/temp.
- session.name
string
session.name specifies the name of the
session which is used as cookie name. It should only contain
alphanumeric characters. Defaults to PHPSESSID.
See also session_name().
- session.auto_start
boolean
session.auto_start specifies whether the
session module starts a session automatically on request
startup. Defaults to 0 (disabled).
- session.serialize_handler
string
session.serialize_handler defines the name
of the handler which is used to serialize/deserialize
data. Currently, a PHP internal format (name
php) and WDDX is supported (name
wddx). WDDX is only available, if PHP is
compiled with WDDX
support. Defaults to php.
- session.gc_probability
integer
session.gc_probability in conjunction with
session.gc_divisor is used to manage probability
that the gc (garbage collection) routine is started.
Defaults to 1. See session.gc_divisor for details.
- session.gc_divisor
integer
session.gc_divisor coupled with
session.gc_probability defines the probability
that the gc (garbage collection) process is started on every session
initialization.
The probability is calculated by using gc_probability/gc_divisor,
e.g. 1/100 means there is a 1% chance that the GC process starts
on each request.
session.gc_divisor defaults to 100.
- session.gc_maxlifetime
integer
session.gc_maxlifetime specifies the number
of seconds after which data will be seen as 'garbage' and
cleaned up.
Note: If you are using the default file-based session handler, your
filesystem must keep track of access times (atime). Windows FAT does
not so you will have to come up with another way to handle garbage
collecting your session if you are stuck with a FAT filesystem or any
other fs where atime tracking is not available.
Since PHP 4.2.3 it has used mtime (modified date) instead of atime. So, you
won't have problems with filesystems where atime tracking is not available.
- session.referer_check
string
session.referer_check contains the
substring you want to check each HTTP Referer for. If the
Referer was sent by the client and the substring was not
found, the embedded session id will be marked as invalid.
Defaults to the empty string.
- session.entropy_file
string
session.entropy_file gives a path to an
external resource (file) which will be used as an additional
entropy source in the session id creation process. Examples are
/dev/random or /dev/urandom
which are available on many Unix systems.
- session.entropy_length
integer
session.entropy_length specifies the number
of bytes which will be read from the file specified
above. Defaults to 0 (disabled).
- session.use_cookies
boolean
session.use_cookies specifies whether the
module will use cookies to store the session id on the client
side. Defaults to 1 (enabled).
- session.use_only_cookies
boolean
session.use_only_cookies specifies whether
the module will only use
cookies to store the session id on the client side. Defaults
to 0 (disabled, for backward compatibility).
Enabling this setting prevents attacks involved passing session
ids in URLs. This setting was added in PHP 4.3.0.
- session.cookie_lifetime
integer
session.cookie_lifetime specifies the lifetime of
the cookie in seconds which is sent to the browser. The value 0
means "until the browser is closed." Defaults to
0. See also
session_get_cookie_params() and
session_set_cookie_params().
- session.cookie_path
string
session.cookie_path specifies path to set
in session_cookie. Defaults to /. See also
session_get_cookie_params() and
session_set_cookie_params().
- session.cookie_domain
string
session.cookie_domain specifies the domain to
set in session_cookie. Default is none at all. See also
session_get_cookie_params() and
session_set_cookie_params().
- session.cookie_secure
boolean
session.cookie_secure specifies whether
cookies should only be sent over secure connections. Defaults to
off.
This setting was added in PHP 4.0.4. See also
session_get_cookie_params() and
session_set_cookie_params().
- session.cache_limiter
string
session.cache_limiter specifies cache
control method to use for session pages
(none/nocache/private/private_no_expire/public). Defaults to
nocache. See also
session_cache_limiter().
- session.cache_expire
integer
session.cache_expire specifies time-to-live
for cached session pages in minutes, this has no effect for
nocache limiter. Defaults to 180. See also
session_cache_expire().
- session.use_trans_sid
boolean
session.use_trans_sid whether transparent
sid support is enabled or not. Defaults to
0 (disabled).
Note:
For PHP 4.1.2 or less, it is enabled by compiling with
--enable-trans-sid.
From PHP 4.2.0, trans-sid feature is always compiled.
URL based session management has additional security risks
compared to cookie based session management. Users may send
a URL that contains an active session ID to their friends by
email or users may save a URL that contains a session ID to
their bookmarks and access your site with the same session ID
always, for example.
- session.bug_compat_42
boolean
PHP versions 4.2.3 and lower have an undocumented feature/bug that
allows you to initialize a session variable in the global scope,
albeit register_globals
is disabled. PHP 4.3.0 and later will warn you, if this feature is
used, and if
session.bug_compat_warn is also enabled. This feature/bug can be
disabled by disabling this directive.
- session.bug_compat_warn
boolean
PHP versions 4.2.3 and lower have an undocumented feature/bug that
allows you to initialize a session variable in the global scope,
albeit register_globals
is disabled. PHP 4.3.0 and later will warn you, if this feature is
used by enabling both
session.bug_compat_42
and
session.bug_compat_warn.
- session.hash_function
integer
session.hash_function allows you to specify the hash
algorithm used to generate the session IDs. '0' means MD5 (128 bits) and
'1' means SHA-1 (160 bits).
Note:
This was introduced in PHP 5.
- session.hash_bits_per_character
integer
session.hash_bits_per_character allows you to define
how many bits are stored in each character when converting the binary
hash data to something readable. The possible values are '4' (0-9, a-f),
'5' (0-9, a-v), and '6' (0-9, a-z, A-Z, "-", ",").
Note:
This was introduced in PHP 5.
- url_rewriter.tags
string
url_rewriter.tags specifies which HTML tags
are rewritten to include session id if transparent sid support
is enabled. Defaults to
a=href,area=href,frame=src,input=src,form=fakeentry,fieldset=
Note:
If you want XHTML conformity, remove the form entry and
use the <fieldset> tags around your form fields.
The track_vars and
register_globals
configuration settings influence how the session variables get
stored and restored.
Note:
As of PHP 4.0.3, track_vars is
always turned on.
This extension has no resource types defined.
The constants below are defined by this extension, and
will only be available when the extension has either
been compiled into PHP or dynamically loaded at runtime.
- SID
(string)
Constant containing either the session name and session ID in
the form of "name=ID" or empty string
if session ID was set in an appropriate session cookie.
Note:
As of PHP 4.1.0, $_SESSION is available as a
global variable just like $_POST,
$_GET, $_REQUEST and so on.
Unlike $HTTP_SESSION_VARS,
$_SESSION is always global. Therefore, you do not
need to use the global
keyword for $_SESSION. Please note that this
documentation has been changed to use
$_SESSION everywhere. You can substitute
$HTTP_SESSION_VARS for
$_SESSION, if you prefer the former. Also note
that you must start your session using session_start()
before use of $_SESSION becomes available.
The keys in the $_SESSION associative
array are subject to the
same limitations as regular variable names in PHP, i.e. they cannot
start with a number and must start with a letter or underscore.
For more details see the section on
variables in this manual.
If register_globals
is disabled, only members of the global associative array
$_SESSION can be registered as session
variables. The restored session variables will only be available
in the array $_SESSION.
Use of $_SESSION (or
$HTTP_SESSION_VARS with PHP 4.0.6 or less) is
recommended for improved security and code readability. With
$_SESSION, there is no need to use the
session_register(),
session_unregister(),
session_is_registered() functions. Session variables
are accessible like any other variables.
Example 1.
Registering a variable with $_SESSION.
|
<?php
session_start();
if (!isset($_SESSION['count'])) {
$_SESSION['count'] = 0;
} else {
$_SESSION['count']++;
}
?>
|
|
Example 2.
Unregistering a variable with $_SESSION and
register_globals disabled.
|
<?php
session_start();
unset($_SESSION['count']);
?>
|
|
| Caution |
Do NOT unset the whole $_SESSION with
unset($_SESSION) as this will disable the
registering of session variables through the
$_SESSION superglobal.
|
| Warning |
You can't use references in session variables as there is no feasible way
to restore a reference to another variable.
|
Example 3.
Unregistering a variable with register_globals
enabled, after registering it using
$_SESSION.
|
<?php
session_start();
session_unregister('count');
?>
|
|
If register_globals
is enabled, then each global variable can be registered as session
variable. Upon a restart of a session, these variables will be restored
to corresponding global variables. Since PHP must know which global
variables are registered as session variables, users need to register
variables with session_register() function.
You can avoid this by simply setting entries in
$_SESSION.
Example 4.
Registering a variable with register_globals
enabled
|
<?php
if (! isset($_SESSION['count'])) {
$_SESSION['count'] = 1;
} else {
$_SESSION['count']++;
}
?>
|
|
If register_globals
is enabled, then the global variables and the
$_SESSION entries will automatically reference the
same values which were registered in the prior session instance.
There is a defect in PHP 4.2.3 and earlier. If you register a new
session variable by using session_register(), the
entry in the global scope and the $_SESSION entry will
not reference the same value until the next
session_start(). I.e. a modification to the newly
registered global variable will not be reflected by the
$_SESSION entry. This has been corrected in PHP 4.3.
There are two methods to propagate a session id:
The session module supports both methods. Cookies are optimal, but
because they are not always available, we also provide an alternative
way. The second method embeds the session id directly into URLs.
PHP is capable of transforming links transparently. Unless you are using
PHP 4.2 or later, you need to enable it manually when building PHP.
Under Unix, pass
--enable-trans-sid to configure. If this build
option and the run-time option
session.use_trans_sid are enabled, relative
URIs will be changed to contain the session id automatically.
Note:
The arg_separator.output
php.ini directive allows to customize the argument seperator. For full
XHTML conformance, specify & there.
Alternatively, you can use the constant SID which is
always defined. If the client did not send an appropriate session
cookie, it has the form session_name=session_id.
Otherwise, it expands to an empty string. Thus, you can embed it
unconditionally into URLs.
The following example demonstrates how to register a variable, and
how to link correctly to another page using SID.
Example 5. Counting the number of hits of a single user |
<?php
if (!session_is_registered('count')) {
session_register('count');
$count = 1;
} else {
$count++;
}
?>
<p>
Hello visitor, you have seen this page <?php echo $count; ?> times.
</p>
<p>
To continue, <a href="nextpage.php?<?php echo strip_tags(SID); ?>">click
here</a>.
</p>
|
|
The strip_tags() is used when printing the SID
in order to prevent XSS related attacks.
Printing the SID, like shown above, is not necessary if
--enable-trans-sid was used to compile PHP.
Note:
Non-relative URLs are assumed to point to external sites and
hence don't append the SID, as it would be a security risk to
leak the SID to a different server.
To implement database storage, or any other storage method, you
will need to use session_set_save_handler() to
create a set of user-level storage functions.
User Contributed Notes
Session Handling Functions
Carlos Aya
18-May-2005 06:29
An bug of my own zoo that was hard to catch with sessions.
This may save time to someone else:
// in some page, after session_start
$_SESSION[$var] = $someValue;
// my bug: $var was wrong, as it didn't contain a valid PHP identifier.
$_SESSION['flag'] = 'here'; // flag is a valid PHP identifier... but...
// then redirect to another page with session_id and everything else ok
. . .
// in next page after session_start()
count($_SESSION) == 0
// ! yes, it's empty, as $var was wrong, that stoped the whole
// $_SESSION array to be stored
hope this saves time to others.
frank723 AT gmail DOT com
02-May-2005 10:27
Here is a script a made to initialize global variables when both GET and SESSION variables are defined. This is common when SESSION variables retain information that is changed by a GET value. For example, when a user selects a style, the url is tagged with ?style=STYLETYPEONE, so $_SESSION['style'] should be set to the get. However, if no get is set then the session variable should remain what it was. If the session variable isnt set either, then it should be set to the default value of the variable.
Here is the code:
# a session helpful thing, start a session, with default session values
# if get for that var is set set the var to th get otherwise use session
session_start();
$ses_vars = array('var1'=>var1defaultvalue, # list of passed get vars
'var2'=>var2defaultvalue,
'var3'=>var3defaultvalue);
foreach ($ses_vars as $var=>$default) {
if (!isset($_SESSION[$var])) $_SESSION[$var] = $default;
if (!isset($_GET[$var])) ${$var} = $_SESSION[$var];
else ${$var} = $_GET[$var];
}
-Frank
http://entelekheia.net
origami HAT cats.ucsc.edu
03-Apr-2005 06:57
Providing the enctype attribute of text/plain in a form tag causes the form submission to result in the _POST scope not being defined.
wolfpack
03-Apr-2005 12:02
Search engines in general don't support cookies, and they don't do well with SIDs in the query string. If you use sessions, especially URL-based sessions, and want your site to be search engine friendly, the following works well:
<?php
$br = get_browser();
if (!($br->crawler))
{
}
else
{
}
?>
To use the function get_browser() you may need to install browscap.ini. See the documentation for get_browser() for more info.
webmaster at paginadespud dot com
28-Mar-2005 12:10
hi all,
i've been troubles with sessions at my production server for weeks and today i've noticed the problem.
If you use /tmp as php sessions file dir, on a procuction server, system garbage will delete randomly files when a certain number os files are stored at tmp, so some sessions are deleted within 1 seconds, like my case.
Solution? use another dir for php sessions file, and be careful of using a shell script for your own garbage collection, called from cron, with this line:
cd /path/to/sessions; find -cmin +24 | xargs rm
Spud.
peavey at pixelpickers dot com
09-Mar-2005 10:09
Stoiev is absolutely right, this problem is a real pain in the ...
<anchor><go href="index.php?estate=1&PHPSESSID=12345678abcde"></go>
instead of this:
<anchor><go href="index.php?estate=1&PHPSESSID=12345678abcde"></go>
But this solution might work out better...
Try setting an own host/path?$id=session_id()&anothervar=someval and call ini_set('session.use_trans_sid', 0); BEFORE starting the session. It doesnt matter where you call it (document itself oder included).
It prevents PHP from putting the PHPSESSID after every get-String...
Best,
Peavey
helvecio_oliveira at yahoo dot com dot br
04-Mar-2005 06:41
This is a simple code, to read all kind of session informations, for all php user in a UN*X Server.
All php session information, are stored in tmp files:
Ex:
ls -1 /tmp/sess_*
/tmp/sess_3a0c122ea49eab3a9cea37d426463945
/tmp/sess_63fe2dda925f836a454368ee8b157ba6
/tmp/sess_8649e55af46746c3f899cf316006e4b5
/tmp/sess_8ffa7e35e7c0be16a213e97602aba31e
The code below, is a sugestion to count and identify users on-line:
<?
$_SESSION["LogonUserVar"]="user.name";
?>
<?
$files=f_ls();
foreach($files as $path){
if($fsize =filesize($path)){
$fp = fopen($path,'rb');
$lines.=fgets($fp,$fsize);
fclose($fp);
$fields = explode(";",$lines);
$fsize =filesize($fullPath);
foreach($fields as $field){
if(ereg("^LogonUserVar",$field)==true){
$aName=explode(":",$field);
$name=str_replace('"','',$aName[2]);
$aUser[$name]=$aUser[$name]+1;
}
}
}
}
$c=0;
$html1= "<html><body>".gtime()."<br>";
foreach($aUser as $user=>$nSessions){
$html3.= "<tr><td>".$user."</td><td>".$nSessions."</td></tr>";
$c++;
}
$html2="<br>$c users on-line:<br><br><table><td>User</td><td>nSessions</td>";
$html=$html1.$html2.$html3."</table></body>";
print $html;
function f_ls(){
$command="ls -1 /tmp/sess_*";
if ($proc = popen("($command)2>&1","r")){
while (!feof($proc)) $contents .= fgets($proc, 1000);
}
pclose($proc);
return explode("\n",$contents);
}
function gtime() {
return date('d/m/Y H:i:s');
}
?>
anders
02-Mar-2005 09:15
To juroh at juroh dot sk:
It's true that session variables are stored on-server, but for the server to know which session the user is using, a cookie is used. If you check your cookie cache, you'd see that the only session-related information you find in your cookie is a session id, no matter how much information you store in $_SESSION.
mat3582 at NOSPAM dot hotmail dot com
28-Feb-2005 05:36
Outputting a pdf file to a MSIE browser didn't work (MSIE mistook the file for an Active-X control,
then failed to download) untill I added
<?php
ini_set('session.cache_limiter',"0");
?>
to my script. I hope this will help someone else.
sae_zzz at yahoo dot com
22-Feb-2005 04:16
Session yang lain:
form.htm
<html>
<body>
<form action="login.php" method="post">
username : <input type="text" name="user"><br>
password : <input type="password" name="pass"><br>
<input type="submit" name="submit" value="kirim">
</form>
</body>
</html>
login.php
<?php
session_start();
if(($_POST['user']=="a3") && ($_POST['pass']=="a3"))
{$_SESSION['user']=$_POST['user'];
echo("login benar<br>
<a href=\"main.php\">Main Page</a>");}
else
{session_destroy();
echo("login salah<br>
<a href=\"form.htm\">back</a>");
exit;
}
?>
beliexp at yahoo dot com
17-Feb-2005 02:29
This is for tom(AT)darlingpet.com
I think that what you are explaining happens because what you have to put inside $_SESSION[] is the name of a variable and there are rules for giving names. I don't remeber all of them but I'm pretty sure one of them is that a variable name or identifier can't start with a number. That's why your solution works because your variable names would be i1, i2, ...
You could always try $_SESSION[my_array[$i]], you may find it more handy.
beliexp at yahoo dot com
17-Feb-2005 02:15
This is a note for someone who posted this:
I'm having toubles using sessions on my local (XP)machine.
I'm using a loginscript that works fine on line but it won't work at home...
Right, I read on the session_start() section of the manual, from the user's notes, that this problem happens in Windows because it doesn't keep the session id and opens a new one every time you call session_start(). I've been where you are too. Annoying, uh? Well, as a solution it gives you a few options:
1. You can always set the same id, which is a bit of a cheeky solution, but it works ( session_start('123456');)
2. You can pass the session_id from the first time you start a session through the URL or as a hidden item in a form and then recover it with HTTP_GET_VARS or HTTP_POST_VARS, respectively.
3. There is another one I don't remember very well but is about changing the header options. For this one you may go to the session_start() section to the user's notes.
Well, hope this can help
Good luck with your thing!!
john at digitizelife dot com
10-Feb-2005 01:30
Here is a simple way to secure a single page (index.php) using sessions. Create a file called index.php and paste the following code;
----------------------------------------------------
<?
session_start();
$un = "Bob";
$pw = "fubar";
if ($action == "logout") {
session_unset();
}
if ($action == "login") {
if ($put_un == $un) {
if ($put_pw == $pw) {
$_SESSION['auth'] = true;
} else {
$error = "incorrect password.";
}
} else {
$error = "incorrect username.";
}
}
if ($_SESSION['auth'] == true) {
} else {
$view = "login";
}
?>
<html>
<title>Secure Area</title>
<body>
<? if ($view == "login") { ?>
<form action="index.php" method="post">
user<br>
<input type="text" name="put_un"><br>
password<br>
<input type="password" name="put_pw">
<input name="action" type="hidden" id="action" value="login"><br>
<input type="submit" name="Submit" value="login"><? echo "$error<br>"; ?>
</form>
<? } if ($_SESSION['auth'] == true) { ?>
<! -- SECURE CONTENT -->
<a href="index.php?action=logout">logout</a>
<? } ?>
</body>
</html>
-----------------------------------------------------
Simply set your user name and password in the "user settings" area and put your secure content in the "SECURE CONTENT" area.
You can login using a URL like this;
http://www.yoursite.com/index.php?action=login&put_un=Bob&put_pw=fubar
You can logout using the following link;
http://www.yoursite.com/index.php?action=logout
Be sure that any addtional PHP code you wish to use should be placed in the "secure code" or the "non-secure code" sections.
Weird Silence
01-Feb-2005 08:24
If you are in need of using shared sessions across multiple servers, and don't want to use a database for it (lots of overhead), we've created a distributed session handler that uses memcached - Check it out at http://weirdsilence.net/software/memsession/ - It's free and open source!
It uses Danga.com's memcached: http://danga.com/memcached/ - Very cool stuff!
trev at beammeupnowplease dot com
03-Jan-2005 11:09
As mentioned by toxalot, you can't turn off session.use_trans_sid on an individual script basis until PHP5.
However, if you use ini_set('url_rewriter.tags', ''); at the top of your script this will stop the SID being written to the URL's in PHP4.
Hopefully will save someone else a frustrating couple of hours.
Trev
jphansen at uga dot edu
23-Dec-2004 10:23
If you assign a session subscript/key to the same name as a variable, the session variable will be volatile and lost upon navigating.
For example, if passing a setting that you want in $_SESSION, don't do this:
<?
$setting = $_REQUEST['setting'];
if (!empty($setting))
$_SESSION['setting'] = $setting;
?>
Instead, rename $setting or $_SESSION['setting'].
Xenon_54
19-Dec-2004 01:27
The session support does not use the IP address for validation. It is based on cookies and URL rewriting.
The reason you lose your session when closing your browser and reconnecting to your ISP (so you are changing your IP), is that sessions are only valides for the visit on your web site, not more.
Changing your IP address will not affect your session except if you close your browser.
Michael Wells
22-Nov-2004 12:04
If you are trying to share sessions across a cluster of servers, and don't want to use NFS, or a relatively heavy and slow RDBMS, there is an excellent tool called ShareDance that can do it over a simple TCP protocol. ShareDance comes complete with a PHP interface example and works 'out of the box' for me.
http://sharedance.pureftpd.org/
My thanks to Frank Denis for writing this elegant, valuable piece of software.
Audun Rundberg
14-Nov-2004 11:50
If you're using header('Location:' . $url) to redirect the user to another page, you should use session_write_close() to save session data before the redirect. $_SESSION is normally serialized and written to the harddrive when the script ends.
Example:
<?php
$_SESSION["Message"] = "The task was completed.";
session_write_close();
header('Location:' . $_SERVER["PHP_SELF"]);
?>
Without session_write_close(), this next piece of code would not output "The task was completed". (Assuming that this code is in place where the user was redirected.)
<?php
echo $_SESSION["Message"];
?>
toxalot
15-Sep-2004 02:54
irm at in3activa dot com
13-Sep-2004 02:57
Warnings :
session.bug_compat_42 and bug_compat_warn
Warnings may appears even if your code is correct,
because some asumptions of the developpers.
In practice, these warnings are automatic when your code results in something like:
$_SESSION['var']= NULL;
That is, the code assume that the programmer tried
to assign a unavailable (=NULL) variable because
register_globals is off.
Solution: assign anything but NULL. For example:
$_SESSION['var']= is_null($var) ? 0 : $var;
cryogen AT mac dot com
09-Sep-2004 08:02
Although this IS mentioned in the PHP manual, it is not very clear and can lead to some very hard to track down bugs.
When REGISTER_GLOBALS is ON on a server, local variables of the same name as a session variable can leak their values into the session during a POST or GET.
For example, if you run script "SESS_TEST1.PHP" below, the local var $animal will bleed its value of "I am an Elephant" into the session variable $_SESSION['animal'], which should have a value of "I am a Monkey". Beware!
<?php
session_start();
$_SESSION['animal'] = 'I am a Monkey';
$animal = 'I am an Elephant';
$value = 249;
echo "<script>window.location=\"sess_test2.php".
"?animal=$animal&value=$value\"</script>";
?>
<?php
session_start();
$animal = $_REQUEST['animal'];
$value = $_REQUEST['value'];
echo "SESSION['animal'] = ".$_SESSION['animal']." (should say \"I am a Monkey\")<br/>";
echo "\$animal = ".$animal."<br/>";
echo "\$value = ".$value."<br/>";
?>
voisine at yahoo dot com
09-Sep-2004 01:05
It seems the issue with $_SESSION being slow has been addressed. Accessing $_SESSION is just as fast as any other superglobal array. It is serialized and written to disk only once at the end of the request, not after each access as some of the previous comments seemed to imply. Some benchmarking info for assigning values to both $_SESSION and $_GET a hundred thousand times or so:
$_SESSION: 0.380021095276
$_GET: 0.50522685051
Dopey
03-Sep-2004 02:06
Be careful when using the Content-Length header with session.use_trans_sid enabled. Technically, it might not be a bug, but PHP does not update the header when it adds the session ID to links in a page. The result is that only partial content is shown in a browser.
In short: if you use ob_get_length to figure out Content-Length, turn session.use_trans_sid off!
root[noSPAM]cyberdark.net
17-Aug-2004 11:55
A common problem with session.auto_start, when activated in php.ini file, is the fact that if you've php objects inside the session classes must be loaded before session in started. You'll run into trouble then...
To avoid this, if you cannot ask your sysadmin to modify the php.ini file, add this line to your .htaccess wherever you need it in your application (usually on top of your app):
php_value session.auto_start 0
bcage at tecdigital dot net
23-Jun-2004 04:24
[Quote]
Someone posted a message here saying you should just all use the MM shared memory management for sessions. I'd like to CAUTION EVERYONE against using it!
I run a few webservers for a webhosting company, and we quickly ran in to PHP pages segfaulting Apache for unknown reasons, until we did a test with sessions. It turns out that the sessions, while using the mm stuff, couldn't keep the data right. I guess it was to do with the file locking issue mentioned in the documentation here (I didn't notice this until now!).
Anyways, if you run a Unix machine that can map virtual memory to a mount point (like tmpfs or shm or whatever it may be called), use this instead. It's volatile like mm, but works. Only thing you don't get is hidden session info so that other people don't know how to open it easily - but it's better than trying to use mm and having the webserver crash all the time!
[EndQuote]
You're totally right, in my server (FreeBSD 5.2) when using mm to handle sessions, dotProject wouldn't even start, it crashed when accessing index.php. This was solved by creating a swap-backed memory disk with the following options
rw,-s60000,,-b=4096,-f=512,-i=560,-c=3,-m=0,nosuid,nodev,nosymfollow
schulze at telstra dot com dot not dot this dot bit
06-Jun-2004 07:10
Osmos
09-May-2004 09:13
Note to the massage from "setec at freemail dot it" (01-Mar-2004 01:41).
For more flexibility I suggest replacing the string
<?php
_safe_set ($parse_url["scheme"], "http");
?>
with the following one:
<?php
_safe_set ($parse_url["scheme"], $_SERVER["HTTPS"] ? "https" : "http");
?>
Afternoon
04-May-2004 03:28
I found a good solution to create a persistent session by storing a persistence flag, ironically, in the session itelf. I start the session (which sends a Set-Cookie with no expiry time), read the flag and then, if the user wants a persistent session, stop and restart the session with the expiry time set using session_set_cookie_params, which then sends a cookie with a good expiry time. This solution has been quickly tested with all major browsers and seems to work.
I have outlined the whole process in my blog: http://aftnn.org/journal/508
Rikahs Design
14-Apr-2004 03:10
When setting url_rewriter.tags parameter in php.ini, make sure that you put quotes around the string portion like this:
url_rewriter.tags = "a=href,area=href,frame=src,input=src,form=fakeentry"
or the PHP won't know what tags to insert the session id into. My web host has a relatively current version of PHP and they still didn't have this parameter configured by default.
nate at 8networks dot com
16-Mar-2004 01:16
Re: $_SESSION can be slooowwwww
Remember $_SESSION varibles are stored and read from a physical drive most of the time. Beside implementing a virtual drive configuration you can also use a faster drive or implement RAID to double access time on the drives you use now.
setec at freemail dot it
01-Mar-2004 04:41
This is a usefull code I have done that allows to make a redirection using headers with full support for sessions and HTTP 1.1.
<?php
function session_redirect ($url = "")
{
function _safe_set (&$var_true, $var_false = "")
{
if (!isset ($var_true))
{ $var_true = $var_false; }
}
$parse_url = parse_url ($url);
_safe_set ($parse_url["scheme"], "http");
_safe_set ($parse_url["host"], $_SERVER['HTTP_HOST']);
_safe_set ($parse_url["path"], "");
_safe_set ($parse_url["query"], "");
_safe_set ($parse_url["fragment"], "");
if (substr ($parse_url["path"], 0, 1) != "/")
{
$parse_url["path"] = dirname ($_SERVER['PHP_SELF']) .
"/" . $parse_url["path"];
}
if ($parse_url["query"] != "")
{ $parse_url["query"] = $parse_url["query"] . "&"; }
$parse_url["query"] = "?" . $parse_url["query"] .
session_name () . "=" .
strip_tags (session_id ());
if ($parse_url["fragment"] != "")
{ $parse_url["fragment"] = "#" . $parse_url["fragment"]; }
$url = $parse_url["scheme"] . "://" . $parse_url["host"] .
$parse_url["path"] . $parse_url["query"] .
$parse_url["fragment"];
session_write_close ();
header ("Location: " . $url);
exit;
}
?>
spagmoid at yahoo dot NOSPAMcom
13-Dec-2003 05:24
WARNING: Yet another dangerous/possibly faulty thing has been added to the session handler, without adequate explanation of it's effects.
referer_check sounds like a great idea - but if you don't understand what it really does, your site could have problems that are very difficult to track down. Especially if you have 2 sites that link back and forth. Consider this: you have a user logged in, happily enjoying a cookie-based session. He clicks on a link to another site. He then clicks a link that returns him to your site, and finds that he is locked out. His session has been reset, even though the SID was not in the URL, it was safely in a cookie. Now consider that he had another browser window open, filling out a 5-page form. When he submits, it will all be lost. A combination of factors on my site has resulted in 10% of new signups being completely LOCKED OUT the last few weeks. For now, DO NOT USE referer_check.
You could easily write your own, that only checks the URL/POST for the session info, rather than the cookie. Then you would also be able to log when it happens. I think this "feature" should be removed - sessions are too important and fragile to be toyed around with.
dan
06-Dec-2003 01:34
If you understand how sessions work in PHP, here's a FREE (GNU) and very well coded custom session handler "package" for use with MySQL. This is extremely useful if you want PHP to handle sessions using a MySQL database, ie, you want to overcome the "slooowww" access to $_SESSION with default settings, you like the idea of custom session handling but are too lazy to set it up (like me =)), you are hosted on a shared server and need session info secured, you'd like to see a really well coded sample of how to take advantage of custom session handling, etc...
The documentation is minimal, so read up on the session.* variables, explore the code, and have fun with it!
http://www.cheetah-soft.com/csh/
To those using a third-party web host, I suggest that you disable persistant connections. Also, note that after going through the "Class Configuration" on the website, the options you selected are very easy to change in the custom generated configuation file.
Thanks to Cheetah Soft, Inc for making it available under GNU!
gzink at zinkconsulting dot com
03-Dec-2003 05:57
[Editors note: I've just benchmarked this, and over a 100 element array the results are as follows: (average over 10 runs)
Standard Array: 0.102ms
$_SESSION: 0.197
This is in the extremely unlikely case of having to loop through 100 elements in a session variable. Remember, if you have that many elements in your session, something is wrong.]
A small warning! $_SESSION can be slooowwwww....
I've never heard of this, but it turns out $_SESSION is much slower than any regular array, even an exact copy of $_SESSION. Copying large amounts of data in/out of $_SESSION is seriously slow and each access to $_SESSION is noticeably slower than regular arrays.
The lesson I learned? Don't use $_SESSION in loops that run very much. Even copying data from $_SESSION before the loop won't help a lot if there's a lot of data there due to a delay that can be pretty hefty, almost equal to working directly on $_SESSION with foreach() and actually slower than working directly on $_SESSION if you need to put the data back in the array in my experience. It's better to pass the data another way if possible, i.e. save the SQL query and re-run, store in a database, etc.
Just a warning for those who may be using this array in medium to large loops or trying to pass lots of data. I hope it saves you the hours of optimizing I've had to spend!
-Galen
http://www.zinkconsulting.com/
pautzomat at web dot de
19-Nov-2003 03:05
Be aware of the fact that absolute URLs are NOT automatically rewritten to contain the SID.
Of course, it says so in the documentation ('Passing the Session Id') and of course it makes perfectly sense to have that restriction, but here's what happened to me:
I have been using sessions for quite a while without problems. When I used a global configuration file to be included in all my scripts, it contained a line like this:
$sHomeDirectory = 'http://my.server.com/one/of/my/projects'
which was used to make sure that all automatically generated links had the right prefix (just like $cfg['PmaAbsoluteUri'] works in phpMyAdmin). After introducing that variable, no link would pass the SID anymore, causing every script to return to the login page. It took me hours (!!) to recognize that this wasn't a bug in my code or some misconfiguration in php.ini and then still some more time to find out what it was. The above restriction had completely slipped from my mind (if it ever was there...)
Skipping the 'http:' did the job.
OK, it was my own mistake, of course, but it just shows you how easily one can sabotage his own work for hours... Just don't do it ;)
zombie (at) localm (dotto) oh - arr-gee
09-Aug-2003 07:42
I don't know if this is obvious or not, but since it took me forever to figure it out, i will post it...
<?
ini_set("session.cookie_domain",".artattack.to");
session_start();
print_r($_SESSION);
?>
This will allow cookies/session info to be available to artattack.to as well as its Cnames (ex: www.artattack.to, zombie.artattack.to, squirrel.nut.artattack.to)
All this does is set the domain attribute of the set_cookie() style function sessions use since a "session" is just a cookie on your computer that php looks for that contains your session id.
I assume, therefor that you can do something of the like for cookies in javascript and such.
The silly thing about all this is that it is a "feature" of cookies to be able to span c names/subdomains. This is exactly why set_cookie() has an option domain argument. However, it seems like most of the people have had my problem have not gone in that direction or at least not posted a correct solution on the web. Google just gave me lots of hacked solutions. In my quest, i read articles about apache hacks, setting the serverside session storage folder, using file() from a sub on a file doing a print_r on the session located ont he main server, etc etc. I guess if you really know how cookies work (which i thought i did before all this mess but obviously not) then this problem seems like not much of a problem at all and a simple missunderstanding of what cookies do and why they are cool.
Wizards vs Hackers.
I hope this helps someone.
--
Blaine
webmaster of the art attack
http://artattack.to
orion at dr-alliance dot com
08-Aug-2003 06:52
Session ID's wont be carried over through meta refreshes, so make sure you add the variables (in GET format) to the URL.
IE )
<meta http-equiv=\"refresh\" content=\"1;URL=index.php?PHPSESSID=$PHPSESSID\">
quinn at strangecode dot com
19-Mar-2003 05:10
Do not 'global' a superglobal! If you register a $_SUPERGLOBAL as a global variable (as in... global $_SESSION; within a function definition) strange things happen with some versions of PHP (PHP 4.2.3 on my MacOS X powerbook, but not my PHP 4.2.3 RH 7.3 linux machine). In the case I found, $_SESSION and $HTTP_SESSION_VARS would not reference the same data, and unsetting or accessing the data was inconsistant. Didn't test very far, but obviously this should not be done, and it did wreck havoc for me.
tim at digicol dot de
04-Feb-2003 01:14
Be careful when using ini_set to change the session.gc_maxlifetime value locally for your script:
You will trash other people's sessions when garbage collection takes place (and they will trash yours) regardless of their (your) intended session.gc_maxlifetime, because the session_name is not taken into account during garbage collection.
Create an own directory and set session.save_path to it, so that your session files don't get mixed.
nutbar at innocent dot com
17-Jan-2003 05:44
Someone posted a message here saying you should just all use the MM shared memory management for sessions. I'd like to CAUTION EVERYONE against using it!
I run a few webservers for a webhosting company, and we quickly ran in to PHP pages segfaulting Apache for unknown reasons, until we did a test with sessions. It turns out that the sessions, while using the mm stuff, couldn't keep the data right. I guess it was to do with the file locking issue mentioned in the documentation here (I didn't notice this until now!).
Anyways, if you run a Unix machine that can map virtual memory to a mount point (like tmpfs or shm or whatever it may be called), use this instead. It's volatile like mm, but works. Only thing you don't get is hidden session info so that other people don't know how to open it easily - but it's better than trying to use mm and having the webserver crash all the time!
jules at dsf dot org dot uk
16-Jan-2003 04:13
There are a few comments above about how using sessions might not be secure, but quite apart from session hijacking, there is a mistake that I think a lot of people are making at the moment that everyone needs to stop and make sure they aren't one.
This mistake arises from having the 'register_globals' setting on.
Take the following example code which is meant to maintain a session variable for whether a user is logged in and allow them to log in using a username and password if they aren't logged in, or give an option for logging out if they are:
<?php
session_register ("logged_in");
if (!strcmp($user, "user") && !strcmp($pass, "password"))
$logged_in = 1;
if ($logout)
$logged_in = 0;
if ($logged_in)
echo "logged in. <A href=\"sestest.php?logout=1\">log out</A>";
else
echo "<FORM action=sestest.php method=get>User: <INPUT type=text name=user><BR>Password: <INPUT type=text name=pass><BR><INPUT type=submit></FORM>";
?>
This works fine under normal use, but an attacker can log in without knowing the username or password by accessing '.../sestest.php?logged_in=1', which will set the session variable 'logged_in' to the value 1.
However, once a session variable has been set, it cannot be overridden in this fashion, so one solution is to use code like the code shown above (which has no explanation attached as to why you should do it that way) that uses session_is_registered:
<?php
session_start ();
if (!session_is_registered ("logged_in"))
{
$logged_in = 0;
session_register ("logged_in");
}
...
?>
thebitman at attbi dot com
16-Dec-2002 03:01
[Editor's Note] Locking a session to an IP address will sometimes result in valid user's sessions not being restored. ISPS sometimes use more than one proxy server, the ISP may direct the traffic through a different proxy on each request[/Note]
The easiest (and therefor, most vulnerable) method of validating a session is to just keep a copy of the REMOTE_IP in $_SESSION, and compare it at the beginning of your script. Of course this doesnt prevent someone from blindly sending things to your server and getting no reply, but I think it will do a pretty good job of preventing someone from hijacking your session in order to get ahold of an order confirmation page that has your address and CC# on it.
As a general rule: Keep track of your users. NEVER allow POST data for things like online purchases without making sure that the last page they were on is the page that should be making that POST (and I dont mean checking the referer: header. This kind of thing is what the _SESSION variable can be good for storing)
Jester at free2code dot net
17-Nov-2002 05:50
It seems quite a lot of people have trouble understanding what sessions do and what they're good for.
For a more newbie explanation our tutorial might help you:
http://www.free2code.net/tutorials/programming/php/4/sessions.php
I tried to expplain how to use sessions in as simple terms as possible, for anyone having trouble understanding this page, give it a go.
jmgonzal_NOSPAM_at_NOESPAM_netred_DOT_cl
12-Oct-2002 06:43
If you have problem to download a file from your PHP , and you have IE (any version) and apache for server with SSL, check the reference of: session-cache-limiter
My best solution is change the php.ini from
session.cache_limiter = nocache
to:
session.cache_limiter = private, must-revalidate
twocandles3000@hotmail
14-May-2002 02:34
Storing class instances in session.
As long as a class MUST be declared BEFORE the session starts and unserializes the session info, i'm using this approach.
0: Set in php.ini session.auto_start = 0
1: create myclass.inc where the class is declared.
2: put in another file, say header.inc, this lines of code:
include_once( "myclass.inc" );
session_start();
3: set in php.ini the auto_prepend_file= "path_to_my_file/header.inc"
Following this steps, the session is started at every page and myclass is always available, avoiding to write the session_start() function at every page.
stoiev at ig dot com
20-Mar-2002 12:10
Carefull when you are working in PHP with WML. The arg separator used to put de PHPSESSID variable in URL is '&' by default, and this cause a Compile Error in browsers:
<anchor><go href="index.php?estate=1&PHPSESSID=12345678abcde"></go>
instead of this:
<anchor><go href="index.php?estate=1&PHPSESSID=12345678abcde"></go>
Itīs safety include the line:
ini_set ( "arg_separator", "&");
to change the arg separator, it worked in PHP 4.1.2
Another thing that the onpick tag is not defined in the url_rewriter.tags list by default(if there are others, i donīt now). This is must be added in php.ini file.
* In most case the WAP GateWay accepts cookies an the auto-transpass-SID is not necessary, itīs hard to find problems with this.
j dot marloweNOSPAM at gmx dot NO_SPAM dot net
11-Feb-2002 05:47
ricmarques at spamcop dot net
15-Oct-2000 08:16
Regarding session.cache_limiter :
For those of you who - like me - had trouble finding the meaning of the possible values (nocache, public and private), here's the explaination taken from the HTTP 1.1 Specification at
http://www.w3.org/Protocols/rfc2068/rfc2068
"14.9.1 What is Cachable
[snip]
public
Indicates that the response is cachable by any cache, even if it would normally be non-cachable or cachable only within a non-shared cache. (See also Authorization, section 14.8, for additional details.)
private
Indicates that all or part of the response message is intended for a single user and MUST NOT be cached by a shared cache. This allows an origin server to state that the specified parts of the response are intended for only one user and are not a valid response for requests by other users. A private (non-shared) cache may cache the response.
Note: This usage of the word private only controls where the response may be cached, and cannot ensure the privacy of the message content.
no-cache
Indicates that all or part of the response message MUST NOT be cached anywhere. This allows an origin server to prevent caching even by caches that have been configured to return stale responses to client requests.
Note: Most HTTP/1.0 caches will not recognize or obey this directive."
shanemayer42 at yaho | |