PHP : questions

(Cliquez-ici pour accéder à la version originale de cette discussion avec couleurs et images)







Posted by: lapras

Bonjour,
j'ai plusieurs questions pour le langage PHP :

-Comment faire qu'une page soit uniquement accessible en include, c'est a dire que si dans fichier.php j'inclus fichier2.php alors le fichier "fichier2.php" ne peut pas etre executé si on entre : "http://monsite.com/fichier2.php"
Donc que le fichier ne puisse etre exécuté que grace a mon include dans fichier.php
(je sais, je peux faire ca avec des "if" mais je voulais savoir si une fonction existait)

-Supprimer toutes les variables a la fin d'un script est il vraiment utile ?
la fonction unset possede elle un attribut "all" (pour toutes les variables, sauf les sessions bien sur)

Merci d'avance
Lapras



Posted by: anima

Citation:
Posté par lapras
Bonjour,
j'ai plusieurs questions pour le langage PHP :

-Comment faire qu'une page soit uniquement accessible en include, c'est a dire que si dans fichier.php j'inclus fichier2.php alors le fichier "fichier2.php" ne peut pas etre executé si on entre : "http://monsite.com/fichier2.php"
Donc que le fichier ne puisse etre exécuté que grace a mon include dans fichier.php
(je sais, je peux faire ca avec des "if" mais je voulais savoir si une fonction existait)

Il n'y a malhereusement pas de fonction telle que celle que tu demande

Citation:
-Supprimer toutes les variables a la fin d'un script est il vraiment utile ?
la fonction unset possede elle un attribut "all" (pour toutes les variables, sauf les sessions bien sur)

Pas a la fin du script, non, vu qu'elles s'enlevent de toutes facons des que PHP a fini d'éxécuter ton code.



Posted by: lapras

Merci !



Posted by: Patastronch

Tu peux simuler aussi. Dans la page qui include tu instancies une variable blabla, et dans la page inclue tu vérifie si la variable blabla est instanciée avec la bonne valeur. C'est la façon la plus simple pour ce genre de chose (utile quand on veut faire du MVC clean), y en a d'autres de bien plus propres mais parfois inutilement compliquées quand ça n'a pas besoin d'être sécurisé.



Posted by: lapras

J'ai utilisé une variable et j'ai fait un "if" tout bête ;)
Dommage c'est pas tres propre mais bon...



Posted by: fatal_error

Bonjour,
Citation:
Dans la page qui include tu instancies une variable blabla, et dans la page inclue tu vérifie si la variable blabla est instanciée avec la bonne valeur


Jolie méthode et fluide. Moi qui utilisait des noms tarabiscotés pour certaines pages...



Posted by: eusebius

Citation:
Posté par lapras
J'ai utilisé une variable et j'ai fait un "if" tout bête ;)
Dommage c'est pas tres propre mais bon...

Pourquoi est-ce que tu ne trouves pas ça propre ? C'est la manière standard pour éviter les inclusions multiples en langage C, par exemple. C'est paramétrable à l'envi, et si tu ne programmes pas comme un cochon (et si ton PHP est bien configuré) tu peux garantir que la variable ne vient pas de l'utilisateur.



Posted by: anima

Citation:
Posté par eusebius
Pourquoi est-ce que tu ne trouves pas ça propre ? C'est la manière standard pour éviter les inclusions multiples en langage C, par exemple. C'est paramétrable à l'envi, et si tu ne programmes pas comme un cochon (et si ton PHP est bien configuré) tu peux garantir que la variable ne vient pas de l'utilisateur.

Pourquoi utiliser une variable? Perso, si le besoin se fait sentir de sécuriser l'inclusion (ce qui n'arrive jamais, vu que je sécurise toujours mes inclusions a l'avance: choix délimité), j'utilise un define(). Ca me permet d'etre certain que,, sur tout serveur, le systeme sera sécurisé.



Posted by: Patastronch

Citation:
Posté par eusebius
Pourquoi est-ce que tu ne trouves pas ça propre ? C'est la manière standard pour éviter les inclusions multiples en langage C, par exemple. C'est paramétrable à l'envi, et si tu ne programmes pas comme un cochon (et si ton PHP est bien configuré) tu peux garantir que la variable ne vient pas de l'utilisateur.


