|
|
 |
C. Sessions
Le support des sessions de PHP est un moyen de préserver
des données entre plusieurs accès. Cela vous permet de
créer des applications personnalisées, et d'augmenter
l'attrait de votre site.
Chaque visiteur accédant à votre page web se voit assigné un
identifiant unique, appelé "identifiant de session". Il peut
être stocké soit dans un cookie, soit propagé dans l'URL.
Le support des sessions vous permet d'enregistrer un
nombre illimité de variables qui doivent être préservées
entre les requêtes. Lorsqu'un visiteur accède à votre site,
PHP va vérifier automatiquement (si session.auto_start est
activé) ou sur demande (explicitement avec
session_start() ou implicitement avec
session_register()) s'il existe une
session du même nom. Si c'est le cas, l'environnement
précédemment sauvé sera recréé.
| Attention |
Si vous activé session.auto_start, alors vous ne pourrez pas enregistrer
d'objets dans votre session tant que la définition de la classe
ne sera pas chargée avant le début de la session, pour recréer les objets de votre session.
|
Toutes les variables sont sérialisées après l'exécution du
script PHP. Les variables qui sont indéfinies sont marquées
comme telles. Lors des accès ultérieurs, elles ne seront pas
définies, jusqu'à ce que l'utilisateur le fasse.
Note :
La gestion des sessions a été ajoutée en PHP 4.0.
Note :
Notez que lorsque vous travaillez avec les sessions, un enregistrement
dans la session ne sera pas créé tant que la variable ne sera pas enregistré
en utilisant la fonction session_register() ou en ajoutant
une clé à la variable super-globale $_SESSION.
Cela n'est vrai que si vous avez débuté une session en appelant la fonction
session_start().
Lien externe : Session fixation
Utiliser les sessions ne signifie pas que les données de session ne
pourront être vue que par un seul utilisateur. Il est important de
garder cela en tête, lorsque vous stockez et affichez des données
importantes. Lorsque vous stockez des données dans une session,
il faut se demander quels seront les problèmes posés si quelqu'un
d'autre accède à cette information, ou comment votre application
est affectée si la session est en fait celle d'un autre.
Par exemple, si quelqu'un usurpe une session, il peut alors poster
un message dans un forum sous une fausse identité. Quelle est la
gravité de ce problème? Ou bien, il peut accéder aux commandes
d'un client, et même, modifier son panier d'achat. A priori, c'est
moins problématique pour un fleuriste que pour un pharmacien.
Si vous voulez résoudre ce souci de façon simple, il peut être utile
d'activer session.use_only_cookies. Dans ce cas,
les cookies devront être activés par le client, sinon, les sessions ne fonctionneront pas.
Par conséquent, lorsque vous manipulez des données importantes,
il faut exploiter d'autres méthodes pour décider si une session
est valide ou pas. Les sessions ne fournissent pas une méthode
fiable d'authentification.
Les sessions reposent sur un identifiant de session, ce qui signifie
que quelqu'un peut voler cet identifiant, rien qu'en volant l'ID. Ce vol
peut être rendu très difficile, comme en utilisant les
cookies, mais en aucun cas cela sera impossible. Les sessions dépendent
aussi de la discipline de l'utilisateur qui referme son navigateur
à la fin de la session pour tout clore proprement.
De plus, même les cookies de session peuvent être
surveillés sur un réseau, ou bien notés par un proxy car ils transitent en clair
sur le réseau.
Pour remédier à cela, vous devriez implémenter un chiffrage SSL sur votre plate-forme.
Ces fonctions sont disponibles dans le module PHP
standard, qui est toujours accessible. Note :
Optionnellement, vous pouvez utiliser l'allocation de mémoire partagée (mm),
développé par Ralf S.Engelschall, pour stocker votre session.
Vous devez télécharger mm et l'installer.
Cette option n'est pas disponible pour les environnements Windows.
Notez que le module de stockage de session mm ne garantit pas
les verrous de sessions en cas d'accès multiples à la même session.
Il peut être moins approprié d'utiliser un système de fichiers
basé en mémoire partagée
(comme tmpfs sur Solaris/Linux ou /dev/md sur BSD) pour stocker les
sessions dans des fichiers, car ils ne seront pas proprement verrouillés.
Le support des sessions est activé par défaut. Si vous souhaitez
exclure le support des sessions de PHP, vous devez utiliser l'option
--disable-session lors de l'exécution
du script de configuration. Pour utiliser la mémoire vive pour le stockage
des sessions, compilez PHP avec l'option
--with-mm[=DIR] .
La version Windows de PHP
dispose du support automatique de cette extension. Vous n'avez pas à ajouter
de bibliothèque supplémentaire pour disposer de ces fonctions. Note :
Par défaut, toutes les données relatives à une session particulière seront
stockées dans un fichier du répertoire spécifié par session.save_path
dans les options du fichier php.ini. Un fichier pour chaque session sera créé.
Cela est dû au fait que une session est ouverte (un fichier est créé) mais
aucune donnée n'est écrite dans ce fichier.
Notez que ce comportement est un effet des limitations d'utilisation
du système de fichiers et il est possible qu'un gestionnaire de session
personnalisé (par exemple, un qui utilise une base de données)
ne garde aucune trace des sessions où aucune donnée n'y a été enregistrée.
Le comportement de ces fonctions est
affecté par la configuration dans le fichier php.ini.
Tableau 1. Options de configuration | Nom | Par défaut | Modifiable |
|---|
| session.save_path | "/tmp" | 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 | | 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 | | session.use_cookies | "1" | PHP_INI_ALL | | session.use_only_cookies | "0" | PHP_INI_ALL | | 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 | | session.bug_compat_42 | "1" | PHP_INI_ALL | | session.bug_compat_warn | "1" | PHP_INI_ALL | | session.hash_function | "0" | PHP_INI_ALL | | session.hash_bits_per_character | "4" | PHP_INI_ALL | | url_rewriter.tags | "a=href,area=href,frame=src,input=src,form=fakeentry" | PHP_INI_ALL |
Pour plus de détails sur les constantes PHP_INI_*,
reportez-vous à ini_set().
Le système de sessions dispose d'un grand nombre de directives
dans le fichier php.ini. En voici une présentation :
- session.save_handler
string
Définit le nom du gestionnaire
de session qui est utilisé pour stocker et relire les
données. Par défaut, c'est le système intégré
par fichiers : files. Voir aussi
session_set_save_handler().
- session.save_path
string
Définit le chemin qui doit être passé
au gestionnaire de sauvegarde. Si vous décidez de
choisir le gestionnaire par défaut (par fichier),
cet argument sera utilisé comme dossier de sauvegarde
des sessions. Par défaut, il vaut /tmp.
Voir aussi session_save_path().
Il y a un argument optionnel N à cette directive qui détermine
la profondeur de répertoires où votre fichier de session sera stocké.
Par exemple, si vous définissez '5;/tmp', votre fichier
sera situé dans /tmp/4/b/1/e/3/sess_4b1e384ad74619bd212e236e52a5a174If
. Si vous voulez utiliser N, vous devez créer
tous ces répertoires avant de les utiliser. Un petit script shell existe dans
ext/session pour réaliser ces créations et il se nomme
mod_files.sh. Notez également que si N
est utilisé et est supérieur à 0, alors la routine automatique gc (garbage collection)
ne sera pas exécuté ; voir une copie de php.ini pour plus d'informations.
Egalement, si vous utilisez N, assurez vous d'entourer
session.save_path de "doubles guillemets" car le séparateur
(;) est également utilisé pour les commentaires dans
php.ini.
| Avertissement |
Si vous laissez cette option configurée avec un dossier
accessible en lecture à tout le monde, comme
/tmp (par défaut), les autres utilisateurs
pourront exploiter ces sessions en obtenant la liste de fichiers
dans ce dossier.
|
Note :
Les utilisateurs de Windows doivent changer cette valeur de variable
pour que les fonctions de sessions de PHP fonctionnent. Indiquez
un chemin de dossier valide, par exemple :
c:/temp.
- session.name
string
Spécifie le nom de la session,
qui sera utilisé comme nom de cookie. Il ne doit contenir que
des caractères alphanumérique. Par défaut, c'est
PHPSESSID.
Voir aussi session_name().
- session.auto_start
boolean
Spécifie si le module
de session doit démarrer automatiquement au début de
chaque script PHP. Par défaut, c'est 0
(désactivé).
- session.serialize_handler
string
Définit le nom
du gestionnaire qui est utilisé pour linéariser/délinéariser
les données. Actuellement, un format interne à PHP
(nommé php) et WDDX (nommé
wddx) sont supportés . WDDX est seulement
disponible, si PHP a été compilé avec l'option
WDDX. Par défaut, c'est php.
- session.gc_probability
integer
Spécifie la probabilité, exprimée en pourcentage, en conjonction de
session.gc_divisor, que la routine gc (garbage collection)
soit démarrée à chaque requête. La valeur par défaut est 1.
Voir session.gc_divisor pour plus de détails.
- session.gc_divisor
integer
session.gc_divisor en conjonction de
session.gc_divisor définie la probabilité que la routine gc
(garbage collection) soit démarré à chaque début de session.
La probabilité est calculé en utilisant gc_probability/gc_divisor, e.g
1/100 signifie qu'il y a 1% de chance pour que la routine gc démarre à chaque
requête. La valeur par défaut est 100.
- session.gc_maxlifetime
integer
Spécifie la durée de
vie des données sur le serveur, en nombre de secondes. Après
cette durée, les données seront considérées comme obsolètes,
et supprimées.
Note :
Si vous utilisez le gestionnaire de session par fichier,
qui est fourni par défaut votre système doit garder la trace des
dates de dernier accès aux fichier (atime). La FAT de Windows ne le
fait pas, alors il vous faudra trouver un autre système pour gérer
les sessions qui ont expirées. Depuis PHP 4.2.3, on utilise
mtime (date de modification) au lieu de atime.
Donc, vous n'aurez plus de souci avec les systèmes de fichiers qui ne gèrent
pas atime.
- session.referer_check
integer
Contient une sous-chaîne
que vous souhaitez retrouver dans tous les en-têtes HTTP Referer. Si
cet en-tête a été envoyé par le client, et que la sous-chaîne n'a pas
été trouvé, l'identifiant de session sera considéré comme invalide.
Par défaut, cette option est une chaîne vide.
- session.entropy_file
string
Est un chemin jusqu'à
une source externe (un fichier), qui sera utilisée comme source
additionnelle d'entropie pour la création de l'identifiant
de session. Des exemples valides sont /dev/random et
/dev/urandom, qui sont disponibles sur
tous les systèmes Unix.
- session.entropy_length
integer
Spécifie le nombre d'octets
qui seront lus dans le fichier défini ci-dessus. Par défaut, il
vaut 0, c'est à dire inactif.
- session.use_cookies
boolean
Spécifie si le module utilisera
les cookies pour stocker les données de session sur le client.
Par défaut, il vaut 1, c'est à dire actif.
- session.use_only_cookies
boolean
Spécifie si le module
doit utiliser seulement les cookies
pour stocker les identifiants de sessions du coté du navigateur. Par défaut,
cette option vaut 0 (inactif, pour compatibilité ascendante).
En l'activant, vous éviterez les attaques qui utilisent des
identifiants de sessions dans les URL. Cette configuration a été ajoutée
en PHP 4.3.0.
- session.cookie_lifetime
integer
Spécifie la durée de
vie du cookie en secondes. La valeur de 0
signifie : "Jusqu'à ce que le navigateur soit éteint".
La valeur par défaut est : 0. Voir aussi
session_get_cookie_params() et
session_set_cookie_params().
- session.cookie_path
string
Spécifie le chemin utilisé
lors de la création du cookie. Par défaut, il vaut /.
Voir aussi
session_get_cookie_params() et
session_set_cookie_params().
- session.cookie_domain
string
Spécifie le domaine utilisé
lors de la création du cookie. Par défaut, il ne vaut rien.
Voir aussi
session_get_cookie_params() et
session_set_cookie_params().
- session.cookie_secure
boolean
Spécifie que les cookies ne doivent être émis que sur des
connexion sécurisée. Par défaut, cette option est à
off. Cette option a été ajoutée en
PHP 4.0.4.
Voir aussi
session_get_cookie_params() et
session_set_cookie_params().
- session.cache_limiter
string
Spécifie le type de
contrôle de cache utilisé pour les pages avec sessions. Les
valeurs possibles sont :
none, nocache, private, private_no_expire, public. Par défaut, il vaut
nocache.
Voir aussi
session_cache_limiter().
- session.cache_expire
integer
Spécifie la durée de
vie des données de sessions, en minute. Cette option n'a aucune
conséquence sur le contrôle de cache. Par défaut, il vaut
180 (3 heures).
Voir aussi
session_cache_expire().
- session.use_trans_sid
boolean
Spécifie si le support du SID est transparent ou pas. Par défaut vaut 0
(désactivé).
Note :
En PHP 4.1.2 ou plus ancien, cette option est activée en utilisant
l'option de compilation
--enable-trans-sid.
Depuis PHP 4.2.0, cette option est toujours activée.
Le système de gestion des sessions par URL pose un risque
supplémentaire de sécurité : un utilisateur peut envoyer
son URL avec l'identifiant de session par email à un ami,
ou bien le mettre dans ses signets. Cela diffusera alors
l'identifiant de session.
- session.bug_compat_42
boolean
Les versions de PHP antérieures à la version 4.2.0
disposaient d'une
fonctionnalité/bogue non documentée, qui vous permettait
d'initialiser une variable de session dans le contexte global, même si
register_globals
était désactivé. PHP 4.3.0 et plus récent vous préviendra de l'utilisation
de cette fonctionnalité si vous avez aussi activé
session.bug_compat_warn.
- session.bug_compat_warn
boolean
Les versions de PHP antérieures à la version 4.2.0
disposaient d'une
fonctionnalité/bogue non-documentée, qui vous permettait d'initialiser
une variable de session dans le contexte global, même si
register_globals
était désactivé. PHP 4.3.0 et plus récent vous préviendra de l'utilisation
de cette fonctionnalité si vous avez activé
session.bug_compat_42
et session.bug_compat_warn.
- session.hash_function
integer
session.hash_function vous permet de spécifier la fonction
de hachage à utiliser pour générer les identifiants de session. '0' signifie
MD5 (128 bits) et '1' signifie SHA-1 (160 bits).
Note :
Cette directive a été ajoutée en PHP 5.
- session.hash_bits_per_character
integer
session.hash_bits_per_character vous permet de définir
le nombre de bits utilisés pour chaque caractère lors des conversions des
données binaires en éléments lisibles. Les valeurs possibles sont '4' (0-9,
a-f), '5' (0-9, a-v), et '6' (0-9, a-z, A-Z, "-", ",").
Note :
Cette directive a été ajoutée en PHP 5.
- session.url_rewriter.tags
string
Spécifie quels sont les balises HTML qui doivent
être réécrites si le support transparent du SID
est activé. Par défaut, il vaut
a=href,area=href,frame=src,input=src,form=fakeentry,fieldset=.
Note :
Si vous voulez vous conformer avec les spécifications XHTML, supprimer l'entrée
form et utiliser le tag <fieldset> autour de votre balise
form.
Les options track_vars et
register_globals
influencent le comportement des sessions, leur stockage et leur restauration.
Note :
Depuis PHP 4.0.3, track_vars est
toujours activé.
Cette extension ne définit aucune ressource. Ces constantes sont définies par cette
extension, et ne sont disponibles que si cette extension a été compilée avec
PHP, ou bien chargée au moment de l'exécution. - SID
(chaîne de caractères)
Constante contenant le nom de la session et l'identifiant en cours,
sous la forme "name=ID" ou une chaîne vide si l'identifiant de session
a été défini dans un cookie de session.
Note :
Depuis PHP 4.1.0, $_SESSION est disponible comme
variable globale, au même titre que $_POST,
$_GET, $_REQUEST, etc.
Contrairement à $HTTP_SESSION_VARS,
$_SESSION est toujours globale. Par conséquent, vous
n'avez pas besoin d'utiliser le mot réservé
global
avec $_SESSION. Notez que cette documentation
a été modifiée pour utiliser $_SESSION.
Vous pouvez toujours le remplacer par $HTTP_SESSION_VARS
si vous préférez l'ancienne version. Notez également vous devez démarrer votre session
en utilisant la fonction session_start() avant d'utiliser
la variable super-globale $_SESSION.
Les clés du tableau $_SESSION sont sujettes
aux mêmes limitations que les variables PHP habituelles, c'est à dire
qu'elles ne peuvent pas commencer par un nombre, mais commencer par
une lettre ou un souligné '_'. Pour plus de détails, reportez vous à
la section sur les variables.
Si track_vars est
activé et register_globals
est désactivé, seuls les éléments du tableau global
$_SESSION contiendront les variables
enregistrées dans la session. Les variables de sessions relues seront
uniquement disponibles dans $_SESSION.
L'utilisation de $_SESSION (ou
$HTTP_SESSION_VARS avec PHP 4.0.6 et plus ancien) est
recommandé pour une meilleure sécurité et un code plus facilement
entretenu. Avec $_SESSION, il n'y a pas besoin
d'utiliser les fonctions session_register(),
session_unregister() et
session_is_registered(). Les variables de sessions
sont accessibles comme toute autre variable.
Exemple 1.
Enregistrer une variable avec $_SESSION.
|
<?php
session_start();
if (!isset($_SESSION['compteur'])) {
$_SESSION['compteur'] = 0;
} else {
$_SESSION['compteur']++;
}
?>
|
|
Exemple 2.
Retirer une variable de session avec $_SESSION et register_globals inactif.
|
<?php
session_start();
unset($_SESSION['compteur']);
?>
|
|
| Attention |
N'utilisez PAS la fonction unset()
avec $_SESSION sous la forme
unset($_SESSION) sinon, cela rendra impossible d'enregistrement
de données dans la session en utilisant la super-globale
$_SESSION.
|
| Avertissement |
Vous ne pouvais pas utiliser les références sur des variables de session car il
n'y a aucune manière faisable de restaurer une référence vers une autre variable.
|
Exemple 3.
Retirer une variable de session avec $_SESSION et register_globals activé,
après l'avoir enregistré avec $_SESSION.
|
<?php
session_start();
session_unregister('compteur');
?>
|
|
Si register_globals
est activé, alors toutes les variables globales peuvent être
enregistrées comme variables de session, et toutes les variables de sessions
seront reconstituées comme variables globales. Comme PHP doit
savoir quels variables globales sont enregistrées comme variables
de sessions, l'utilisateur doit enregistrer les variables avec
session_register() tandis que
$HTTP_SESSION_VARS et $_SESSION
ne nécessitent pas session_register().
Exemple 4.
Enregistrer une variable avec
register_globals
activé
|
<?php
if (! isset($_SESSION['compteur'])) {
$_SESSION['compteur'] = 1;
} else {
$_SESSION['compteur']++;
}
?>
|
|
Si register_globals
est activé, alors les variables globales et les entrées dans le tableau
$_SESSION seront des références sur la même valeur pour
les valeurs qui auront été enregistrées avant le démarrage de la session
(donc, dans les page précédentes).
De plus, si vous enregistrez une nouvelle variable avec la fonction
session_register(), l'entrée dans l'environnement
globale et $_SESSION ne fera pas de référence vers la
même valeur jusqu'à la prochaine utilisation de
session_start() (ceci s'applique à PHP 4.2 est
avant seulement). C'est à dire qu'une modification dans les variables
globales ne seront pas répercutés dans les entrées de $_SESSION.
Il est peu probable que cela ait un impact en pratique, et de plus,
cela a été corrigé en PHP 4.3.
Il y a deux méthodes de propagation de l'identifiant de session :
Le module de session supporte les deux méthodes. Les cookies sont
optimaux, mais comme ils ne sont pas sûrs (tous les internautes
ne les acceptent pas), ils ne sont pas fiables. La seconde
méthode place l'identifiant de session directement dans les URL.
PHP est capable de faire cela de manière transparente, lorsqu'il est compilé
avec l'option
--enable-trans-sid. Si vous activez
cette option, les URL relatives seront modifiées pour contenir
l'identifiant de session automatiquement. Alternativement,
vous pouvez utiliser la constante SID, qui est
définie, si le client n'a pas envoyé le cookie approprié.
SID est soit de la forme
session_name=session_id ou une chaîne vide.
Note :
L'option arg_separator.output
de php.ini vous permet de personnaliser le séparateur d'arguments.
Pour être complètement en accord avec les spécifications XHTML, spécifiez
& ici.
Alternativement, vous pouvez utiliser la constante SID qui est toujours
définie. Si le client n'envoie pas un cookie de session approprié, il aura la forme
session_name=session_id.
Sinon, il vaudra une chaîne vide. Ainsi, vous pouvez dans tous les cas l'inclure dans l'URL.
L'exemple suivant vous montre comment enregistrer une variable et comment
réaliser un lien correct avec une autre page, avec SID.
Exemple 5. Compter le nombre de passages d'un utilisateur sur une page |
<?php
if (!session_is_registered('compteur')) {
session_register('compteur');
$compteur = 1;
} else {
$compteur++;
}
?>
<p>
Bonjour visiteur, vous avez vu cette page <?php echo $compteur; ?> fois.
</p>
<p>
Pour continuer, <a href="nextpage.php?<?php echo strip_tags(SID); ?>">cliquez ici</a>.
</p>
|
|
La fonction strip_tags() est utilisé lors de l'affichage du
SID dans le but de contrer les attaques XSS.
L'affichage du SID, comme montré dans l'exemple ci-dessus, n'est pas nécessaire
si
--enable-trans-sid a été utilisé pour compiler PHP.
Note :
Les URL non-relatives sont considérées comme externes au site, et ne
recevront pas le SID, car c'est une fuite d'information vers un autre
site (envoi d'informations importantes).
Pour implémenter un stockage en base de données, ou toute autre méthode,
vous aurez besoin de la fonction session_set_save_handler() pour
paramétrer vos propres fonctions de stockage.
Michael Wells
22-Nov-2004 06: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 05: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 08:54
irm at in3activa dot com
13-Sep-2004 08: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
10-Sep-2004 02: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 07: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 08: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 05: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 10: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 01:10
Osmos
09-May-2004 03: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 09: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 09: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 07: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 10: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 11: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 07: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 11: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 09: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
10-Aug-2003 01: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
09-Aug-2003 12: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 11: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 07: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 11: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 10: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 09: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 11: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
13-Oct-2002 12: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 08: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 06: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 11:47
ricmarques at spamcop dot net
16-Oct-2000 02: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 yahoo dot com
20-Aug-2000 04:11
Session Garbage Collection Observation:
It appears that session file garbage collection occurs AFTER the current session is loaded.
This means that:
even if session.gc_maxlifetime = 1 second,
if someone starts a session A and no one starts a session for an hour, that person can reconnect to session A and all of their previous session values will be available (That is, session A will not be cleaned up even though it is older than gc_maxlifetime).
| |