Euh, je pense pas que ce soit comparable avec le C, les variable d'include dans le C sont gérées par le précompilateur et ne generont jamais l'execution du programme.

Mais je suis d'accord pour dire que c'est pas specialement crado, ni spécialement sous-optimale quand on voit les autres solution réalisables, non c'est plus les problèmes de sécurités qui sont génant. Tu dis que tu peux t'assurer que la variable ne viens pas d'un utilisateur ? et moi je dis que dans le 3/4 des sites amateur les injections de code (et donc de variables instanciées) se font tres facilement uniquement parceque les gens ne comprennent pas l'utilité de la fonction addslash (et donc ne l'utilisent pas).

Tiens ca me fait penser a une petite blague en bd :

http://kyosukenobaka.free.fr/img/kn...ts_of_a_mom.png

Enfin bon, de toute facon quand on veut faire un truc sécurisé on fait pas du php, le php c'est bien trop chiant a configurer !



Posted by: eusebius

Citation:
Posté par anima
si le besoin se fait sentir de sécuriser l'inclusion (ce qui n'arrive jamais, vu que je sécurise toujours mes inclusions a l'avance: choix délimité)

Tu veux dire quoi exactement, tu peux détailler ?
Citation:
Posté par anima
j'utilise un define()

Oui, c'est sans doute mieux que le coup de la variable.

Citation:
Posté par Patastronch
Tu dis que tu peux t'assurer que la variable ne viens pas d'un utilisateur ? et moi je dis que dans le 3/4 des sites amateur les injections de code (et donc de variables instanciées) se font tres facilement uniquement parceque les gens ne comprennent pas l'utilité de la fonction addslash (et donc ne l'utilisent pas).

C'est ce que je voulais dire (plus ou moins) par "si tu ne programmes pas comme un cochon" : isolation et validation de toutes les entrées.

Citation:
Posté par Patastronch
Enfin bon, de toute facon quand on veut faire un truc sécurisé on fait pas du php, le php c'est bien trop chiant a configurer !

Oué, faites du prolog !



Posted by: lapras

J'ai une autre question :
comment faire pour qu'u utilisateur ne se logue pas sur deux ordinateurs différents simultanément et sur le meme compte ?
On peut toujours comparer les IP dans mysql mais c'est trop lourd comme méthode, en avez vous une autre ?



Posted by: Patastronch

Citation:
Posté par lapras
J'ai une autre question :
comment faire pour qu'u utilisateur ne se logue pas sur deux ordinateurs différents simultanément et sur le meme compte ?
On peut toujours comparer les IP dans mysql mais c'est trop lourd comme méthode, en avez vous une autre ?


Tu utilises quoi pour gerer la connexion ? Les variables de sessions je présume ?
Dans ce cas te suffit de regénérer une session lorsqu'elle est deja ouverte pour un identifiant unique. Exemple naif :
Dans ta variable de session tu stock l'id de l'user. Si au moment de la connexion y adeja une variable de session avec une id identeique tu la détruit et tu la recrée pour la nouvelle connexion. Y a plus fin comme facon de faire, je te donne l'idée seulement. Une telle technique te permet d'assurer l'unicité de la connexion pour un compte précis.

Sinon y a aussi les methode par cookie qui peuvent t'assurer seulement l'unicité d'une connexion par machine. C'est a dire qu' a la connexion tu verifies si y a deja un cookie provenant de ton serveur présent sur l'ordi. Une telle technique te permet d'assurer l'unicité de la connexion pour une machine précise (en fait non, pour un navigateur précis sur une machine précise).

Y a plusieurs techniques possible, mais innutile de tout mettre, ca dépend vraiment de tes besoin parceque la gestion d'unicité quelque soit le domaine (connexion, identification ...) est quelque chose de lourd a gérer quoiqu'il arrive.



Posted by: Patastronch

Citation:
Posté par eusebius
Oué, faites du prolog !


J'ai jamais essayé de faire un site en prolog mais ca doit pas etre de la tarte :p



Posted by: Patastronch

Citation:
Posté par eusebius
C'est ce que je voulais dire (plus ou moins) par "si tu ne programmes pas comme un cochon" : isolation et validation de toutes les entrées.


L'ennuie c'est que meme les informaticiens codent comme des porcs :p Pour ca que je suis toujours etonné de voir que c 'est le php qui domine alors que c'est un des rares langages ou faut tout gérer soit meme pour atteindre un niveau sécurité acceptable (et je parle pas du coté pragrammation crado de ce langage).

Sincerement je conseille aux gens qui se mettent au php de se mettre plutot soit au struts/hibernate (si il savent faire de la POO, c'est du java) soit ruby on rails (si vous n'avez jamais vraiment programmé, ca a ete concu pour faire du MVC, de l'ajax, de code clean et sécurisé et tout ca de maniere tres simple).



Posted by: eusebius

Citation:
Posté par Patastronch
J'ai jamais essayé de faire un site en prolog mais ca doit pas etre de la tarte :p

Ya un truc qui s'appelle "prolog server pages" je crois (à ne pas confondre avec "python server pages"), je fantasme dessus mais je n'ai jamais essayé...



Posted by: lapras

Oui j'utilise les sessions.
Mais je ne vois pas trop ce que tu veux dire.
Comment puis je savoir si une variable de session contenant le meme id est crée ?



Posted by: Patastronch

Citation:
Posté par lapras
Oui j'utilise les sessions.
Mais je ne vois pas trop ce que tu veux dire.
Comment puis je savoir si une variable de session contenant le meme id est crée ?

Ben en fait t'as rien a faire, ca sert a ca une session :)
quand tu fais start_session, ca regarde deja si une session est active avec le visiteur, si elle est active alors il s'en sert, sinon il en cré une.

Donc si ton but est d'assurer une connexion unique par identité c'est la ou ça deviens compliqué, il faut interdire la création des sessions ayant les même instanciations de variables. Mais cela est très coûteux (il faut parcourir toutes les sessions et la comparer avec celle qu'on veut créer). Comment faire ? Une variable de session c 'est rien d'autre qu'un fichier ... defaut de cette facon de faire => gros traitement pour autoriser une connexion.
Autre façon de faire plus maligne, a la connexion ajouter dans la db le numéro de session utilisé pour l'identité et sa date de péremption qu'on met a jour a chaque clic de l'utilisateur. Et lorsque l'user essai de creer la connexion avec une identité deja connectée alors tu compares les numéros de sessions pour autoriser oui ou non la connexion. Défaut de cette facon de faire => chaque clic doit etre vérifié par ce traitement ce qui est tres lourd.

Mais je doute sincèrement qu'il existe des cas ou on ait besoin d'assurer l'unicité de la session pour un identifiant donne. Expose ton problème plutot, je suis presque sur qu'il n'y a pas besoin d'unicité de la connexion pour résoudre ton problème. D'ailleurs il te suffit d'ouvrir IE et firefox et de te connecter avec le même login sur le même site. tu verras qu'aucun site n'a jamais eu besoin (enfin pas a ma connaissance) d'assurer l'unicité de la connexion.



Posted by: lapras

Je comprend mieux, mais ca revient a faire une requete par clique c'est lourd...
En fait voila mon probleme :
je fais une page php, chaque joueur a un unique id et a de l'argent (virtuel). Il peut par exemple acheter un article dans un magasin (virtuellement bien sur), donc je regarde si la session['argent'] est >= au prix de l'article, je fait l'achat donc je modifie sa session['argent'] et son argent dans la bdd.
Supposons que le joueur a dépensé TOUT son argent dans cet article , il a donc $0
Imaginons que je demande a un ami de se connecter en meme temps que moi sur mon compte sur un ordi différent. Alors sur l'ordinateur B (celui de l'ami), la session['argent'] est égale a celle a la connection donc si il va sur la page du magasin, il a une session['argent'] suffisante pour acheter l'article (meme si dans la BDD argent=0)
donc du coup il va acheter l'article et il va avoir de l'argent dans les négatifs

On me dira : je peux toujours vérifier si il a assez d'argent en faisant une requete a Mysql, mais c'est une requete de plus, et je souhaite économiser les requetes.

Merci d'avance



Posted by: Patastronch

Citation:
Posté par lapras
Je comprend mieux, mais ca revient a faire une requete par clique c'est lourd...
En fait voila mon probleme :
je fais une page php, chaque joueur a un unique id et a de l'argent (virtuel). Il peut par exemple acheter un article dans un magasin (virtuellement bien sur), donc je regarde si la session['argent'] est >= au prix de l'article, je fait l'achat donc je modifie sa session['argent'] et son argent dans la bdd.
Supposons que le joueur a dépensé TOUT son argent dans cet article , il a donc $0
Imaginons que je demande a un ami de se connecter en meme temps que moi sur mon compte sur un ordi différent. Alors sur l'ordinateur B (celui de l'ami), la session['argent'] est égale a celle a la connection donc si il va sur la page du magasin, il a une session['argent'] suffisante pour acheter l'article (meme si dans la BDD argent=0)
donc du coup il va acheter l'article et il va avoir de l'argent dans les négatifs

On me dira : je peux toujours vérifier si il a assez d'argent en faisant une requete a Mysql, mais c'est une requete de plus, et je souhaite économiser les requetes.

Merci d'avance


Aucune variable sensible dans les sessions et les cookies ! Si l'argent est une donnée sensible dans ce cas la il ne faut surtout pas la stocker ni dans les sessions ni dans les cookies. Les sessions c'est assez sécurisé puisque seul le serveur y a acces en lecture, mais il est tres facile (a la hauteur de n'importe quel plouc qui a fait un peu d'informatique) de faire un script php par injection de code (ou directement par execution si t'es pas sur un serveur dedié) qui va lire (ou meme ecrire) les variables de session. Tu me diras qu'il y a le safe_mode mais ca n'affecte que le php donc rien n'empeche d'utliser un autre langage pour le script espion. La plupart des gros site stockent généralement les sessions dans la db directement pour éviter ce genre de probleme.

Les infos qu'on met dans une session doivent etre des infos mineurs, c 'est a dire uniquement des infos dont la publication/edition n'est pas problématique. Par exemple l'id, le pseudo, le nom ou l'age c 'est pas sensible. Par contre le mot de passe, les coordonnées bancaires c'est sensible et problématique si quelqu'un peut les lire ou les modifier.

Conclusion => oui faut faire une requete pour chaque lecture/modification de la variable d'argent !



Posted by: lapras

Mais alors ou les stocker ?
de plus j'ai fait attention aux injections de codes, en mettant des htmlspecialchars et en faisant attention pour tous les formulaires.
De toute facon session['argent'] ne me sert que pour afficher son argent mais la bdd est bien modifiée en faisant
update joueur set argent=argent - $prix_achat where id=".$_SESSION['id']."
EDIT : j'ai vu ton edit, donc je vais etre forcé de faire une requte, dommage ! (j'aime vraiment pas faire des requetes)



Posted by: Patastronch

Citation:
Posté par lapras
Mais alors ou les stocker ?
de plus j'ai fait attention aux injections de codes, en mettant des htmlspecialchars et en faisant attention pour tous les formulaires.
De toute facon session['argent'] ne me sert que pour afficher son argent mais la bdd est bien modifiée en faisant
update joueur set argent=argent - $prix_achat where id=".$_SESSION['id']."


L'affichage c 'est pas sensible, mais la lecture de la valeur pour vérifier si il a assez d'argent ainsi que la modification de la quantité d'argent doit toujours se faire par la db selon moi.

Utilise addslashes surtout pour eviter le SQL inject, sinon c'est ta db qui va devenir une vraie passoire.



Posted by: lapras

htmlspecialchars ne suffie pas pour eviter les injections ?



Posted by: Patastronch

Citation:
Posté par lapras
htmlspecialchars ne suffie pas pour eviter les injections ?


Je suis loin d 'etre un pro de la sécurité, mais on est jamais a l'abris des injections !
addslashes s'utilise sur toutes les données qui vont faire parti d'une requete SQL. Par exemple dans ton update ton $prix_achat moi je le fait passer par un addslashes avant (voir meme un intval).
mysql_real_escape_string peut aussi remplacer addslashes (la différence entre les 2 est que addslashes ne fait pas tout ce que fait mysql_real_escape_string)

htmlspecialchars j'utillise pas, je peux pas te dire ce qu'il empeche vraiment. Mais je crois que c'est comme htmlentities mais uniquement sur un sous-ensemble de balise.

htmlentities ca te permet d'eviter les injections de javascript ( et encore c'est vite dit ...).

De toute facon il ya toujours moyen de feinter des filtres (surtout si on sait lesquelles sont utilisé) pour faire passer du code dans une variable. Apres en utilisant les bon filtre au bon moment tu augemente cette difficulté et t'empeche qu'un gamin de 15 ans viennes te pourrir ton site.











-