Discussion:
Passage php4 vers php5
(trop ancien pour répondre)
Yannick
2009-04-06 09:36:36 UTC
Permalink
Bonjour,

N'étant pas très doué je n'arrive pas à modifié les 3 scripts suivants.
Il fonctionne très bien sous php4 mais rien à faire sous php5.
1) la recherche ne se fait pas
2) l'affichage dans le pop est vide

Merci à celui qui voudras bien me résoudre cet incident.

Amitiés

Début des scripts

INDEX.PHP

<?php /* echo "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?".">"; */?>
<?
//INCLUSION DU FICHIER DE CONNEXION
include("connect.inc");

//CONNEXION A LA BASE
$mysql_id=mysql_connect($server,$user,$pwd);

// Sortir du script en cas de problème de connexion
//au serveur.
if(!$mysql_id){
echo "Problème de connexion à la base : ".mysql_errno().":
".mysql_error()."<br />";
exit;
}

//SELECTION DE LA BASE
mysql_select_db($base,$mysql_id);

//SELECTION DE LA TABLE
$table = 'FP_Complet';

//CONSTRUCTION DE LA CLAUSE 'WHERE'
if ($nom){ // Si un nom est inscrit dans le formulaire
$where=" WHERE nom LIKE '%".$nom. "%'";
if ($prenom){ // Si le prénom est aussi renseigné
$where=" WHERE nom='".$nom."' AND prenom LIKE '%".$prenom. "%'";
}
}
else{ // Les deux champs sont vides
$where="";
}

//CONSTRUCTION DE LA CLAUSE 'LIMIT'
//Nombre d'enregistrements souhaités par page
$nb_par_page=10;

if (!$page){
$ligne_debut=0;
}
else{
$page=$page-1;
$ligne_debut=$page*$nb_par_page;
}

$limit=" LIMIT ".$ligne_debut.", ".$nb_par_page;

//REQUETE SQL
$qry="SELECT * FROM $table".$where." ORDER BY nom " .$limit;
//echo $qry;

//EXECUTION DE LA REQUETE
$result=mysql_query($qry);

$nb_pages=($nb_fiches_max/$nb_par_page);
$nb_pages=ceil($nb_pages);

//CALCUL DU NOMBRE DE PAGES

if (!$nb_pages) { // Si le nb de pages n'a encore jamais été calculé

if ($nom){
$nb_fiches_max=mysql_num_rows($result);
}
else{
$qry2="SELECT * FROM $table";
//echo $qry2;
$result2=mysql_query($qry2);
$nb_fiches_max=mysql_num_rows($result2);
}
$nb_pages=($nb_fiches_max/$nb_par_page);
$nb_pages=ceil($nb_pages);
}

// MESSAGE AU DESSUS DU TABLEAU
if ($nb_fiches_max > 0){ //S'il y a au moins un résultat
$page=$page+1;
$msg= "page ".$page." sur ".$nb_pages; //On affiche le nombre de
pages sur le total
}
else{
$msg="Désolé, aucun enregistrement trouvé !"; //Sinon, on signale
qu'il n'y a pas de résultats
}
?>

<!DOCTYPE php PUBLIC "-//W3C//DTD Xphp 1.1//EN"
"http://www.w3.org/TR/xphp11/DTD/xphp11.dtd">
<php xmlns="http://www.w3.org/1999/xphp" xml:lang="fr">
<head>
<title>Fonctionnaires</title>
<meta http-equiv="Content-Type" content="text/php; charset=iso-8859-1" />
<style type="text/css">

body{
background-color:#ffffff;
font-family: Trebuchet MS,Verdana,Geneva,Arial,Helvetica,sans-serif;
}
table.result{
font-family:Arial,sans-serif;
border-collapse:collapse;
border:1px solid #333333;
margin-top:10px;
width:780px;
text-align: center;
}
td.nom {
padding:5px;
width: 200px;
border:1px solid #333333;
text-align: center;
background-color:#087417;
color:#ffffff;
}
td.prenom {
padding:5px;
width: 250px;
border:1px solid #333333;
text-align: center;
background-color:#087417;
color:#ffffff;
}
td {
border:1px solid #333333;
padding:3px;
text-align: left;
}
span.page{
padding-left: 10px;
}
div.pages{
text-align: center;
padding-top: 5px;
}
</style>
</head>
<div align="center">
<body bgcolor="#E7FFB3"><h1>Les fonctionnaires dans les registres</h1>
Vous trouverez ici les donn&eacute;es de fonctionnaires vues dans
les registres.<br>
<strong>Pourquoi cette base?</strong><br>
Le fait que les fonctionnaires soient appelés à se déplacer les rends
difficilement localisables.<br>
<br>
</div><center>
<?
##########################
# Recherche infos pour affichage des infos completes

$r=mysql_query("SELECT id FROM $table ORDER by id DESC LIMIT 1 " );
while($row =mysql_fetch_array($r))
{
echo ("<b><p>Il y a "); ?>
<font color="#006599">
<? echo (" $row[id] "); ?>
</font>
<? echo (" entrées dans la base <br> "); }

//$r=mysql_query("SELECT nom, id FROM $table ORDER by id LIMIT 1 ");
// while($row =mysql_fetch_array($r))
// {
// echo ("Pour "); ?>
<font color="#006599">
<? // echo (" $row[id] "); ?>
</font>
<?// echo (" patronymes dans la base<br></b>"); }
?>


<!-- FORMULAIRE -->
<form action="FP_adh.php" method="get" class="page">
<table align="center" style="border:0px;">
<tr>
<td style="border:0px;">NOM</td>
<td style="border:0px;"><input type="text" name="nom"
value="<?echo $nom?>" /></td>
<td style="border:0px;">Prénom</td>
<td style="border:0px;"><input type="text" name="prenom"
value="<?echo $prenom?>" /></td>
<td style="border:0px;"><input type="submit" name="submit"
value="Rechercher" /></td>
</tr>
</table>
</form>

</div>
<!-- FIN FORMULAIRE -->
<br><br>
Interrogez la base par départements<br>
<a href="FP_cartes.php">Lieux des registres</a><br>
<a href="FP_cartes_n.php">Lieux de naissances</a><br>
Lieux de décès à l'étude
<br>
<?php
echo "<br />\n"; //On passe une ligne
include ('../../Pied_page.php'); ?>
</center>
</body>
</html>



<?php /* echo "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?".">"; */?>
<?php
//INCLUSION DU FICHIER DE CONNEXION
include("connect.inc");

//CONNEXION A LA BASE
$mysql_id=mysql_connect($server,$user,$pwd);

// Sortir du script en cas de problème de connexion
//au serveur.
if(!$mysql_id){
echo "Problème de connexion à la base : ".mysql_errno().":
".mysql_error()."<br />";
exit;
}

//SELECTION DE LA BASE
mysql_select_db($base,$mysql_id);

//SELECTION DE LA TABLE
$table = 'FP_Complet'; // Le nom de cette table ne passe pas chez Sivit !

//CONSTRUCTION DE LA CLAUSE 'WHERE'
if ($nom){ // Si un nom est inscrit dans le formulaire
$where=" WHERE Nom LIKE '%". $nom. "%'";
if ($prenom){ // Si le prénom est aussi renseigné
$where=" WHERE nom='". $nom."' AND prenom LIKE '%".$prenom. "%'";
}
}
else{ // Les deux champs sont vides
$where="";
}

//CONSTRUCTION DE LA CLAUSE 'LIMIT'
//Nombre d'enregistrements souhaités par page
$nb_par_page=50;

if (!$page){
$ligne_debut=0;
}
else{
$page=$page-1;
$ligne_debut=$page*$nb_par_page;
}

$limit=" LIMIT ".$ligne_debut.", ".$nb_par_page;

//REQUETE SQL
$qry="SELECT * FROM $table".$where." ORDER BY nom " .$limit;
//echo $qry;

//EXECUTION DE LA REQUETE
$result=mysql_query($qry);

$nb_pages=($nb_fiches_max/$nb_par_page);
$nb_pages=ceil($nb_pages);

//CALCUL DU NOMBRE DE PAGES

if (!$nb_pages) { // Si le nb de pages n'a encore jamais été calculé

if ($nom){
$nb_fiches_max=mysql_num_rows($result);
}
else{
$qry2="SELECT * FROM $table";
//echo $qry2;
$result2=mysql_query($qry2);
$nb_fiches_max=mysql_num_rows($result2);
}
$nb_pages=($nb_fiches_max/$nb_par_page);
$nb_pages=ceil($nb_pages);
}

// MESSAGE AU DESSUS DU TABLEAU
if ($nb_fiches_max > 0){ //S'il y a au moins un résultat
$page=$page+1;
$msg= "page ".$page." sur ".$nb_pages; //On affiche le nombre de
pages sur le total
}
else{
$msg="Désolé, aucun enregistrement trouvé !"; //Sinon, on signale
qu'il n'y a pas de résultats
}
?>

<!DOCTYPE php PUBLIC "-//W3C//DTD Xphp 1.1//EN"
"http://www.w3.org/TR/xphp11/DTD/xphp11.dtd"><head>
<title>Fonctionnaires</title>

<center><h1>Les fonctionnaires dans les registres</h1></center>
<?php
echo $msg."\n"; // On écrit le message au dessus du tableau
?>


<!-- EN-TÊTES DU TABLEAU -->
<center>
Pour obtenir les informations complètes vous devez accepter les 'pop-up'
de ce site<br><br>
Cliquez sur la ligne de votre choix.
<link rel="stylesheet" href="base_resultat.css" type="text/css">

<table class="result">
<tr>
<td class="nom"><strong><font size="3">Nom</font></strong></td>
<td class="prenom"><strong><font size="3">Prénom</font></strong></td>
<td class="date_N"><strong><font size="3">Date
Naissance</font></strong></td>
<td class="lieu_N"><strong><font size="3">Lieu
Naissance</font></strong></td>
<td class="dpt_N"><strong><font size="3">Département
Naissance</font></strong></td>
</tr>

<!-- FIN EN-TÊTES DU TABLEAU -->

<!-- REMPLISSAGE DU TABLEAU -->

<?php
while($row=mysql_fetch_object($result)){
echo "<tr style=\"cursor: hand;\"
onmouseover=\"this.style.backgroundColor='#6C81B9'\"
onmouseout=\"this.style.backgroundColor = ''\"
onclick=\"javascript:window.open('pop_FP_adh.php?id=$row->id&choixpop_FP_adh','width=480,height=300,left=0,top=0,toolbar=no,menubar=no,resizable=no,scrollbars=yes');return(false)\">\n";
echo "<td>$row->nom</td>\n";
echo "<td>$row->prenom</td>\n";
echo "<td>$row->date_n</td>\n";
echo "<td>$row->lieu_n</td>\n";
echo "<td>$row->dpt_n</td>\n";
echo "</tr>\n";
}
?>

</table>
</center>
<!-- FIN REMPLISSAGE DU TABLEAU -->
</div>

<!-- LIENS VERS LES AUTRES PAGES -->
<div align="center" class="pages">
<?php
$i=0;
while ($i <= $nb_pages-1):
$j=$i+1;
if ((!$nom) AND (!$prenom)){
echo "<span class=\"page\"><a
href=\"FP_adh.php?page=".$j."&nb_pages=".$nb_pages."\">".$j."</a></span>\n";
}
else if (($nom) AND ($prenom)) {
echo "<span class=\"page\"><a
href=\"FP_adh.php?page=".$j."&nb_pages=".$nb_pages."&nom=".$nom."&prenom=".$prenom."\">".$j."</a></span>\n";
}
else{
echo "<span class=\"page\"><a
href=\"FP_adh.php?page=".$j."&nb_pages=".$nb_pages."&nom=".$nom."\">".$j."</a></span>\n";
}
$i++;
endwhile;
?>
</div>
<!-- FIN LIENS VERS LES AUTRES PAGES -->
<?php
echo "<br />\n"; //On passe une ligne
include ('../../Pied_page.php'); ?>
</body>
</html>




<?
//INCLUSION DU FICHIER DE CONNEXION
include("connect.inc");

//CONNEXION A LA BASE
$mysql_id=mysql_connect($server,$user,$pwd);

// Sortir du script en cas de problème de connexion
//au serveur.
if(!$mysql_id){
echo "Problème de connexion à la base : ".mysql_errno().":
".mysql_error()."<br />";
exit;
}

//SELECTION DE LA BASE
mysql_select_db($base,$mysql_id);

//SELECTION DE LA TABLE
$table = 'FP_Complet'; // Le nom de cette table ne passe pas chez Sivit !

//REQUETE SQL
$qry="SELECT * FROM $table WHERE id='".$id."'";
//echo $qry;

//EXECUTION DE LA REQUETE
$result=mysql_query($qry);

//AFFECTATION DES VALEURS RENVOYEES AUX VARIABLES
while($row=mysql_fetch_object($result)){
$adh_nom_prenom=$row->adh_nom_prenom;
$adh=$row->adh;
$depot=$row->depot;
$dpt_depot=$row->dpt_depot;
$cote=$row->cote;
$prenom=$row->prenom;
$date_n=$row->date_n;
$lieu_n=$row->lieu_n;
$dpt_n=$row->dpt_n;
$titre=$row->titre;
$nom=$row->nom;
$profession=$row->profession;
$acte=$row->acte;
$qualite=$row->qualite;
$date_acte=$row->date_acte;
$description=$row->description;
$commentaire=$row->commentaires;
}

//DECLARATIONS DES FONCTIONS RIGHT ET LEFT QUI N'EXISTENT PAS EN PHP !
function left($chaine,$num) {
return substr($chaine,0,$num);
}

function right($chaine,$num) {
return substr($chaine,-$num);
}
?>


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr">
<head>
<title>Fonctionnaires</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<style type="text/css">

body{
background-color:#FEE7FE;
font-family: Trebuchet MS,Verdana,Geneva,Arial,Helvetica,sans-serif;
}
span.bold{
font-weight: bold;
}
a:link {
color: #0A42A7;
text-decoration:underline;
padding-right: 6px;
padding-left: 6px;
}
a:visited {
color: #0A42A7;
text-decoration:underline;
padding-right: 6px;
padding-left: 6px;
}
a:hover{
text-decoration:none;
color:#0A42A7;
padding-right: 6px;
padding-left: 6px;
}
</style>
</head>
<body bgcolor="#FFDFFC">
<div align="center"><h1>Les fonctionnaires dans les registres</h1>
<h3 style="text-align: center">Ensemble des informations sur</h3>
<h2 style="text-align: center;"><? echo $nom." ".$prenom;?></h2>
<? //dépôt?>
<div style="padding-left: 15px;"><span class="bold">Dépôt :
</span><span><? echo $depot." ".$dpt_depot;?></span></div>

<hr width="50%" />
<?
//Cote
if ($cote){
echo "<div style=\"padding-left: 15px;\"><span class=\"bold\">Cote du
document: </span><span>$cote</span></div>";
}

//Titre
if ($titre){
echo "<div style=\"padding-left: 15px;\"><span class=\"bold\">Titre du
document: </span><span>$titre</span></div>";
}
?>
<hr width="50%" />
<?
//Profession
if ($profession){
echo "<div style=\"padding-left: 15px;\"><span
class=\"bold\">Profession: </span><span>$profession</span></div>";
}

//LIGNE NAISSANCE
if (($date_n) AND ($lieu_n) AND ($dpt_n)) { // Si le lieu et la date de
naissance sont présents
echo "<div style=\"padding-left: 15px;\"><span class=\"bold\">Né le
</span><span>$date_n</span><span class=\"bold\"> à
</span><span>$lieu_n</span> (<span>$dpt_n</span>)</div>";
}
else if (($date_n) AND (!$lieu_n) AND ($dpt_n)){ // Si la date de
naissance est présente mais pas le lieu
echo "<div style=\"padding-left: 15px;\"><span class=\"bold\">Né le
</span><span>$date_n</span> dans le <span>$dpt_,</span></div>";
}
else if ((!$date_n) AND ($lieu_n) AND ($dpt_n)){ // Si le lieu est
présent sans la date de naissance (si ça existe ;-))
echo "<div style=\"padding-left: 15px;\"><span class=\"bold\">Né à
</span><span>$lieu_n</span> (<span>$dpt_n</span>)</div>";
}

// Type acte
if ($acte){
echo "<div style=\"padding-left: 15px;\"><span class=\"bold\">Type
d'acte: </span><span>$acte</span></div>";
}

// Date de l'acte
if ($date_acte){
echo "<div style=\"padding-left: 15px;\"><span class=\"bold\">Date de
l'acte: </span><span>$date_acte</span></div>";
}

// Qualité
if ($qualite){
echo "<div style=\"padding-left: 15px;\"><span class=\"bold\">Qualité:
</span><span>$qualite</span></div>";
}
?>
<hr width="50%" />
<?

// Description
if ($description){
echo "<div style=\"padding-left: 15px;\"><span
class=\"bold\">Description de
l'acte:<br></span><span>$description</span></div>";
}

// Commentaires
if ($commentaire){
echo "<div style=\"padding-left: 15px;\"><span
class=\"bold\">Commentaires:</span><br><span>$commentaire</span></div>";
}
?>
<hr width="50%" />
<div align="center"><font size="-2">Informations relevées par: <? echo
$adh_nom_prenom;?></font>
</div>
<br>
<? include('../../Pied_page.php');?>
</body>
</html>
Olivier Miakinen
2009-04-06 10:10:47 UTC
Permalink
Bonjour,
Post by Yannick
N'étant pas très doué je n'arrive pas à modifié les 3 scripts suivants.
Il fonctionne très bien sous php4 mais rien à faire sous php5.
1) la recherche ne se fait pas
2) l'affichage dans le pop est vide
Tu as un message d'erreur ? Par ailleurs ce serait bien que tu nous
donnes une URL pour qu'on puisse se rendre compte par nous-mêmes où ça
coince, MAIS PAS TOUT DE SUITE ! En tout premier lieu, il faudrait que
tu vérifies, au cas où connect.inc contiendrait des identifiants de
connection (mot de passe...), qu'il ne soit pas accessible directement
par http://...chemin.d.accès.../connect.inc !
Post by Yannick
<?
Tu autorises les « balises courtes » (short tags en anglais) ? Si oui,
c'est OK. Sinon, il faut écrire « <?php ».
Post by Yannick
//INCLUSION DU FICHIER DE CONNEXION
include("connect.inc");
ACHTUNG ! C'est une habitude très dangereuse de mettre un fichier avec
identifiants de connexion dans l'arborescence accessible directement
depuis l'extérieur, qui plus est avec une extension différence de .php
(et donc le risque qu'il soit présenté en clair à l'appelant au lieu
d'être exécuté).
Post by Yannick
//CONNEXION A LA BASE
[...]
Je ne lis pas tout, c'est bien trop long.
Post by Yannick
<!DOCTYPE php PUBLIC "-//W3C//DTD Xphp 1.1//EN"
"http://www.w3.org/TR/xphp11/DTD/xphp11.dtd">
;-)

Joli DOCTYPE. Il y a des navigateurs qui le comprennent ?
Post by Yannick
<php xmlns="http://www.w3.org/1999/xphp" xml:lang="fr">
Intéressant. Quel est le Content-Type transmis avec ce fichier dans les
entêtes HTTP ?
Post by Yannick
<head>
<title>Fonctionnaires</title>
<meta http-equiv="Content-Type" content="text/php; charset=iso-8859-1" />
Ah... (???)
Post by Yannick
[...]
</html>
Je n'ai pas loupé une étape ? C'est bien l'élément ouvert par <php> qui
est fermé par </html> ? Bon, j'ai peut-être un peu trop coupé : essaye
de nous mettre les fichiers un par un sur un site tel que cjoint.com par
exemple afin que ce soit plus clair.
Post by Yannick
[...]
Bon, je ne cite pas le reste, il y a déjà fort à faire avec ce qui
précède (mais si l'une de mes remarques t'a semblé pertinente, bien sûr
tu peux la reporter dans les autres fichiers).

Cordialement,
--
Olivier Miakinen
Yannick
2009-04-06 20:14:08 UTC
Permalink
Post by Yannick
Bonjour,
Bon, je ne cite pas le reste, il y a déjà fort à faire avec ce qui
précède (mais si l'une de mes remarques t'a semblé pertinente, bien sûr
tu peux la reporter dans les autres fichiers).
Cordialement,
Bonjour,

Tes remarques sont pertinentes et je modifierais les fichiers en
conséquences.
Non je n'ai pas de message d'erreur

voici les deux URL à tester
http://fp.voyeaud.org:81/ pour le php5
http://fp.voyeaud.org/ pour le php4

Le php4 marche mais pas le php5
Teste avec 'ma' en Nom tu comprendras ce qui ne colle pas

Merci de prendre le temps de m'aider.
--
Yannick VOYEAUD
Denis Beauregard
2009-04-07 14:51:04 UTC
Permalink
Post by Yannick
Post by Yannick
Bonjour,
Bon, je ne cite pas le reste, il y a déjà fort à faire avec ce qui
précède (mais si l'une de mes remarques t'a semblé pertinente, bien sûr
tu peux la reporter dans les autres fichiers).
Cordialement,
Bonjour,
Tes remarques sont pertinentes et je modifierais les fichiers en
conséquences.
Non je n'ai pas de message d'erreur
voici les deux URL à tester
http://fp.voyeaud.org:81/ pour le php5
http://fp.voyeaud.org/ pour le php4
Le php4 marche mais pas le php5
Teste avec 'ma' en Nom tu comprendras ce qui ne colle pas
De façon évidente, les paramètres n'arrivent pas à destination.

Je ferais une intégration de tous les fichiers en un fichier
unique et affichage des données intermédiaires pour voir où les
données se perdent.


Denis
Eric Demeester
2009-04-07 21:27:15 UTC
Permalink
dans (in) fr.comp.lang.php, Denis Beauregard
Post by Denis Beauregard
De façon évidente, les paramètres n'arrivent pas à destination.
C'est aussi mon avis, d'autant plus après avoir testé les versions php4
et 5 des pages proposées par Yannick.

Je persiste à penser qu'il y a un problème de configuration entre php4
et php5, et que ce problème concerne register_globals.
--
Eric
Yannick
2009-04-07 23:21:43 UTC
Permalink
Post by Eric Demeester
Je persiste à penser qu'il y a un problème de configuration entre php4
et php5, et que ce problème concerne register_globals.
Re,

Je pense que tu as raison!
C'est bien pour cela que j'ai mis TOUS les éléments de compréhension du
problème en diffusant le code des 3 pages concernées.

L'un des modérateurs m'a suggéré une page que je suis allé voir et je ne
suis pas sûr d'avoir bien compris:

À chaque fois que j'ai une ligne de type URL je dois mettre juste avant
$toto=$_REQUEST['toto']
où toto est la variable utilisée dans l'adresse url après le '?' et ce
quelque soit leur nombre cad si mon url contient un & pour dire de
prendre une seconde variable je dois faire le même rajout pour la
seconde variable

Hors apparemment ce n'est pas totalement exact selon un autre modérateur!

Que dois-je faire?

Au passage une bonne poignée de main à l'ami Denis du Québec.

Amitiés
--
Yannick VOYEAUD
Eric Demeester
2009-04-06 14:10:08 UTC
Permalink
dans (in) fr.comp.lang.php, Yannick <***@voyeaud.org> ecrivait (wrote) :

Bonjour,
Post by Yannick
N'étant pas très doué je n'arrive pas à modifié les 3 scripts suivants.
Il fonctionne très bien sous php4 mais rien à faire sous php5.
1) la recherche ne se fait pas
2) l'affichage dans le pop est vide
INDEX.PHP
[...]
Post by Yannick
//CONSTRUCTION DE LA CLAUSE 'WHERE'
if ($nom){ // Si un nom est inscrit dans le formulaire
D'où sort $nom ?
Post by Yannick
<!-- FORMULAIRE -->
<form action="FP_adh.php" method="get" class="page">
Le nom est donc envoyé en GET au script suivant.

Tout ça me fait penser à un problème de transfert de variables d'un
script à l'autre. Si register_globals est à On en PHP4 et à Off en PHP5,
(à vérifier dans un phpinfpo()), il est normal que plus rien ne
fonctionne.

Pour voir si le problème vient de là, essaye ça en début du script qui
traite le formulaire :

$nom = "";
if (isset($_REQUEST['nom']) & !empty($_REQUEST['nom'])) {
$nom = $_REQUEST['nom'];
echo 'Nom : ' . $nom . '<br />';
} else {
echo 'Le problème est ailleurs...<br />';
}

Si le nom s'affiche, tu as trouvé la solution.

Voir : http://www.manuelphp.com/php/ini.register-globals.php

Bon courage.
--
Eric
Yannick
2009-04-07 21:27:15 UTC
Permalink
Post by Eric Demeester
Tout ça me fait penser à un problème de transfert de variables d'un
script à l'autre. Si register_globals est à On en PHP4 et à Off en PHP5,
(à vérifier dans un phpinfpo()), il est normal que plus rien ne
fonctionne.
Pour voir si le problème vient de là, essaye ça en début du script qui
$nom = "";
if (isset($_REQUEST['nom']) & !empty($_REQUEST['nom'])) {
$nom = $_REQUEST['nom'];
echo 'Nom : ' . $nom . '<br />';
} else {
echo 'Le problème est ailleurs...<br />';
}
Si le nom s'affiche, tu as trouvé la solution.
Voir : http://www.manuelphp.com/php/ini.register-globals.php
Bon courage.
Bonsoir,

Oui lorsque j'ai rajouté tes lignes et mis 'ma' dans le formulaire il
m'a été affiché Nom : ma
et ensuite il m'a affiché la même page ne répondant pas à ce critère

donc si je te suis c'est ce type de problème
Comment je le résoud dans mon script? Je n'ai pas accès à la modif vers
ON ce qui d'ailleurs ne semble pas recommandé de faire.

La variable $nom que tu me signale en début de script est réellement
crée à partir du formulaire

Amitiés
--
Yannick VOYEAUD
Eric Demeester
2009-04-08 15:54:30 UTC
Permalink
dans (in) fr.comp.lang.php, Yannick <***@voyeaud.org> ecrivait (wrote) :

Bonjour Yannick,
Post by Yannick
Oui lorsque j'ai rajouté tes lignes et mis 'ma' dans le formulaire il
m'a été affiché Nom : ma
et ensuite il m'a affiché la même page ne répondant pas à ce critère
C'est parce qu'il faut appliquer le même traitement à toutes les
variables passées à ton script. Il reste peut-être d'autres erreurs,
mais il faut procéder par élimination...
Post by Yannick
donc si je te suis c'est ce type de problème
Comment je le résoud dans mon script? Je n'ai pas accès à la modif vers
ON ce qui d'ailleurs ne semble pas recommandé de faire.
Mieux vaut laisser register_globals à Of pour des raisons de sécurité,
effectivement.

Je vais essayer de t'expliquer le mécanisme...

Dans un formulaire, tu as :

- une script de destination (action="traitement.php") ;
- une méthode de transmission des données (GET ou POST) ;
- une succession de champs (nom, prenom, etc.) ;
- un bouton d'envoi (submit) provoquant l'appel à la page de
destination.

Voir par exemple :
http://www.siteduzero.com/tutoriel-3-13596-les-formulaires.html#ss_part_1
pour des explications détaillées.

Pour utiliser les variables (le contenu des champs du formulaire) dans
le script de destination, il faut d'abord les récupérer, car avec
register_global à Off, elles ne sont pas directement disponibles, mais
contenues dans un tableau ($_GET ou $_POST).

On fait cela au début du script, avant d'effectuer des traitements sur
les variables, selon la syntaxe que je t'indiquais.

// initialisation des variables (non indispensable mais
// je trouve ça plus propre)
$nom = "";
$prenom = "";

// récupération des variables. j'utilise $_REQUEST qui permet de
// récupérer indifféremment les variables passées et GET ou en
// POST, mais chacun ses goûts ;)

// Le nom
// On vérifie que la variable existe et est non vide
if (isset($_REQUEST['nom']) & !empty($_REQUEST['nom'])) {
$nom = $_REQUEST['nom'];
}

// Le prénom
if (isset($_REQUEST['prenom']) & !empty($_REQUEST['prenom'])) {
$prenom = $_REQUEST['prenom'];
}

L'opération est à renouveler pour toutes les variables transmises,
qu'elles soient contenues dans un formulaire ou passées directement dans
l'URL.

S'il n'y a pas d'autres erreurs, ton script devrait s'exécuter
correctement.
--
Eric
Yannick
2009-04-08 21:43:54 UTC
Permalink
Post by Eric Demeester
Pour utiliser les variables (le contenu des champs du formulaire) dans
le script de destination, il faut d'abord les récupérer, car avec
register_global à Off, elles ne sont pas directement disponibles, mais
contenues dans un tableau ($_GET ou $_POST).
On fait cela au début du script, avant d'effectuer des traitements sur
les variables, selon la syntaxe que je t'indiquais.
Bonsoir,

En ayant vraiment souffert je crois avoir trouvé!
C'est à mettre, $nom=$_REQUEST['nom'], avant le traitement de la requête
SQL de la page qui va recevoir les informations.

J'ai renommé mes fichiers en index_2.php pour tester et je crois que
cela marche. Il ne resterait plus que les bas de pages à traiter de la
même façon.

Pour récapituler je ne touche pas à index.php mais je tritures
FP_adh.php et Pop_FP_Adh.php

Où puis-je faire passer les deux copies (avant et après) pour servir à
d'autres. Je ne dois sûrement pas être le seul à avoir ce soucis de
passage 'forcé' de php4 à php5?

Amitiés
Eric Demeester
2009-04-09 09:28:06 UTC
Permalink
dans (in) fr.comp.lang.php, Yannick <***@voyeaud.org> ecrivait (wrote) :

Bonjour,
Post by Yannick
En ayant vraiment souffert je crois avoir trouvé!
C'est à mettre, $nom=$_REQUEST['nom'], avant le traitement de la requête
SQL de la page qui va recevoir les informations.
Oui.

Tu peux généraliser à tout passage de variables entre scripts en
respectant cet ordre :

1. on initialise les variables
2. on les récupère via $_REQUEST en vérifiant au passage si elles
existent et sont non vides)
3. on effectue les traitements associés aux variables (interrogation
de la base de données ou tout autre traitement)
4. on affiche les résultats
Post by Yannick
J'ai renommé mes fichiers en index_2.php pour tester et je crois que
cela marche. Il ne resterait plus que les bas de pages à traiter de la
même façon.
Même principe que ci-dessus, il faut récupérer les variables et les
traiter _avant_ de les afficher. Après, l'endroit et l'ordre dans
lequels elles seront affichées dans la page importe peu...
Post by Yannick
Pour récapituler je ne touche pas à index.php mais je tritures
FP_adh.php et Pop_FP_Adh.php
index.php envoie des informations à telle ou telle page, elles sont
récupérées dans la page de destination, ensuite on applique l'ordre
indiqué ci-dessus, peu importe le nom de la page (ou du script) de
destination, c'est généralisable à la quasi-totalité des cas.
Post by Yannick
Où puis-je faire passer les deux copies (avant et après) pour servir à
d'autres. Je ne dois sûrement pas être le seul à avoir ce soucis de
passage 'forcé' de php4 à php5?
Le fait d'avoir rencontré ce problème lors du passage de php4 à php5 est
un cas particulier que tu as rencontré. La plupart des hébergeurs que je
connais ont imposé register_globals à Off dès php4, c'est d'ailleurs je
crois sa configuration par défaut.

La vraie difficulté est de comprendre les effets de register_globals sur
le comportement de PHP en terme de transmission d'informations entre
pages, c'est très largement documenté dans des tutoriels disponibles en
ligne. L'essentiel est que tu ais compris le mécanisme et résolu ton
problème. Inutile je pense, compte tenu du grand nombre de sites
traitant déjà de cela, d'écrire une documentation supplémentaire, même
si cette proposition t'honore :)

Amicalement,
--
Eric
Yannick
2009-04-09 12:22:42 UTC
Permalink
Bonjour,
Post by Eric Demeester
La vraie difficulté est de comprendre les effets de register_globals sur
le comportement de PHP en terme de transmission d'informations entre
pages, c'est très largement documenté dans des tutoriels disponibles en
ligne. L'essentiel est que tu ais compris le mécanisme et résolu ton
problème. Inutile je pense, compte tenu du grand nombre de sites
traitant déjà de cela, d'écrire une documentation supplémentaire, même
si cette proposition t'honore :)
Dire que j'ai compris est bien grand mot!
J'ai résolu un problème c'est tout.
Cela marche sur cette table maintenant je vais faire du copié-collé pour
toutes mes autres tables.

Quant à la documentation elle existe belle et bien mais faite par des
spécialistes pour des spécialistes!
Si vraiment elle avait été faite pour des novices je n'aurais
probablement jamais posé la question car j'aurais trouvé la solution à
mon problème.
A noter que le lien que tu m'as indiqué est meilleur que les autres sur
ce point.

Je fais de l'entraide dans d'autres domaines et il me parait important
de transmettre ce que je sais en étant le plus proche possible en
langage de celui qui démarre.
Lorsque je fais un mode opératoire c'est du pas à pas cad un clic égale
un commentaire écrit. Je préfère 50 lignes inutiles car je suis sûr que
l'information est complète et peut être comprise de quiconque.

Amitiés
--
Yannick VOYEAUD
Eric Demeester
2009-04-09 14:35:24 UTC
Permalink
dans (in) fr.comp.lang.php, Yannick <***@voyeaud.org> ecrivait (wrote) :

Bonjour,
Post by Yannick
Dire que j'ai compris est bien grand mot!
Mais si tu verras, avec le temps ça rentrera. On a tous débuté...
Post by Yannick
Cela marche sur cette table maintenant je vais faire du copié-collé pour
toutes mes autres tables.
Attention au copié-collé, ça aide parfois, mais si on ne comprend pas au
moins un peu ce qu'on fait, ça peut être dangereux...
Post by Yannick
Quant à la documentation elle existe belle et bien mais faite par des
spécialistes pour des spécialistes!
On trouve de tout, mais il est vrai que les références « officielles »
de PHP ne sont pas forcément évidentes à assimiler, surtout quand on
débute.
Post by Yannick
A noter que le lien que tu m'as indiqué est meilleur que les autres sur
ce point.
Si tu parles de http://www.siteduzero.com, même s'il est parfois décrié
par les puristes, je trouve qu'il est très didactique, tout est expliqué
pas à pas. C'est l'idéal quand on débute, ou pour trouver un exemple
simple quand on a comme moi (la vieillesse est un naufrage) des trous de
mémoire.

Je te conseille si tu as le temps, de suivre les cours de PHP proposés
sur ce site. C'est progressif, simple, plein d'exemples pour faire des
tests, et des QCM permettent à la fin de chaque chapitre de vérifier
l'acquisition des connaissances.
Post by Yannick
Lorsque je fais un mode opératoire c'est du pas à pas cad un clic égale
un commentaire écrit.
C'est une excellente habitude de commenter au maximum ce qu'on écrit.
Cela permet de se relire facilement et ça aide, du moins en mon cas, à
mémoriser.

Bon courage pour la suite !
--
Eric
Mickael Wolff
2009-04-09 19:34:23 UTC
Permalink
Post by Eric Demeester
Si tu parles de http://www.siteduzero.com, même s'il est parfois décrié
par les puristes, je trouve qu'il est très didactique, tout est expliqué
pas à pas. C'est l'idéal quand on débute, ou pour trouver un exemple
simple quand on a comme moi (la vieillesse est un naufrage) des trous de
mémoire.
Il n'est pas décrié, il est honnis. Les imprécisions et les mauvaises
pratiques en font une source de médiocrité constante/
Post by Eric Demeester
Je te conseille si tu as le temps, de suivre les cours de PHP proposés
sur ce site. C'est progressif, simple, plein d'exemples pour faire des
tests, et des QCM permettent à la fin de chaque chapitre de vérifier
l'acquisition des connaissances.
Je n'ai jamais compris en quoi les QCM sont une méthode fiable de
sondage des connaissances. En plus, ils sont souvent faux sur ce site.
Post by Eric Demeester
C'est une excellente habitude de commenter au maximum ce qu'on écrit.
Cela permet de se relire facilement et ça aide, du moins en mon cas, à
mémoriser.
C'est une très mauvaise idée de commenter excessivement. Il faut
commenter à point nommé, ce qui est nécessaire.
--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org
Yannick
2009-04-09 23:38:55 UTC
Permalink
Post by Mickael Wolff
Post by Eric Demeester
C'est une excellente habitude de commenter au maximum ce qu'on écrit.
Cela permet de se relire facilement et ça aide, du moins en mon cas, à
mémoriser.
C'est une très mauvaise idée de commenter excessivement. Il faut
commenter à point nommé, ce qui est nécessaire.
Bonsoir,

Ce qui est important c'est de savoir ce qui se passe à tel ou tel moment
dans le script.
En conséquence un pro n'a pas besoin de commentaires car il sait mais un
amateur en a besoin pour repérer rapidement ses commandes et les actions
qu'elles sont sensées faire.
Un programme bien documenté et bien commenté est réutilisable par une
autre personne. Un programme non commenté EST illisible donc mieux vaut
trop que pas assez.

Si je m'en sort c'est bien parce que mon code, bien que pas génial pour
les puristes, est commenté en abondance.
Certes il y a beaucoup à dire sur le travail que j'ai fait mais pour un
programmeur dilettant je crois que j'ai le droit d'être fier car j'ai
été très largement largué techniquement alors que je programmais en
basic puis en DbaseII en auto-formé.

Amitiés
--
Yannick VOYEAUD
Mickaël Wolff
2009-04-10 21:43:56 UTC
Permalink
Post by Yannick
Bonsoir,
Bonsoir :)
Post by Yannick
Ce qui est important c'est de savoir ce qui se passe à tel ou tel moment
dans le script.
En conséquence un pro n'a pas besoin de commentaires car il sait mais un
amateur en a besoin pour repérer rapidement ses commandes et les actions
qu'elles sont sensées faire.
Un pro comme un amateur a besoin de commentaires. Mais chacun à
besoin d'une information claire, concise, et maintenable. Si les
commentaires sont illisibles et grèvent le code, il est inutile et aura
beaucoup de chances de devenir dépassé. Et il n'y a rien de pire qu'une
documentation erronée. n'oublions pas que les commentaires sont
interprétés par le cerveau humain, et seul cet organe est capable de
déterminer si le commentaire est cohérent ou non.
Post by Yannick
Un programme bien documenté et bien commenté est réutilisable par une
autre personne. Un programme non commenté EST illisible donc mieux vaut
trop que pas assez.
Un code bien écrit n'a pas besoin de commentaires superflus. Les
commentaires doivent signaler le comportement attendu et l'usage d'un
bout de code, et des points délicats du code source.
Post by Yannick
Si je m'en sort c'est bien parce que mon code, bien que pas génial pour
les puristes, est commenté en abondance.
Certes il y a beaucoup à dire sur le travail que j'ai fait mais pour un
programmeur dilettant je crois que j'ai le droit d'être fier car j'ai
été très largement largué techniquement alors que je programmais en
basic puis en DbaseII en auto-formé.
Je comprends bien ton point de vue. Mais comprends aussi le mien, qui
suis confronté professionnellement à du code de qualité variable.
--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org
Sylvain SF
2009-04-09 20:47:17 UTC
Permalink
Il faut traiter $_GET (pour déterminer les ressources consultées)
et $_POST (pour déterminer les alterations des ressources).
[...]
Ce que je trouve dommage c'est que tu traites indistinctement les
données d'alteration et de consultation.
tu peux expliciter ce qui te parait manquer ?

ici tu nommes (assez pompeusement) 2 moyens de transmettre
des données à un script, merci pour cette grande leçon de
sémantique mais quel est l'apport ? dans moulte cas, ce
moyen de transmission n'est que pure évidence pragmatique;
le traitement des paramètres, de tous les paramètres, reste
nécessaire, un nommage branché ne change rien.

Sylvain.
Olivier Miakinen
2009-04-09 21:25:53 UTC
Permalink
Post by Sylvain SF
Il faut traiter $_GET (pour déterminer les ressources consultées)
et $_POST (pour déterminer les alterations des ressources).
[...]
Ce que je trouve dommage c'est que tu traites indistinctement les
données d'alteration et de consultation.
C'est le printemps : les marronniers sont en fleurs...
Post by Sylvain SF
tu peux expliciter ce qui te parait manquer ?
ici tu nommes (assez pompeusement) 2 moyens de transmettre
des données à un script, merci pour cette grande leçon de
sémantique mais quel est l'apport ? dans moult cas, ce
moyen de transmission n'est que pure évidence pragmatique;
le traitement des paramètres, de tous les paramètres, reste
nécessaire, un nommage branché ne change rien.
Je suis du même avis.

Si un programmeur était assez tordu pour demander à recevoir deux
données de même nom, l'une dans $_GET et l'autre dans $_POST (ou bien
l'une des deux dans $_COOKIE), alors oui, il aurait probablement besoin
de distinguer par où lui parvient chacune de ces données. Mais dans le
cas d'un programmeur sain d'esprit je ne vois pas ce que ça peut lui
apporter de contrôler ça. Il vaut mieux se concentrer sur les valeurs
reçues !
Denis Beauregard
2009-04-09 23:38:55 UTC
Permalink
Post by Olivier Miakinen
Si un programmeur était assez tordu pour demander à recevoir deux
données de même nom, l'une dans $_GET et l'autre dans $_POST (ou bien
l'une des deux dans $_COOKIE), alors oui, il aurait probablement besoin
de distinguer par où lui parvient chacune de ces données. Mais dans le
cas d'un programmeur sain d'esprit je ne vois pas ce que ça peut lui
apporter de contrôler ça. Il vaut mieux se concentrer sur les valeurs
reçues !
Pourquoi pas les 3 en parallèle ? get, post et cookie (il y en a un
4e ?).

Ceci dit, quand je développe, j'aime bien voir les noms des variables
dans l'URL, histoire de ne pas avoir à cliquer 2 fois quand je
rafraichis une page (avec POST, de mémoire). Donc, cela a du sens
de développer avec une méthode, puis d'utiliser l'autre méthode (sans
que les noms soient dans l'URL), histoire d'avoir un historique sans
les détails des transactions par exemple quand c'est sensible. On
pourrait même utiliser des cookies pour avoir une sorte de machine
à états durant le développement.




Denis
Patrick Mevzek
2009-04-10 07:36:02 UTC
Permalink
Post by Olivier Miakinen
Si un programmeur était assez tordu pour demander à recevoir deux
données de même nom, l'une dans $_GET et l'autre dans $_POST (ou bien
l'une des deux dans $_COOKIE), alors oui, il aurait probablement besoin
de distinguer par où lui parvient chacune de ces données. Mais dans le
cas d'un programmeur sain d'esprit je ne vois pas ce que ça peut lui
apporter de contrôler ça. Il vaut mieux se concentrer sur les valeurs
reçues !
Pourquoi pas les 3 en parallèle ? get, post et cookie (il y en a un 4e
?).
Comme passage d'informations, il y a le PATH_INFO mais peu utilisé.
Sinon, dans $_REQUEST, il y avait aussi avant $_FILES.
Et question environnement, il y a aussi (mais non fusionné) $_SERVER et
$_ENV
Ceci dit, quand je développe, j'aime bien voir les noms des variables
dans l'URL, histoire de ne pas avoir à cliquer 2 fois quand je
rafraichis une page (avec POST, de mémoire). Donc, cela a du sens de
développer avec une méthode, puis d'utiliser l'autre méthode (sans que
Euh... les deux ne sont pas complétement interchangeables quand même, la
sémantique n'est pas la même.

Je ne comprends pas très bien votre histoire de "voir les variables" ?
En phase de développement, vous ne pouvez pas ajouter des echo dans votre
code pour afficher des informations supplémentaires dans la page
(voir, pour faire plus subtil, des inscriptions javascript qui utilisent
Firebug pour faire du beau debug en console) ?
--
Patrick Mevzek . . . . . . . . . . . . . . Dot and Co
<http://www.dotandco.net/> <http://www.dotandco.com/>
<http://www.dotandco.net/ressources/icann_registrars/prices>
<http://icann-registrars-life.dotandco.net/>
Denis Beauregard
2009-04-10 13:51:23 UTC
Permalink
Le 10 Apr 2009 07:36:02 GMT, Patrick Mevzek
Post by Patrick Mevzek
Post by Olivier Miakinen
Si un programmeur était assez tordu pour demander à recevoir deux
données de même nom, l'une dans $_GET et l'autre dans $_POST (ou bien
l'une des deux dans $_COOKIE), alors oui, il aurait probablement besoin
de distinguer par où lui parvient chacune de ces données. Mais dans le
cas d'un programmeur sain d'esprit je ne vois pas ce que ça peut lui
apporter de contrôler ça. Il vaut mieux se concentrer sur les valeurs
reçues !
Pourquoi pas les 3 en parallèle ? get, post et cookie (il y en a un 4e
?).
Comme passage d'informations, il y a le PATH_INFO mais peu utilisé.
Sinon, dans $_REQUEST, il y avait aussi avant $_FILES.
Et question environnement, il y a aussi (mais non fusionné) $_SERVER et
$_ENV
mais pas réellement un passage d'arguments.
Post by Patrick Mevzek
Ceci dit, quand je développe, j'aime bien voir les noms des variables
dans l'URL, histoire de ne pas avoir à cliquer 2 fois quand je
rafraichis une page (avec POST, de mémoire). Donc, cela a du sens de
développer avec une méthode, puis d'utiliser l'autre méthode (sans que
Euh... les deux ne sont pas complétement interchangeables quand même, la
sémantique n'est pas la même.
Je sais. Si je fais un logiciel interrogeant une base de données,
je peux utiliser le GET et le POST en 1re étape (ce que je recherche),
puis le GET dans une liste de choix possibles, donc une série de
details.php?id=12345.

Durant le développement, si je commence avec un POST, à chaque essai,
le navigateur va me demander si je veux répéter les "POST DATA", alors
qu'avec un GET, les arguments étant dans l'URL, la question n'est pas
pertinente.

Par la suite, cela dépend si les données sont sensibles ou pas. Si
j'ai un GET, la chaîne recherchée par l'utilisateur sera visible dans
l'historique et donc un utilisateur plutôt novice utilisant la base
dans une bibliothèque publique pourrait laisser des traces. Imaginez
par exemple une recherche dans une base de données personnelles ou
mieux, le mot de passe dans l'URL.

Je permets donc les deux, soit de passer par le GET (j'envoie l'URL
pour se connecter avec le mot de passe) et l'utilisateur ajoute le
lien à ses signets à la maison, et de passer par le POST (il y a
des champs pour le nom d'usager et le mot de passe dans la page
d'accueil, mais ces données ne sont pas dans l'URL) pour l'utilisateur
qui travaillerait depuis un ordinateur public.
Post by Patrick Mevzek
Je ne comprends pas très bien votre histoire de "voir les variables" ?
En phase de développement, vous ne pouvez pas ajouter des echo dans votre
code pour afficher des informations supplémentaires dans la page
(voir, pour faire plus subtil, des inscriptions javascript qui utilisent
Firebug pour faire du beau debug en console) ?
Avec le GET et donc l'URL, je peux modifier facilement l'URL pour
changer l'argument et faire le test sans remonter d'une page.
Et j'ajoute quelques echo mais pour d'autres raisons.


Denis
Patrick Mevzek
2009-04-10 15:18:07 UTC
Permalink
Par la suite, cela dépend si les données sont sensibles ou pas. Si j'ai
un GET, la chaîne recherchée par l'utilisateur sera visible dans
l'historique et donc un utilisateur plutôt novice utilisant la base dans
une bibliothèque publique pourrait laisser des traces. Imaginez par
exemple une recherche dans une base de données personnelles ou mieux, le
mot de passe dans l'URL.
Dans ce cas l'application est mal conçue, que ce soit un GET ou un POST
n'y change rien (pensez à un sniffeur sur le réseau...), un mot de passe
n'a pas à circuler en clair.
Avec le GET et donc l'URL, je peux modifier facilement l'URL pour
changer l'argument et faire le test sans remonter d'une page.
Une extension comme Firebug fait des merveilles dans tous les cas pour ce
genre de choses...
--
Patrick Mevzek . . . . . . . . . . . . . . Dot and Co
<http://www.dotandco.net/> <http://www.dotandco.com/>
<http://www.dotandco.net/ressources/icann_registrars/prices>
<http://icann-registrars-life.dotandco.net/>
Mickael Wolff
2009-04-09 23:38:55 UTC
Permalink
Post by Olivier Miakinen
Je suis du même avis.
Si un programmeur était assez tordu pour demander à recevoir deux
données de même nom, l'une dans $_GET et l'autre dans $_POST (ou bien
l'une des deux dans $_COOKIE), alors oui, il aurait probablement besoin
de distinguer par où lui parvient chacune de ces données. Mais dans le
cas d'un programmeur sain d'esprit je ne vois pas ce que ça peut lui
apporter de contrôler ça. Il vaut mieux se concentrer sur les valeurs
reçues !
Imaginons que nous ayons le formulaire suivant dans notre application :

<form action='#' method='post'>
<p>
<input type='hidden' name='action' value='news.delete' />
<input type='hidden' name='id' value='42' />
<input type='submit' value='Supprimer' />
</p>
</form>

Ce formulaire permet de supprimer une news :

<?php

if(isset($_POST['action']))
{
$action = $_POST['action'] ;
if($action === 'news.delete')
{
// on traite la suppression de la news
}
}

?>

Si on avais utiliser $_REQUEST, que les données soient soumises en
GET ou en POST n'a pas d'importance. Dans ce cas là, un attaquant
pourrait transmettre un lien forgé à une victime utilisatrice du site :

<http://example.com/?action=news.delete&id=42>

Ce lien peut ^etre explicite (dans un courriel par exemple), ou caché
(et chargé automatiquement) dans une page HTML visitée par l'utilisateur
alors qu'il est connecté à l'application compromise. On peut cacheer
dans une balise img, stype, script, etc. Bien s^ur, le HTML peut ^etre
caché dans le courriel...

Moralité, ce n'est pas parce que le programmeur tordu du site a
décidé d'utiliser un nom commun entre les paramètres HTTP (COOKIE
compris) qu'il faut distinguer POST et GET, mais parce qu'un attaquant
peut ^etre tordu et profiter de la na"iveté de chacun pour nuir.

Je vous conseille à tous la lecture du très bon « Sécurité PHP 5 et
MySQL » qui détaille ce genre de trous de sécurité auquelles on ne peut
que difficilement imaginer. A moins d'^etre tordu ;)

<http://www.eyrolles.com/Informatique/Livre/securite-php-5-et-mysql-9782212121148>
--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org
Olivier Miakinen
2009-04-10 00:23:59 UTC
Permalink
Bonjour,
Post by Mickael Wolff
<form action='#' method='post'>
<p>
<input type='hidden' name='action' value='news.delete' />
<input type='hidden' name='id' value='42' />
<input type='submit' value='Supprimer' />
</p>
</form>
Ahem... c'est tout ? Il n'y a pas un petit id de session quelque
part dans le formulaire ? Mettons par exemple :
<input type='hidden' name='sessid' value='45ef0063d0aab7f39199' />
Ah oui, c'est sûr que s'il suffit d'envoyer un paramètre fixe
(news.delete) et un numéro d'article pour effacer l'article en
question, il n'est pas très difficile à un attaquant de demander
cet effacement. Mais note que le faire avec WGET en POST n'est
pas beaucoup plus difficile qu'en GET.
Post by Mickael Wolff
<?php
if(isset($_POST['action']))
{
$action = $_POST['action'] ;
if($action === 'news.delete')
{
// on traite la suppression de la news
}
}
?>
Je ne connais pas la syntaxe de WGET pour envoyer cette requête, mais si
tu y tiens je veux bien la chercher.
Post by Mickael Wolff
Si on avait utiliser $_REQUEST, que les données soient soumises en
GET ou en POST n'a pas d'importance. Dans ce cas là, un attaquant
<http://example.com/?action=news.delete&id=42>
Ce lien peut ^etre explicite (dans un courriel par exemple), ou caché
(et chargé automatiquement) dans une page HTML visitée par l'utilisateur
alors qu'il est connecté à l'application compromise. On peut cacheer
dans une balise img, stype, script, etc. Bien s^ur, le HTML peut ^etre
caché dans le courriel...
Ah, je crois que je comprends enfin où peut être le problème : c'est
quand l'id de session se trouve dans un cookie. Oui, en effet dans ce
cas là un lien envoyé par courriel à quelqu'un déjà connecté pourrait
faire ce genre de chose. Mais ne peut-on faire la même chose avec un
formulaire dans un courriel en HTML ? La seule vraie protection serait
alors de mettre un id non devinable dans un champ caché du formulaire.
Post by Mickael Wolff
Moralité, ce n'est pas parce que le programmeur tordu du site a
décidé d'utiliser un nom commun entre les paramètres HTTP (COOKIE
compris) qu'il faut distinguer POST et GET, mais parce qu'un attaquant
peut ^etre tordu et profiter de la na"iveté de chacun pour nuire.
J'attends encore d'être complètement convaincu qu'un attaquant peut
amener la victime à faire par GET quelque chose qu'il ne pourrait pas
lui faire faire par POST.
Post by Mickael Wolff
Je vous conseille à tous la lecture du très bon « Sécurité PHP 5 et
MySQL » qui détaille ce genre de trous de sécurité auquelles on ne peut
que difficilement imaginer. A moins d'^etre tordu ;)
<http://www.eyrolles.com/Informatique/Livre/securite-php-5-et-mysql-9782212121148>
Merci !
Patrick Mevzek
2009-04-10 07:36:02 UTC
Permalink
Ahem... c'est tout ? Il n'y a pas un petit id de session quelque part
<input type='hidden' name='sessid' value='45ef0063d0aab7f39199' />
Encore mieux : un jeton unique, qui est lié à ce formulaire précisément
et cette tentative (telle action sur tel objet). Ainsi, dans la même
"session" (par exemple avec deux onglets simultanés) on peut avoir 2
formulaires distincts (action et/ou objet) qui fonctionneront
correctement sans se marcher l'un sur l'autre.

Cela simplifie pas mal de choses : plus besoin de variables dans le
formulaire et de champ caché, à part le numéro de jeton, car toutes les
données sont stockées sur le serveur, liées au numéro de jeton. Quand on
actionne le bouton, le serveur reçoit le numéro de jeton et retrouve
localement de quelles données il s'agissait, pas besoin de tout
retransmettre.
Je ne connais pas la syntaxe de WGET pour envoyer cette requête, mais si
tu y tiens je veux bien la chercher.
wget --post-data='action=news.delete&id=42' ...
Post by Mickael Wolff
Ce lien peut ^etre explicite (dans un courriel par exemple), ou caché
(et chargé automatiquement) dans une page HTML visitée par
l'utilisateur alors qu'il est connecté à l'application compromise. On
peut cacheer dans une balise img, stype, script, etc. Bien s^ur, le
HTML peut ^etre caché dans le courriel...
Ah, je crois que je comprends enfin où peut être le problème : c'est
quand l'id de session se trouve dans un cookie.
D'où :
1) pourquoi je n'aime pas les cookies comme stockage d'identifiants de
session :-)
2) il faut des jetons par formulaire/action/object, liés à la session
(pour qu'un utilisateur A ne puisse pas utiliser les jetons de
l'utilisateur B), mais sémantiquement séparé.
Oui, en effet dans ce
cas là un lien envoyé par courriel à quelqu'un déjà connecté pourrait
faire ce genre de chose.
Le problème alors n'est pas GET vs POST mais application pas suffisamment
bien concue, c'est à dire qui ne comprend pas comment fonctionne la
gestion des états au-dessus du mécanisme sans états qu'est HTTP (d'accord
personne n'a dit que c'était forcément trivial), et qui n'a pas de modèle
cohérent d'authorisation (que faut-il préciser pour avoir le droit de
supprimer telle information)
--
Patrick Mevzek . . . . . . . . . . . . . . Dot and Co
<http://www.dotandco.net/> <http://www.dotandco.com/>
<http://www.dotandco.net/ressources/icann_registrars/prices>
<http://icann-registrars-life.dotandco.net/>
Patrick Mevzek
2009-04-10 07:36:02 UTC
Permalink
Post by Mickael Wolff
Si on avais utiliser $_REQUEST, que les données soient soumises en
GET ou en POST n'a pas d'importance. Dans ce cas là, un attaquant
<http://example.com/?action=news.delete&id=42>
... comme il pourrait transmettre un email avec du code HTML et du
javascript qui déclenche l'envoi du formulaire en POST.
Niveau attaque c'est pareil, aucune des deux solutions ne change quoi que
ce soit, preuve que la surface d'exposition est la même et que ce n'est
pas dans ce genre de différences qu'il faut espérer sécuriser
l'application.

Pour qui, au passage, une bonne façon de faire serait de vérifier quelle
est la page "précédente" (et non, pas avec le "referer"), ce qui assure
que la demande de suppression arrive selon le canal prévu, en couplant
avec un mécanisme de jetons uniques pour éviter le rejeu et les liens
directs.
Post by Mickael Wolff
Ce lien peut ^etre explicite (dans un courriel par exemple), ou caché
(et chargé automatiquement) dans une page HTML visitée par l'utilisateur
alors qu'il est connecté à l'application compromise.
Idem en POST.
Post by Mickael Wolff
Moralité, ce n'est pas parce que le programmeur tordu du site a
décidé d'utiliser un nom commun entre les paramètres HTTP (COOKIE
compris) qu'il faut distinguer POST et GET, mais parce qu'un attaquant
peut ^etre tordu et profiter de la na"iveté de chacun pour nuir.
Cela ne s'appelle pas de la naïveté, mais une application mal conçue.
Après tout c'est un métier aussi !
Et cette erreur de conception ne se résout pas en changeant un get en
post ou le contraire en HTML ou un $_GET en $_POST ou le contraire dans
un code PHP.
Post by Mickael Wolff
Je vous conseille à tous la lecture du très bon « Sécurité PHP 5 et
MySQL » qui détaille ce genre de trous de sécurité auquelles on ne peut
que difficilement imaginer.
On ne peut que difficilement imaginer ce genre de trous ? Ah bon ? Mais
là ce n'est pas d'un trou que vous parlez, mais d'un goufre, connu et
archi connu, documenté partout (la preuve vous citez un livre en français
mainstream c'est pas comme s'il fallait se dégoter un PDF en anglais
d'une conférence paumée pour découvrir une nouvelle attaque...).

Après je ne connais pas le livre en question, mais déjà rien que le titre
me fait tiquer :
- il n'existe pas que MySQL, y compris dans/avec PHP. Ca pourrait être
bien de commencer à l'envisager...
- on parle de la sécurité sur le web, en général (et alors les problèmes
sont les mêmes dans tous les langages de programmation et SGBDR), ou de
la sécurité de/en PHP et de/en MySQL ? Ce n'est pas tout à fait la même
chose...

Pour moi *LE* bouquin sur la sécurité pour le web (même si je ne suis pas
d'accord à 100% avec ses recommandations, notamment sur la gestion de la
persistence entre URLs et cookies) c'est le Huseby « Innocent Code ».
Et dedans il n'y a rien de spécifique à PHP ou à MySQL, c'est 100% la
sécurité des environnements web et donc cela s'applique à tout le monde.
--
Patrick Mevzek . . . . . . . . . . . . . . Dot and Co
<http://www.dotandco.net/> <http://www.dotandco.com/>
<http://www.dotandco.net/ressources/icann_registrars/prices>
<http://icann-registrars-life.dotandco.net/>
Mickael Wolff
2009-04-09 23:38:55 UTC
Permalink
Post by Sylvain SF
tu peux expliciter ce qui te parait manquer ?
Ben la distinction entre les méthodes. Utiliser $_REQUEST revient à
reproduire le comportement stupide de register_global, qui a entra^iné
tant de désillusions en compromettant la sécurité des données en raison
d'une erreur grave de conception.
Post by Sylvain SF
ici tu nommes (assez pompeusement)
Désolé, quand ça ménerve je ne me retiens plus :-/
Post by Sylvain SF
2 moyens de transmettre
des données à un script, merci pour cette grande leçon de
sémantique mais quel est l'apport ? dans moulte cas, ce
moyen de transmission n'est que pure évidence pragmatique;
le traitement des paramètres, de tous les paramètres, reste
nécessaire, un nommage branché ne change rien.
Je pense que par nommage branché tu désigne la distinction des
données soumises en $_POST ou en $_GET.

Je considère ceci comme fondamental. Les utilisateurs avancé de la
liste savent que de nombreuses applications voyaient leur comportement
détourné en raison du manque de discernement au niveau du tra^itement
des données soumises par le navigateur. Par exemple OsCommerce,
Wordpress, Dotclear, etc. C'est pourquoi je considère inconcevable qu'on
puisse conseiller l'usage de $_REQUEST à un débutant. D'ailleurs,
j'espère que $_REQUEST dispara^itra un jour !
--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org
Patrick Mevzek
2009-04-10 07:36:02 UTC
Permalink
Post by Mickael Wolff
Post by Sylvain SF
tu peux expliciter ce qui te parait manquer ?
Ben la distinction entre les méthodes. Utiliser $_REQUEST revient à
reproduire le comportement stupide de register_global,
Strictement AUCUN rapport !

Le problème du register_global est de fusionner deux contextes qui n'ont
rien à voir : celui de l'environnement Web (les échanges avec le client)
et celui de l'intérieur du programme (les variables)
$_REQUEST fusionne $_GET et $_POST (entre autres) mais ils sont par
essence dans le *même* contexte (celui du web, c'est à dire contenu non
sûr provenant de l'utilisateur), donc leur fusion ne créé pas de problème
supplémentaire de sécurité.
Post by Mickael Wolff
Je considère ceci comme fondamental.
Oui, mais pas pour la raison que vous évoquez.
Post by Mickael Wolff
Les utilisateurs avancé de la
liste savent que de nombreuses applications voyaient leur comportement
détourné en raison du manque de discernement au niveau du tra^itement
des données soumises par le navigateur.
Parce que le simple fait de changer un GET en POST ou le contraire
faisait 'planter' l'application ? Bah alors là le problème est ailleurs
et il me semble qu'on a discuté de cela récemment.
Post by Mickael Wolff
Par exemple OsCommerce,
Wordpress, Dotclear, etc. C'est pourquoi je considère inconcevable qu'on
puisse conseiller l'usage de $_REQUEST à un débutant.
C'est tout à fait concevable et c'est même la bonne façon de faire.
Toutes les bonnes APIs de tous les langages de programmation offrent une
interface identique que l'on soit en GET en POST (tout en étant capable
de discriminer bien sûr quand on en a besoin), ce qui illustre bien que
le problème n'est pas là.
C'est une forme d'abstraction qui, quand on connaît bien les choses (et
quand on ne les connaît pas on s'abstient ou on apprend), est tout à fait
utile.
Post by Mickael Wolff
D'ailleurs, j'espère que $_REQUEST dispara^itra un jour !
C'est le genre de paravent de mesure de sécurité. Supprimer $_REQUEST
n'augmentera en rien la sécurité des applications. Au contraire, un
"faux" sentiment de sécurité est bien pire selon moi que pas de sécurité
du tout, mais clairement avouée.
--
Patrick Mevzek . . . . . . . . . . . . . . Dot and Co
<http://www.dotandco.net/> <http://www.dotandco.com/>
<http://www.dotandco.net/ressources/icann_registrars/prices>
<http://icann-registrars-life.dotandco.net/>
Mickael Wolff
2009-04-10 21:43:56 UTC
Permalink
Post by Patrick Mevzek
Le problème du register_global est de fusionner deux contextes qui n'ont
rien à voir : celui de l'environnement Web (les échanges avec le client)
et celui de l'intérieur du programme (les variables)
Le jet des variables HTTP dans le scope global n'était pas le
problème. Personnelement, hormis dans les script simples
d'apprentissage, je ne vois pas comment on peut sérieusement utiliser
les variables globales dans ces fonctions. Dans les cursus de formation
des développeurs, les variables globales sont toujours présentées comme
l'une des plaies de la programmation, au côté de goto.
Post by Patrick Mevzek
$_REQUEST fusionne $_GET et $_POST (entre autres) mais ils sont par
essence dans le *même* contexte (celui du web, c'est à dire contenu non
sûr provenant de l'utilisateur), donc leur fusion ne créé pas de problème
supplémentaire de sécurité.
Je pars du principe qu'aucune donnée n'est fiable. Quelle que soit ça
provenance, même si les données provenant de sources considérées comme
sûres doivent être considérées comme compromises :D Mais c'est un point
de vu paranoïaque.

Maintenant je regrète : les contextes POST, GET et COOKIE sont
différents. Qu'ils proviennent de la même source ne permettent pas de
les considérer comme équivalent. Pourtant tu devrais le savoir, tu n'es
pas un abruti, mais je pense que tu n'as jamais observé la gueule d'une
requête. Si ces trois contextes étaient interchangeables, pourquoi
sont-ils séparés, et pourquoi leur sémantique (et donc leur
comportement) est-il si différent ?
Post by Patrick Mevzek
Oui, mais pas pour la raison que vous évoquez.
J'évoque deux raisons. La sémantique et la sécurité. Elles sont
liées, certes, mais importantes.
Post by Patrick Mevzek
Parce que le simple fait de changer un GET en POST ou le contraire
faisait 'planter' l'application ? Bah alors là le problème est ailleurs
et il me semble qu'on a discuté de cela récemment.
Mais alors où est-il ? Si on ne peut plus distinguer les données
saisies en POST et en GET ? Alors certes, pour vérifier que j'ai reçu
une requête POST je vérifie la clé 'REQUEST_METHOD' de la superglobale
$_SERVER, mais j'utilises tout de même $_POST et $_GET pour distinguer
la provenance des instructions. Simplement parce qu'une application
complexe peut requérir l'accès à une ressource ne même temps que la
modification d'une autre. Mais aussi parce que l'ordre d'importation des
contextes est configurable, il n'y a aucune garantie de fonctionnement
alors.

En fait, avant d'utiliser $_REQUEST, tu vérifie la valeur de la
variable $_SERVER['REQUEST_METHOD'] ? Et finalement, lorsque tu es en
'POST' tu ignores les paramètres GET (donc en partie l'URL) ?
Post by Patrick Mevzek
Post by Mickael Wolff
Par exemple OsCommerce,
Wordpress, Dotclear, etc. C'est pourquoi je considère inconcevable qu'on
puisse conseiller l'usage de $_REQUEST à un débutant.
C'est tout à fait concevable et c'est même la bonne façon de faire.
Toutes les bonnes APIs de tous les langages de programmation offrent une
interface identique que l'on soit en GET en POST (tout en étant capable
de discriminer bien sûr quand on en a besoin), ce qui illustre bien que
le problème n'est pas là.
Tu as des noms d'API ? Ça m'intéresse en C++ ;)
Post by Patrick Mevzek
Post by Mickael Wolff
D'ailleurs, j'espère que $_REQUEST dispara^itra un jour !
C'est le genre de paravent de mesure de sécurité. Supprimer $_REQUEST
n'augmentera en rien la sécurité des applications. Au contraire, un
"faux" sentiment de sécurité est bien pire selon moi que pas de sécurité
du tout, mais clairement avouée.
C'est vrai que de supprimer register_global est un paravent ;)
--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org
Olivier Miakinen
2009-04-13 13:16:26 UTC
Permalink
Post by Mickael Wolff
Post by Patrick Mevzek
Le problème du register_global est de fusionner deux contextes qui n'ont
rien à voir : celui de l'environnement Web (les échanges avec le client)
et celui de l'intérieur du programme (les variables)
Le jet des variables HTTP dans le scope global n'était pas le
problème. Personnelement, hormis dans les script simples
d'apprentissage, je ne vois pas comment on peut sérieusement utiliser
les variables globales dans ces fonctions. Dans les cursus de formation
des développeurs, les variables globales sont toujours présentées comme
l'une des plaies de la programmation, au côté de goto.
Euh... quoique vous ayez (à mon avis) raison tous les deux, tu parles
d'une chose qui n'a rien à voir avec ce dont parle Patrick. En effet,
Patrick parle des variables globales dans le *programme* alors que toi
tu parles des variables globales dans les *fonctions*.

(Au passage, $_POST, $_GET et $_REQUEST sont « superglobales », et elles
sont donc visibles aussi bien dans les fonctions qu'en dehors, mais
c'est encore un troisième point qui n'a que peu à voir avec les deux
premiers.)
Post by Mickael Wolff
Post by Patrick Mevzek
$_REQUEST fusionne $_GET et $_POST (entre autres) mais ils sont par
essence dans le *même* contexte (celui du web, c'est à dire contenu non
sûr provenant de l'utilisateur), donc leur fusion ne créé pas de problème
supplémentaire de sécurité.
Je pars du principe qu'aucune donnée n'est fiable. Quelle que soit ça
provenance, même si les données provenant de sources considérées comme
sûres doivent être considérées comme compromises :D Mais c'est un point
de vu paranoïaque.
Vous êtes encore d'accord tous les deux. Mais justement tu apportes de
l'eau à notre moulin : puisque aucune donnée n'est fiable, il faut
toujours vérifier la valeur de chacune d'entre elles, quelle que soit sa
provenance. Vérifier un jeton à usage unique de 128 bits, par exemple,
est ainsi beaucoup plus utile que de vérifier si le jeton a été mis dans
$_GET ou $_POST.
Post by Mickael Wolff
Maintenant je regrète : les contextes POST, GET et COOKIE sont
différents. Qu'ils proviennent de la même source ne permettent pas de
les considérer comme équivalent.
Pourquoi cela ? Ils proviennent de la même source, et sont donc aussi
peu fiables en passant par $_POST que par $_GET. Si tu considères que
vérifier le passage par $_POST est nécessaire pour la sécurité, c'est
que tu n'as pas un bon moyen pour vérifier la sécurité par ailleurs (par
exemple un jeton à usage unique).
Post by Mickael Wolff
[...]
Post by Patrick Mevzek
Oui, mais pas pour la raison que vous évoquez.
J'évoque deux raisons. La sémantique et la sécurité. Elles sont
liées, certes, mais importantes.
La sémantique, c'est ce qui fait qu'un programmeur choisira tantôt une
URL (et donc un GET avec données passant par $_GET) tantôt un formulaire
(en POST avec données passant par $_POST).

La sécurité, c'est vérifier les valeurs reçues, celles-ci permettant
d'avoir une assurance raisonnable (proportionnée aux dommages possibles)
qu'un attaquant n'a pas forgé une requête à la place de l'utilisateur.

Alors certes, l'utilisateur honnête enverra bien un GET si tu as prévu
un GET et un POST si tu as prévu un POST. Mais l'attaquant, s'il peut
forger un GET là où tu attends un POST, pourrait aussi bien forger un
POST avec les mêmes données. Du coup, tu peux bien vérifier ce point
particulier si ça te chante, mais il ne faut pas l'ériger en principe
de sécurité car ce n'en est pas un.
Post by Mickael Wolff
[...] j'utilises tout de même $_POST et $_GET pour distinguer
la provenance des instructions. Simplement parce qu'une application
complexe peut requérir l'accès à une ressource ne même temps que la
modification d'une autre.
... et donc avoir besoin à la fois de $_POST['truc'] et $_GET['truc'] ?
Je ne donnerai pas d'avis sur cette méthode, juste que si vraiment le
programmeur veut faire ça il *peut* utiliser à la fois $_GET et $_POST
mais que ça n'a strictement rien à voir avec la sécurité.
Post by Mickael Wolff
Mais aussi parce que l'ordre d'importation des
contextes est configurable, il n'y a aucune garantie de fonctionnement
alors.
Idem. Personnellement je sais que j'éviterais à tout prix d'avoir
deux valeurs de même nom parmi $_GET['truc'], $_POST['truc'] et
$_COOKIE['truc'] car ce serait vraiment casse-gueule et une grosse
source possible de bugs.
Post by Mickael Wolff
[...]
Post by Patrick Mevzek
D'ailleurs, j'espère que $_REQUEST disparaîtra un jour !
C'est le genre de paravent de mesure de sécurité. Supprimer $_REQUEST
n'augmentera en rien la sécurité des applications. Au contraire, un
"faux" sentiment de sécurité est bien pire selon moi que pas de sécurité
du tout, mais clairement avouée.
C'est vrai que de supprimer register_global est un paravent ;)
Ahem... merci de reconnaître que cet argument est de la pure mauvaise
foi ! Utiliser $_REQUEST au lieu de $_GET et $_POST ne permet pas à des
variables de se glisser dans le contexte global à l'insu du programmeur.
Mickael Wolff
2009-04-22 20:04:08 UTC
Permalink
Post by Olivier Miakinen
Vous êtes encore d'accord tous les deux. Mais justement tu apportes de
l'eau à notre moulin : puisque aucune donnée n'est fiable, il faut
toujours vérifier la valeur de chacune d'entre elles, quelle que soit sa
provenance. Vérifier un jeton à usage unique de 128 bits, par exemple,
est ainsi beaucoup plus utile que de vérifier si le jeton a été mis dans
$_GET ou $_POST.
Mais s'il a été mis dans $_GET tu peux déclencher une alert.
Post by Olivier Miakinen
Post by Mickael Wolff
Maintenant je regrète : les contextes POST, GET et COOKIE sont
différents. Qu'ils proviennent de la même source ne permettent pas de
les considérer comme équivalent.
Pourquoi cela ? Ils proviennent de la même source, et sont donc aussi
peu fiables en passant par $_POST que par $_GET. Si tu considères que
vérifier le passage par $_POST est nécessaire pour la sécurité, c'est
que tu n'as pas un bon moyen pour vérifier la sécurité par ailleurs (par
exemple un jeton à usage unique).
Je suis d'accord que c'est insuffisant.
Post by Olivier Miakinen
La sémantique, c'est ce qui fait qu'un programmeur choisira tantôt une
URL (et donc un GET avec données passant par $_GET) tantôt un formulaire
(en POST avec données passant par $_POST).
Tout mes formulaires ne sont pas en POST ;)
Post by Olivier Miakinen
Alors certes, l'utilisateur honnête enverra bien un GET si tu as prévu
un GET et un POST si tu as prévu un POST. Mais l'attaquant, s'il peut
forger un GET là où tu attends un POST, pourrait aussi bien forger un
POST avec les mêmes données. Du coup, tu peux bien vérifier ce point
particulier si ça te chante, mais il ne faut pas l'ériger en principe
de sécurité car ce n'en est pas un.
Mais cett pratique ajoute une première fosse à l'attaquant.
Post by Olivier Miakinen
Idem. Personnellement je sais que j'éviterais à tout prix d'avoir
deux valeurs de même nom parmi $_GET['truc'], $_POST['truc'] et
$_COOKIE['truc'] car ce serait vraiment casse-gueule et une grosse
source possible de bugs.
Pas si tu les distingue, et que tu les traite séparément.
Post by Olivier Miakinen
Ahem... merci de reconnaître que cet argument est de la pure mauvaise
foi ! Utiliser $_REQUEST au lieu de $_GET et $_POST ne permet pas à des
variables de se glisser dans le contexte global à l'insu du programmeur.
Je mettrais plus de smilies la prochaine fois ;)
--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org
John GALLET
2009-04-24 13:58:58 UTC
Permalink
Post by Mickael Wolff
Post by Olivier Miakinen
Alors certes, l'utilisateur honnête enverra bien un GET si tu as prévu
un GET et un POST si tu as prévu un POST. Mais l'attaquant, s'il peut
forger un GET là où tu attends un POST, pourrait aussi bien forger un
POST avec les mêmes données. Du coup, tu peux bien vérifier ce point
particulier si ça te chante, mais il ne faut pas l'ériger en principe
de sécurité car ce n'en est pas un.
Mais cett pratique ajoute une première fosse à l'attaquant.
Là franchement je n'ai qu'un seul commentaire: ROTFL !! Si "l'attaquant"
n'est même pas capable de faire ça... il est pas bien dangereux.
--
C'est quoi les dinos ?
J'ai compris que c'était des vieux cons, mais à part ça ??
-+- CL in GNU : Je ne voudrais pas passer pour un con... Loupé. -+-
Patrick Mevzek
2009-04-13 13:16:26 UTC
Permalink
Post by Mickael Wolff
Post by Patrick Mevzek
Le problème du register_global est de fusionner deux contextes qui
n'ont rien à voir : celui de l'environnement Web (les échanges avec le
client) et celui de l'intérieur du programme (les variables)
Le jet des variables HTTP dans le scope global n'était pas le
problème.
Ah bon ce n'est pas ca le problème de register_global ?
Bah je crois qu'il y a fort peu de chance qu'on soit d'accord sur quelque
chose si on n'est pas d'accord sur un fait de base comme ca.
C'est quoi alors selon vous le problème de register_global ?
Post by Mickael Wolff
Personnelement, hormis dans les script simples
d'apprentissage, je ne vois pas comment on peut sérieusement utiliser
les variables globales dans ces fonctions. Dans les cursus de formation
des développeurs, les variables globales sont toujours présentées comme
l'une des plaies de la programmation, au côté de goto.
Sauf que la façon dont PHP est architecturé (avec le code dans *chaque*
page, par défaut), ne motive justement pas à faire des factorisations.
(oui on peut évidemment, non on n'y est pas encouragé)
Post by Mickael Wolff
Post by Patrick Mevzek
$_REQUEST fusionne $_GET et $_POST (entre autres) mais ils sont par
essence dans le *même* contexte (celui du web, c'est à dire contenu non
sûr provenant de l'utilisateur), donc leur fusion ne créé pas de
problème supplémentaire de sécurité.
Je pars du principe qu'aucune donnée n'est fiable. Quelle que soit ça
provenance, même si les données provenant de sources considérées comme
sûres doivent être considérées comme compromises :D Mais c'est un point
de vu paranoïaque.
De ce point de vue là on est d'accord, et donc vous êtes d'accord avec le
fait que $_REQUEST, $_GET, et $_POST ont exactement le même niveau de
sécurité (d'insécurité).
Post by Mickael Wolff
Maintenant je regrète : les contextes POST, GET et COOKIE sont
différents. Qu'ils proviennent de la même source ne permettent pas de
les considérer comme équivalent. Pourtant tu devrais le savoir, tu n'es
pas un abruti, mais je pense que tu n'as jamais observé la gueule d'une
requête. Si ces trois contextes étaient interchangeables, pourquoi
sont-ils séparés, et pourquoi leur sémantique (et donc leur
comportement) est-il si différent ?
Ils sont interchangeables *du point de vue de la sécurité*. J'ai bien dit
plusieurs fois, dans ce fil même, que GET et POST sont *sémantiquement*
différents et non interchangeables. Mais au niveau sécurité rattachée
c'est pareil et on ne peut *PAS* sécuriser une application en changeant
un get en post ou le contraire.
Post by Mickael Wolff
Post by Patrick Mevzek
Parce que le simple fait de changer un GET en POST ou le contraire
faisait 'planter' l'application ? Bah alors là le problème est ailleurs
et il me semble qu'on a discuté de cela récemment.
Mais alors où est-il ? Si on ne peut plus distinguer les données
saisies en POST et en GET ?
D'acord on le peut toujours techniquement. MAis la question est: cela a-t-
il un sens, et cela solutionne-t-il un quelconque problème de sécurité ?
Selon moi, non, car ce que vous présentez comme problème de sécurité
prétendûment résolu en POST et problèmatique en GET:
1) est en fait autant un problème en POST qu'en GET
2) n'est pas un problème de sécurité à la base, mais un problème
d'application mal concue, qui ne gère pas l'aspect sans états du HTTP
correctement, et ne met pas en oeuvre de bonnes pratiques relatives à
l'authentification, l'autorisation et les opérations délicates comme la
suppression (cf ma mention de jetons uniques dans un autre message).
Post by Mickael Wolff
Alors certes, pour vérifier que j'ai reçu
une requête POST je vérifie la clé 'REQUEST_METHOD' de la superglobale
$_SERVER, mais j'utilises tout de même $_POST et $_GET pour distinguer
la provenance des instructions. Simplement parce qu'une application
complexe peut requérir l'accès à une ressource ne même temps que la
modification d'une autre.
Vous voulez dire que vous avez une application qui réagit différemment
quand appelée en GET ou en POST sur la *même* URL ?
C'est bien sûr possible, mais la balance entre ce que cela apporte et ce
que cela peut causer comme désagréments n'est pas penchée du mauvais
côté ?
Post by Mickael Wolff
Mais aussi parce que l'ordre d'importation des
contextes est configurable, il n'y a aucune garantie de fonctionnement
alors.
Là pour le coup, je veux bien accepter cet argument... on dépend de la
configuration du serveur... sauf que ca ne concerne que le cas de la page
qui mélange des paramètres dans l'URL et dans le corps, ce qui
1) n'est pas forcément défini dans le standard (je n'ai pas vérifié)
2) est au moins pris en compte dans une API en jetant tout simplement la
partie GET (ce qui découle peut-être du 1), je ne sais pas).

Et puis si on veut blinder
1) on se refaire son $_REQUEST à soi avec import_request_variables()
avec un prefix non vide évidemment
ou
2) on assure, dans un .htaccess ou équivalent que variables_order est
positionné sainement.

Mais bon encore une fois je doute que cela soit un réel problème, sauf
pour les applications qui reagissent différemment à la même url en GET/
POST. Ce qui serait d'ailleurs plutôt enclin à montrer que c'est une
mauvaise idée :-)
Post by Mickael Wolff
En fait, avant d'utiliser $_REQUEST, tu vérifie la valeur de la
variable $_SERVER['REQUEST_METHOD'] ? Et finalement, lorsque tu es en
'POST' tu ignores les paramètres GET (donc en partie l'URL) ?
Si je dois donner mon petit cas particulier, pas forcément en PHP mais ca
donne
1) je ne m'occupe pas de REQUEST_METHOD car mon API d'accès aux variables
gère POST et GET de la même façon quant à la récupération des valeurs
2) je ne fais pas d'applications qui réagissent différemment à la même
URL selon que c'est GET ou POST
3) si je fais un POST je ne m'amuse pas à mettre de variables dans l'URL
car je me suis déjà fait piéger (genre la même variable aux deux
endroits... eh eh qui gagne ?) et mon API dans ce cas précis au final ne
considére pas ce qu'il y a dans le GET, histoire de trancher.
Post by Mickael Wolff
Post by Patrick Mevzek
Post by Mickael Wolff
Par exemple OsCommerce,
Wordpress, Dotclear, etc. C'est pourquoi je considère inconcevable
qu'on puisse conseiller l'usage de $_REQUEST à un débutant.
C'est tout à fait concevable et c'est même la bonne façon de faire.
Toutes les bonnes APIs de tous les langages de programmation offrent
une interface identique que l'on soit en GET en POST (tout en étant
capable de discriminer bien sûr quand on en a besoin), ce qui illustre
bien que le problème n'est pas là.
Tu as des noms d'API ? Ça m'intéresse en C++ ;)
Pas d'expérience directe, mais après une recherche je tombe sur
http://rudeserver.com/cgiparser/usage.html
et manifestement j'infère de
cgi["color"]
que ca sera toujours ca quelle que soit la méthode
(mais je peux me tromper, je n'ai pas lu toute la documentation).

Après je ne connais pas toutes les API C++, certaines font peut-être
comme PHP en séparant, d'autres non.
Post by Mickael Wolff
Post by Patrick Mevzek
Post by Mickael Wolff
D'ailleurs, j'espère que $_REQUEST dispara^itra un jour !
C'est le genre de paravent de mesure de sécurité. Supprimer $_REQUEST
n'augmentera en rien la sécurité des applications. Au contraire, un
"faux" sentiment de sécurité est bien pire selon moi que pas de
sécurité du tout, mais clairement avouée.
C'est vrai que de supprimer register_global est un paravent ;)
register_global n'est pas une mesure de sécurité c'est même une hénaurme
mesure d'insécurité dès le départ. L'enlever permet donc just de revenir
à la normale ;-)
--
Patrick Mevzek . . . . . . . . . . . . . . Dot and Co
<http://www.dotandco.net/> <http://www.dotandco.com/>
<http://www.dotandco.net/ressources/icann_registrars/prices>
<http://icann-registrars-life.dotandco.net/>
Mickael Wolff
2009-04-14 07:56:29 UTC
Permalink
Post by Patrick Mevzek
Ah bon ce n'est pas ca le problème de register_global ?
Bah je crois qu'il y a fort peu de chance qu'on soit d'accord sur quelque
chose si on n'est pas d'accord sur un fait de base comme ca.
C'est quoi alors selon vous le problème de register_global ?
Je pense que le vrai problème des register_global était la confusion
de tout et n'importe quoi, sans maitrise et sans controle des données
provenant de sources différentes.

Les variables globales ne sont accessible que depuis le scope global.
Donc tant qu'on codait proprement avec des fonctions, il n'y avait pas
de soucis.
Post by Patrick Mevzek
Sauf que la façon dont PHP est architecturé (avec le code dans *chaque*
page, par défaut), ne motive justement pas à faire des factorisations.
(oui on peut évidemment, non on n'y est pas encouragé)
Ce est la racine du mal, on est d'accord.
Post by Patrick Mevzek
De ce point de vue là on est d'accord, et donc vous êtes d'accord avec le
fait que $_REQUEST, $_GET, et $_POST ont exactement le même niveau de
sécurité (d'insécurité).
Complètement. Mais je pense que $_REQUEST ajoute un niveau de
confusion, c'est ce qui gene mon caractère anxieux.
Post by Patrick Mevzek
Ils sont interchangeables *du point de vue de la sécurité*. J'ai bien dit
plusieurs fois, dans ce fil même, que GET et POST sont *sémantiquement*
différents et non interchangeables. Mais au niveau sécurité rattachée
c'est pareil et on ne peut *PAS* sécuriser une application en changeant
un get en post ou le contraire.
Ce n'est pas exactement pareil. Mon propos était de dire que, si le
GET pouvait ^etre déclenché involontairement par l'utilisateur de
l'application, le POST ne le peut qu'avec beaucoup de difficultés
(Firefox n'autorises pas les requu^etes XHR transversales, et donc
neutralises la possibilité de faire des HTTP POST).
Post by Patrick Mevzek
D'acord on le peut toujours techniquement. MAis la question est: cela a-t-
il un sens, et cela solutionne-t-il un quelconque problème de sécurité ?
Selon moi, non, car ce que vous présentez comme problème de sécurité
1) est en fait autant un problème en POST qu'en GET
2) n'est pas un problème de sécurité à la base, mais un problème
d'application mal concue, qui ne gère pas l'aspect sans états du HTTP
correctement, et ne met pas en oeuvre de bonnes pratiques relatives à
l'authentification, l'autorisation et les opérations délicates comme la
suppression (cf ma mention de jetons uniques dans un autre message).
La technique des jetons est effectivement incontournable. Mais est-ce
que ça résoud complètement le problème que j'avais exposé ?
Post by Patrick Mevzek
Vous voulez dire que vous avez une application qui réagit différemment
quand appelée en GET ou en POST sur la *même* URL ?
C'est bien sûr possible, mais la balance entre ce que cela apporte et ce
que cela peut causer comme désagréments n'est pas penchée du mauvais
côté ?
On peut imaginer un formulaire d'authentification sur toutes les
pages d'un site, mais qu'on ne veuille pas accéder à la ressource « page
d'authentification » à chaque fois qu'on se logue, mais rester sur la
page de la ressource consultée actuellement. Dans ce cas, ce n'est pas
un contre-sens que de récupérer à la fois les données de consultation et
celles d'altération.
Post by Patrick Mevzek
Là pour le coup, je veux bien accepter cet argument... on dépend de la
configuration du serveur... sauf que ca ne concerne que le cas de la page
qui mélange des paramètres dans l'URL et dans le corps, ce qui
Tout à fait.
Post by Patrick Mevzek
1) n'est pas forcément défini dans le standard (je n'ai pas vérifié)
2) est au moins pris en compte dans une API en jetant tout simplement la
partie GET (ce qui découle peut-être du 1), je ne sais pas).
La norme de définit effectivement pas les variables qui seront
accessible via PHP ^^; Cependant, on sait qu'elles sont disponibles
puisque faisant partie de la Requiest-URI.
Post by Patrick Mevzek
Et puis si on veut blinder
1) on se refaire son $_REQUEST à soi avec import_request_variables()
avec un prefix non vide évidemment
ou
Ou sa classe http_request ;)
Post by Patrick Mevzek
2) on assure, dans un .htaccess ou équivalent que variables_order est
positionné sainement.
Il faut pouvoir l'imposer ;) Mais il y a d'autres possiblités
d'arriver au meme résultat.
Post by Patrick Mevzek
Mais bon encore une fois je doute que cela soit un réel problème, sauf
pour les applications qui reagissent différemment à la même url en GET/
POST. Ce qui serait d'ailleurs plutôt enclin à montrer que c'est une
mauvaise idée :-)
Ben en fait, RFC2616 section 9.5
<http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.5> :
« The POST method is used to request that the origin server accept the
entity enclosed in the request as a new subordinate of the resource
identified by the Request-URI in the Request-Line. »

Donc en fait, avec une lecture intégriste, les données concernant la
désignation de la ressource devraient etre passées dans l'URI. J'avais
essayé de faire ça. Mais c'est peut-etre un peu lourd gérer.
Post by Patrick Mevzek
Si je dois donner mon petit cas particulier, pas forcément en PHP mais ca
donne
1) je ne m'occupe pas de REQUEST_METHOD car mon API d'accès aux variables
gère POST et GET de la même façon quant à la récupération des valeurs
2) je ne fais pas d'applications qui réagissent différemment à la même
URL selon que c'est GET ou POST
3) si je fais un POST je ne m'amuse pas à mettre de variables dans l'URL
car je me suis déjà fait piéger (genre la même variable aux deux
endroits... eh eh qui gagne ?) et mon API dans ce cas précis au final ne
considére pas ce qu'il y a dans le GET, histoire de trancher.
C'est une façon, mais elle ne plait pas à ma compréhension du
protocole HTTP.
Post by Patrick Mevzek
Pas d'expérience directe
C'est ce m'intéresserait. Sinon je sais me servir, quelque peu, d'un
moteur de recherche :)
Post by Patrick Mevzek
register_global n'est pas une mesure de sécurité c'est même une hénaurme
mesure d'insécurité dès le départ. L'enlever permet donc just de revenir
à la normale ;-)
Un peu comme request :p (oui, lynchez moi !)
--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org
John GALLET
2009-04-14 09:04:53 UTC
Permalink
Bonjour,
Post by Mickael Wolff
Post by Patrick Mevzek
C'est quoi alors selon vous le problème de register_global ?
Je pense que le vrai problème des register_global était la confusion
de tout et n'importe quoi, sans maitrise et sans controle des données
provenant de sources différentes.
A mon sens, le *vrai* problème est (comme souvent) lié à l'interface
chaise-clavier: comme les développeurs ne savent pas initialiser une
variable, on peut injecter des variables depuis l'extérieur. Avoir
register_globals à off ou le retirer, c'est exclusivement encourager les
gens à porc-grammer(1) sans initialiser leur contexte. Mais nous
revenons là des années en arrière, ce qui est fait (contre l'avis de
Rasmus lui même) est fait.

(1) non, pas de faute de frappe.
Post by Mickael Wolff
Les variables globales ne sont accessible que depuis le scope global.
Donc tant qu'on codait proprement avec des fonctions, il n'y avait pas
de soucis.
Même pas besoin de fonctions (même si bien évidemment la factorisation
du code est souhaitable), il suffit d'initialiser ses variables. Ensuite
l'attaquant peut injecter ce qu'il veut, on s'en fout vu qu'on écrase sa
valeur. C'est quand même pas bien compliqué, surtout dans ce Brave New
World des frameworks et autres gadgets qui font tout même le café.
Post by Mickael Wolff
Complètement. Mais je pense que $_REQUEST ajoute un niveau de
confusion, c'est ce qui gene mon caractère anxieux.
Je ne vois pas où est la confusion, *au contraire*: TOUT ce qui vient du
monde extérieur sur la requête courante (et donc *par définition
dangereux*) est CENTRALISE dans ce tableau qui est une zone tampon des
choses dangereuses. Un guignol a eut l'idée géniale d'en retirer $_FILES
au bout d'un certain temps (j'avoue ne pas avoir suivi la raison
invoquée) alors que ça en fait partie, mais c'est bien à ça que ça sert.

Et soyons réalistes: combien de développeurs de web-app connaissent
aujourd'hui la vraie différence de protocole entre un get et un post et
ce que ça implique ? Il a fallu que je la rappelle pas plus tard qu'hier
vu les énormités proférées. Donc on ferait mieux de dire aux débutants:
côté serveur, vous vous posez pas la question de savoir COMMENT ça
arrive car votre problème c'est *d'où* ça arrive (i.e. de l'extérieur
donc dangereux). Ce qui n'empêche en rien de mettre dans la couche de
présentation la bonne méthode appropriée au besoin.
Post by Mickael Wolff
Ce n'est pas exactement pareil. Mon propos était de dire que, si le
GET pouvait ^etre déclenché involontairement par l'utilisateur de
l'application, le POST ne le peut qu'avec beaucoup de difficultés
Ah ? un coup de submit() en js ça le fait pas immédiatement en une ligne
de code ? (vraie question sans malice, j'avoue ne pas avoir fait de tests)
Post by Mickael Wolff
Post by Patrick Mevzek
register_global n'est pas une mesure de sécurité c'est même une
hénaurme mesure d'insécurité dès le départ. L'enlever permet donc just
de revenir à la normale ;-)
Un peu comme request :p (oui, lynchez moi !)
J'ai pas particulièrement le temps ni l'envie et de toutes façons ça a
peu d'importance. Il n'y a aucun trou de sécurité à utiliser
register_globals=On si le code est écrit proprement (il SUFFIT
d'initialiser ses variables, y compris les tableaux) et dans tous les
cas AUCUN trou de sécurité à taper directement côté serveur dans
_REQUEST au lieu de séparer _GET et _POST (c'est le contenu qui est
dangereux, pas la méthode de transmission).

L'essentiel c'est de filtrer le *contenu* des variables et de vérifier
la légitimité de la requête, pas de savoir si la variable a été
transmise par méthode get, post ou pigeon voyageur. Ou livreur de
machine à laver (private joke pour autre marronier en floraison
perpétuelle qui peut d'ailleurs se relier à celui-ci vu que header
location force un get).

a++;
JG
mpg
2009-04-14 21:15:08 UTC
Permalink
Post by John GALLET
L'essentiel c'est de filtrer le *contenu* des variables et de vérifier
la légitimité de la requête, pas de savoir si la variable a été
transmise par méthode get, post ou pigeon voyageur.
La RFC 1149 a réellement été implémentée ? ;-)

À part ça, même si ça tourne parfois un peu à la querelle de clocher, je
suis très content de lire cette discussion dans laquelle j'apprends des
choses, sérieusement.
--
Manuel Pégourié-Gonnard Institut de mathématiques de Jussieu
http://weblog.elzevir.fr/ http://people.math.jussieu.fr/~mpg/
John GALLET
2009-04-15 08:46:51 UTC
Permalink
Bonjour/soir,
Post by mpg
La RFC 1149 a réellement été implémentée ? ;-)
Le problème avec les pigeons voyageurs, c'est pas tant la détection de
collision (voir ci-dessous pour une solution pratique), c'est la perte
de paquets pendant l'ouverture de la chasse.
Post by mpg
À part ça, même si ça tourne parfois un peu à la querelle de clocher, je
suis très content de lire cette discussion dans laquelle j'apprends des
choses, sérieusement.
Ca aura au moins servi à quelque chose. Mais si on regarde la situation
et les discussions d'il y a 4-5 ans et de maintenant, ça n'a pas
beaucoup évolué. D'ailleurs, à part les problèmes liés à ajax qui en
rajoute sur les dangers de l'encodage pour les XSS, on n'a pas beaucoup
évolué dans le besoin non plus.
JG
--
JR> Le progrès. Maintenant sur CD à dos de chameau. Quel protocole?
La détection de collision. Si deux chameaux se téléscopent, on
retransmet un kangourou.
-+- JYB in GNU : C'est cha mot pour mot -+-
Mickael Wolff
2009-04-22 20:04:08 UTC
Permalink
Post by John GALLET
Post by Mickael Wolff
Je pense que le vrai problème des register_global était la confusion
de tout et n'importe quoi, sans maitrise et sans controle des données
provenant de sources différentes.
A mon sens, le *vrai* problème est (comme souvent) lié à l'interface
chaise-clavier: comme les développeurs ne savent pas initialiser une
variable, on peut injecter des variables depuis l'extérieur. Avoir
register_globals à off ou le retirer, c'est exclusivement encourager les
gens à porc-grammer(1) sans initialiser leur contexte. Mais nous
revenons là des années en arrière, ce qui est fait (contre l'avis de
Rasmus lui même) est fait.
Je pense que le manque de discernement conduit irrémédiablement à des
erreurs graves de design. et que Lerdorf ne soit pas d'accord n'est pas
vraiment un argument de poids. Pour lui, sa manière d'éviter les
problèmes dont nous parlons, c'est d'utiliser plusieurs navigateurs
différents selon l'usage qu'il en a. Dans ce cas, pas besoin de se
soucier du canal de transmission les données :p
Post by John GALLET
Post by Mickael Wolff
Les variables globales ne sont accessible que depuis le scope
global. Donc tant qu'on codait proprement avec des fonctions, il n'y
avait pas de soucis.
Même pas besoin de fonctions (même si bien évidemment la factorisation
du code est souhaitable), il suffit d'initialiser ses variables. Ensuite
l'attaquant peut injecter ce qu'il veut, on s'en fout vu qu'on écrase sa
valeur. C'est quand même pas bien compliqué, surtout dans ce Brave New
World des frameworks et autres gadgets qui font tout même le café.
Dans ce cas-là, quel est l'intéret de register_global si tu écrases
les données ?
Post by John GALLET
Je ne vois pas où est la confusion, *au contraire*: TOUT ce qui vient du
monde extérieur sur la requête courante (et donc *par définition
dangereux*) est CENTRALISE dans ce tableau qui est une zone tampon des
choses dangereuses. Un guignol a eut l'idée géniale d'en retirer $_FILES
au bout d'un certain temps (j'avoue ne pas avoir suivi la raison
invoquée) alors que ça en fait partie, mais c'est bien à ça que ça sert.
Très honetement, je préfère mon objet http_request ;) Qui centralisee
sans confondre.
Post by John GALLET
Et soyons réalistes: combien de développeurs de web-app connaissent
aujourd'hui la vraie différence de protocole entre un get et un post et
ce que ça implique ?
Ce n'est pas parce que l'incompétence domine que je m'y plierait.
Post by John GALLET
Il a fallu que je la rappelle pas plus tard qu'hier
côté serveur, vous vous posez pas la question de savoir COMMENT ça
arrive car votre problème c'est *d'où* ça arrive (i.e. de l'extérieur
donc dangereux). Ce qui n'empêche en rien de mettre dans la couche de
présentation la bonne méthode appropriée au besoin.
Faut que je termine mon tutoriel :D
Post by John GALLET
Ah ? un coup de submit() en js ça le fait pas immédiatement en une ligne
de code ? (vraie question sans malice, j'avoue ne pas avoir fait de tests)
Il faut pouvoir injecter le javascript dans un premier temps.
--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org
John GALLET
2009-04-24 13:58:58 UTC
Permalink
Dans ce cas-là, quel est l'intéret de register_global si tu écrases les
données ?
M'enfin !! "J'écrase" en les initialisant correctement les éventuelles
variables injectées à l'insu de mon plein gré, si j'écrasais les arguments
reçus je ne les recevrais pas...

Quand on développait avec register_globals à On la seule chose que ça
changeait c'était ça:

Version On:
$safe=filtrer($unsafe);
$locale=0; // si toto me passe http://...../...&locale=dangereux
...

Version Off:
$safe=filtrer($_REQUEST['unsafe']);
$locale=0; // mais là on se fout que toto m'envoie ...&locale=dangereux
c'est juste pour faire propre

Je comprends que bon nombre de contributeurs qui débatent aujourd'hui
n'aient aucune expérience de production de ce qu'était PHP3, mais faut
quand même pas prendre les anciennes méthodes pour des passoires.
Ce n'est pas parce que l'incompétence domine que je m'y plierait.
Et ce n'est pas parce qu'on raconte n'importe quoi sur la soit-disant
sécurité supplémentaire qu'apporte la vérification de la méthode de
transmission http des variables que c'est vrai. Si un attaquant n'est même
pas capable de t'envoyer les données comme tu t'attends à les recevoir en
regardant ton code html, il n'est pas bien dangereux à la base...
Ah ? un coup de submit() en js ça le fait pas immédiatement en une ligne de
code ? (vraie question sans malice, j'avoue ne pas avoir fait de tests)
Il faut pouvoir injecter le javascript dans un premier temps.
Je ne te parle pas d'injecter quoi que ce soit, je te parle d'envoyer des
données dangereuses à tes scripts PHP dans la variable serveur où tu
t'attends à les y trouver. Ce qui anéantit tout intérêt de vérification.

a++;
JG

mpg
2009-04-10 07:36:03 UTC
Permalink
Post by Mickael Wolff
Je pense que par nommage branché tu désigne la distinction des
données soumises en $_POST ou en $_GET.
Je ne sais pas ce que voulait dire Sylvain, mais pour ma part, même si je
perçois plutôt bien la différence technique entre GET et POST (mais peut-être
pas encore toutes les implications que ça a au niveau sécurité, je lis
attentivement ton exemple et ses commentaires à ce sujet), je n'arrive pas à
voir en quoi l'un représente des « données d'alteration » et l'autre « de
consultation ». Peux-tu détailler ce qui se cache derrière ces deux mots ?

Merci,
--
Manuel Pégourié-Gonnard Institut de mathématiques de Jussieu
http://weblog.elzevir.fr/ http://people.math.jussieu.fr/~mpg/
Paul
2009-04-10 13:51:23 UTC
Permalink
Post by mpg
Post by Mickael Wolff
Je pense que par nommage branché tu désigne la distinction des
données soumises en $_POST ou en $_GET.
Je ne sais pas ce que voulait dire Sylvain, mais pour ma part, même si je
perçois plutôt bien la différence technique entre GET et POST (mais peut-être
pas encore toutes les implications que ça a au niveau sécurité, je lis
attentivement ton exemple et ses commentaires à ce sujet), je n'arrive pas à
voir en quoi l'un représente des « données d'alteration » et l'autre « de
consultation ». Peux-tu détailler ce qui se cache derrière ces deux mots
Bien sûr, qu'il peut, et peut être même va t il le faire.... Mais pour
dire quoi ? qu'il s'agit d'une pratique sodomite des hyménoptéres courants ?
Mickael Wolff
2009-04-14 07:56:29 UTC
Permalink
Post by Paul
Bien sûr, qu'il peut, et peut être même va t il le faire....
Ouaip. Mais d'abord je m'occupe des insultes.
Post by Paul
Mais pour dire quoi ? qu'il s'agit d'une pratique sodomite des hyménoptéres
courants ?
Non, pour dire que pour freiner en urgence on utilises le frein
arrière, et pas le frein avant, sinon on fait un soleil.
--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org
Mickael Wolff
2009-04-10 21:43:56 UTC
Permalink
Post by Yannick
je n'arrive pas à
voir en quoi l'un représente des « données d'alteration » et l'autre « de
consultation ». Peux-tu détailler ce qui se cache derrière ces deux mots ?
Bien sûr je peux détaille, et avec plaisir.

GET se traduit par « prendre » (consultation)
POST peut se traduire par « soumettre » (altération)

Par consultation, je pense bien sûr à la lecture des données. Par
altération, je considère l'ajout, la modification et la suppression
d'une ressource (un article, un contact, etc).

Les méthodes existantes sont listées et décrites dans la RFC 2616
<http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9>.
D'ailleurs, ce que je dis, y est exposé en moins extrémiste :

« In particular, the convention has been established that the GET and
HEAD methods SHOULD NOT have the significance of taking an action other
than retrieval. These methods ought to be considered "safe". This allows
user agents to represent other methods, such as POST, PUT and DELETE, in
a special way, so that the user is made aware of the fact that a
possibly unsafe action is being requested. »

La seule différence majeure entre ce que j'affirme et ce que déclare
le RFC, c'est je dis MUST NOT plutôt que SHOULD NOT. Ceci signifie
simplement que GET ne devrait pas être utilisé pour modifier des données.

Cependant je pense que cet usage devrait être bannit de nos habitudes
pour des problèmes évidents (enfin, pas tant que ça visiblement :p ) de
sécurité.

Le protocole HTTP prévoie donc que la méthode GET ne devrait être
utilisée que pour requérir des données, et non les modifier. Car la
méthode GET ne requiert pas d'action explicite de l'utilisateur.
--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org
Sylvain SF
2009-04-13 13:16:26 UTC
Permalink
Post by Mickael Wolff
Les méthodes existantes sont listées et décrites dans la RFC 2616
les méthodes, quelles méthodes ?? celles de la construction d'une URL
(au niveau applicatif) ou celles du fonctionnement du serveur ?

si cette RFC répondait au problème débattu ici, tu aurais utilisé une
commande DELETE pour effacer ta fiche 42.
Post by Mickael Wolff
« In particular, the convention has been established that the GET and
HEAD methods SHOULD NOT have the significance of taking an action other
than retrieval. These methods ought to be considered "safe". This allows
user agents to represent other methods, such as POST, PUT and DELETE, in
a special way, so that the user is made aware of the fact that a
possibly unsafe action is being requested. »
donc après avoir affirmé que rien n'est sur ("Je pars du principe
qu'aucune donnée n'est fiable." - pas même tes propres variables
$_SESSION), tu t'appuies sur une prétendue "safety" pour défendre
le point ?! j'ai du mal à suivre.

toute requête GET comme POST pour être forgée à fin d'attaque,
l'argument est non recevable.

une différence évidente entre les protocoles GET et POST est simplement
la taille maximale des données transmises.

la taille de la seule URI (donc la taille des params GET) est limité
par le browser (de 2Ko (IE) à 64Ko (FireFox) ou plus) et par le serveur
(+/- 4Ko pour Apache); la taille des params POST est (virtuellement
illimité).

donc oui, il fait sens de "demander" (GET) la fiche 42 via un GET, et
il fait sens de transmettre le contenu de cette fiche (pour stockage
sur serveur) via un POST (les exemples du § 9.5 de RFC 2616 ne montrent
rien d'autre que des opérations "volumineuses").

le choix du protocole GET ou POST n'est donc que motivé par les tailles
d'échanges supportées, en aucun cas par de pseudo-sécurités, en aucun
cas par des traductions opportunistes.
Post by Mickael Wolff
Le protocole HTTP prévoie donc que la méthode GET ne devrait être
utilisée que pour requérir des données, et non les modifier.
du fait de la taille des arguments transmis.
et pratiquement, du fait que les arguments POST peuvent être lus
par bloc, spoolés, etc, alors que l'URL GET doit être entièrement
reçue pour invoquer le bon script, accéder au bon fichier.
Post by Mickael Wolff
Car la méthode GET ne requiert pas d'action explicite de l'utilisateur.
de quelle action parles-tu ? cliquer sur un lien (GET) est aussi
explicite que de cliquer sur un bouton (d'un FORM POST).

Sylvain.
John GALLET
2009-04-13 14:59:54 UTC
Permalink
Post by Sylvain SF
une différence évidente entre les protocoles GET et POST est simplement
la taille maximale des données transmises.
Tellement évidente que c'est une conséquence et non une cause: c'est la
méthode d'encodage qui est différente, et seulement celle-ci en ce qui
concerne le dialogue tcp/ip. Ceci a pour effet de bord accessoire qu'en
général, selon le navigateur et le serveur, la méthode get est
effectivement plus limitée en taille, mais ce n'est pas toujours le cas,
selon le navigateur et le serveur il y a aussi des restrictions de
taille sur le post.
Post by Sylvain SF
le choix du protocole GET ou POST n'est donc que motivé par les tailles
d'échanges supportées, en aucun cas par de pseudo-sécurités, en aucun
cas par des traductions opportunistes.
Non, autant je suis le premier à dire depuis des années qu'on se
tamponne de le re-vérifier côté serveur, autant là c'est abuser en
simplification pour le choix de la méthode à indiquer dans la couche de
présentation.

Une des autres différences majeures entre les deux méthodes est son
traitement côté serveur dans les logs et côté client dans le referrer.

Donc il est évident (?) qu'on va transmettre les paramètres sensibles
(données de carte bancaire si on doit malheureusement les gèrer, login
et mot de passe) en POST pour qu'il ne soient pas connement stockés en
clair dans les logs http (qui ne sont que très rarement considérés comme
contenant des données confidentielles donc improprement peu protégés et
ne devraient JAMAIS en contenir en DMZ), et qu'il faut faire un minimum
attention aux XSS involontaires par referer.

On voit ci-dessous la différence d'encodage en envoyant les mêmes
données (variable id_client valant 12345 et mode valant full, exemple
bateau sur un entier et une string pour montrer qu'on s'en fout), en
particulier le content-type pour le post. La requête est faite depuis le
client 192.168.0.1 qui envoie les données à .2 après avoir demandé la
page une première fois (cf referer).

On remarquera au passage que pour des faibles volumes de données, ce qui
bouffe le plus la BP ce sont toutes les conneries ajoutées par le
navigateur, mais c'est une autre histoire...

a++;
JG


Exemples en capture de trame IP par tcpdump (après décodage) et log apache:

Capture GET - ASCII (décodée)

12:08:10.134499 IP 192.168.0.1.29518 > 192.168.0.2.http: P 0:503(503)
ack 1 win 65535 <nop,nop,timestamp 1414277 77576113>
E..+....7.F..)j`..;.sN.Pd4g..6.......s.....
........GET /a.php?id_client=12345&mode=full HTTP/1.1
Host: www.192.168.0.2
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.11)
Gecko/20050729
Accept:text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;
q=0.5
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Referer: http://192.168.0.2/a.php
Cache-Control: max-age=0
Connection: Keep-Alive
X-BlueCoat-Via: 9162C0441D1EC4D6

Trace associée dans le log Apache :

192.168.0.1 - - [06/Dec/2006:12:08:10 +0100] "GET
/a.php?id_client=12345&mode=full HTTP/1.1" 200 340
"http://192.168.0.2/a.php" "Mozilla/5.0 (X11; U; Linux i686; en-US;
rv:1.7.11) Gecko/20050729"


Capture POST - ASCII décodée
12:08:27.381567 IP 192.168.0.1.29756 > 192.168.0.2.http: P 0:572(572)
ack 1 win 65535 <nop,nop,timestamp 1414312 77577837>
E..p....7.)..)j`..;.t<.P4h.V..b
...........
.......mPOST /a.php HTTP/1.1
Host: 192.168.0.2
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.11)
Gecko/20050729
Accept:
text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;
q=0.5
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Referer: http://192.168.0.2/a.php?id_client=12345&mode=full
Content-Type: application/x-www-form-urlencoded
Content-Length: 25
Connection: Keep-Alive
X-BlueCoat-Via: 9162C0441D1EC4D6

id_client=12345&mode=full
12:08:27.564526 IP 192.168.0.1.29756 > 192.168.0.2.http: . ack 523 win
65535 <nop,nop,timestamp 1414312 77577838>
E..4.,..7.+~.)j`..;.t<.P4h....d............
.......n

Trace associée dans le log Apache :

192.168.0.1 - - [06/Dec/2006:12:08:27 +0100] "POST /a.php HTTP/1.1" 200
340 "http://192.168.0.2/a.php?id_client=12345&mode=full" "Mozilla/5.0
(X11; U; Linux i686; en-US; rv:1.7.11) Gecko/20050729"
Mickael Wolff
2009-04-22 20:04:08 UTC
Permalink
Post by Sylvain SF
les méthodes, quelles méthodes ?? celles de la construction d'une URL
(au niveau applicatif) ou celles du fonctionnement du serveur ?
La méthode HTTP évidemment.
Post by Sylvain SF
si cette RFC répondait au problème débattu ici, tu aurais utilisé une
commande DELETE pour effacer ta fiche 42.
La RFC apporte des éléments de réponse. Ensuite, chacun interpete le
Texte.
Post by Sylvain SF
donc après avoir affirmé que rien n'est sur ("Je pars du principe
qu'aucune donnée n'est fiable." - pas même tes propres variables
$_SESSION), tu t'appuies sur une prétendue "safety" pour défendre
le point ?! j'ai du mal à suivre.
C'est peut-etre mal exprimé, ce que je voulais dire c'est que je
tente de toujours rester en alert face aux données. On ne sait jamais ce
qu'il peut arriver.
Post by Sylvain SF
toute requête GET comme POST pour être forgée à fin d'attaque,
l'argument est non recevable.
Le problème n'était pas là. Le POST peut certes etre forgé, mais
c'est plus difficile de contraindre l'utilisateur à soumettre le
formulaire. Et meme avec du javascript, il faut déjà etre parvenu à
injecter du javascript.
Post by Sylvain SF
une différence évidente entre les protocoles GET et POST est simplement
la taille maximale des données transmises.
En théorie, non :p Mais cette limitation n'est pas un problème tant
qu'on respecte la sémantique des méthodes HTTP.
Post by Sylvain SF
le choix du protocole GET ou POST n'est donc que motivé par les tailles
d'échanges supportées, en aucun cas par de pseudo-sécurités, en aucun
cas par des traductions opportunistes.
La taille ne devrait pas entrer en ligne de compte dans le choix du
canal de transmission. Mais 8ko c'est déjà énorme.
Post by Sylvain SF
Post by Mickael Wolff
Le protocole HTTP prévoie donc que la méthode GET ne devrait être
utilisée que pour requérir des données, et non les modifier.
du fait de la taille des arguments transmis.
Je pense que tu confonds la cause et la conséquence ;p
Post by Sylvain SF
Post by Mickael Wolff
Car la méthode GET ne requiert pas d'action explicite de l'utilisateur.
de quelle action parles-tu ? cliquer sur un lien (GET) est aussi
explicite que de cliquer sur un bouton (d'un FORM POST).
Mais comme je l'ai déjà expliqué, il n'est pas nécessaire de devoir
cliquer pour soumettre un HTTP GET. Il n'y a pas que <a> dans la viv!e
--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org
Olivier Miakinen
2009-04-13 13:16:25 UTC
Permalink
Bonjour
Post by Mickael Wolff
Post by Yannick
je n'arrive pas à
voir en quoi l'un représente des « données d'alteration » et l'autre « de
consultation ». Peux-tu détailler ce qui se cache derrière ces deux mots ?
GET se traduit par « prendre » (consultation)
POST peut se traduire par « soumettre » (altération)
Par consultation, je pense bien sûr à la lecture des données. Par
altération, je considère l'ajout, la modification et la suppression
d'une ressource (un article, un contact, etc).
Attention cependant à ne pas confondre la requête GET avec les valeurs
de $_GET ni la requête POST avec les valeurs de $_POST. Même s'il est
vrai qu'une requête GET ne transmet pas de valeurs dans $_POST,
l'inverse peut être faux (quelque mal que l'on puisse penser d'un
POST transmettant des données dans $_GET).
Post by Mickael Wolff
Les méthodes existantes sont listées et décrites dans la RFC 2616
<http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9>.
« In particular, the convention has been established that the GET and
HEAD methods SHOULD NOT have the significance of taking an action other
than retrieval. These methods ought to be considered "safe". This allows
user agents to represent other methods, such as POST, PUT and DELETE, in
a special way, so that the user is made aware of the fact that a
possibly unsafe action is being requested. »
Ici, il s'agit des types de requêtes (GET, HEAD, POST, PUT et DELETE),
pas des types de transmission de données (ceux que PHP appelle $_GET et
$_POST).
Post by Mickael Wolff
La seule différence majeure entre ce que j'affirme et ce que déclare
le RFC, c'est je dis MUST NOT plutôt que SHOULD NOT. Ceci signifie
simplement que GET ne devrait pas être utilisé pour modifier des données.
Àmha, la différence majeure est surtout que la discussion était sur
le canal de transmission des données, absolument pas sur le type de requête.
Post by Mickael Wolff
Cependant je pense que cet usage devrait être bannit de nos habitudes
pour des problèmes évidents (enfin, pas tant que ça visiblement :p ) de
sécurité.
Tu as raison : visiblement il n'est pas si évident de distinguer le type
de requête du type de transmission des données. Tu es bien excusable,
cela dit, tant il est vrai que $_GET/$_POST font penser à GET/POST.
Post by Mickael Wolff
Le protocole HTTP prévoie donc que la méthode GET ne devrait être
utilisée que pour requérir des données, et non les modifier. Car la
méthode GET ne requiert pas d'action explicite de l'utilisateur.
Nous sommes d'accord. Un bon concepteur programmera donc une méthode GET
pour requérir des données et une méthode POST pour les modifier. Mieux :
il prévoiera de transmettre les données dans $_GET quand il programme
une requête GET (paramètres dans l'URL), et dans $_POST quand il prévoit
une requête POST (par un formulaire).

*MAIS* il ne doit pas avoir besoin de vérifier par quel canal l'informa-
tion a été transmise pour assurer sa sécurité. La sécurité doit être
assurée par les valeurs elles-mêmes et non par le mode de transmission.
Si vérifier le canal de transmission est nécessaire pour assurer la
sécurité, alors c'est que la sécurité est intrinsèquement mauvaise et
qu'il faut faire autrement (cas du delete que tu me donnais en exemple
dans un autre article).

En effet, si un attaquant est capable d'amener une victime à faire un
GET donné, ou un POST donné avec variables dans $_GET, alors il pourrait
tout aussi bien amener une victime (la même ou une autre) à faire un
POST avec toutes ces données dans $_POST. Et si l'attaquant sait quelles
valeurs mettre pour faire une opération non voulue (comme un delete dans
une base de données), c'est que la sécurité est mauvaise au départ.
mpg
2009-04-14 07:56:29 UTC
Permalink
Post by Olivier Miakinen
Attention cependant à ne pas confondre la requête GET avec les valeurs
de $_GET ni la requête POST avec les valeurs de $_POST. Même s'il est
vrai qu'une requête GET ne transmet pas de valeurs dans $_POST,
l'inverse peut être faux (quelque mal que l'on puisse penser d'un
POST transmettant des données dans $_GET).
Bon, question stupide dans mon précédent message, je viens de comprendre.
Il s'agissait de requêtes comme

POST /foo.php?var=value HTTP/1.1

Mes doigts ont été plus rapides que mes neurones, désolé pour le bruit.
--
Manuel Pégourié-Gonnard Institut de mathématiques de Jussieu
http://weblog.elzevir.fr/ http://people.math.jussieu.fr/~mpg/
John GALLET
2009-04-14 09:04:53 UTC
Permalink
Bonjour,
Post by mpg
Bon, question stupide dans mon précédent message, je viens de comprendre.
Non, pas stupide du tout. C'est tellement tordu à la fois comme syntaxe
et comme comportement serveur que si on l'a pas vu une fois dans sa vie
ça fait quand même drôle quand on y est confronté la première fois.
Post by mpg
Il s'agissait de requêtes comme
POST /foo.php?var=value HTTP/1.1
Exactement, générées en html par exemple par:

<form action="foo.php?var=value method="post">
<input type="text" name="varpost">
...

On aura alors var dans $_GET et varpost dans $_POST
Post by mpg
Mes doigts ont été plus rapides que mes neurones, désolé pour le bruit.
Ce n'est pas du bruit. Moult contributeurs de ce forum n'ont jamais
rencontré le cas qui nécessite à la fois du code html d'une syntaxe
discutable et la connaissance du fonctionnement interne de php au lieu
de croire (faussement) que method="post" implique nécessairement toutes
variables dans $_POST.

On est bien d'accord, c'est un cas "tordu".

a++;
JG
mpg
2009-04-14 07:56:29 UTC
Permalink
Post by Olivier Miakinen
Attention cependant à ne pas confondre la requête GET avec les valeurs
de $_GET ni la requête POST avec les valeurs de $_POST. Même s'il est
vrai qu'une requête GET ne transmet pas de valeurs dans $_POST,
l'inverse peut être faux (quelque mal que l'on puisse penser d'un
POST transmettant des données dans $_GET).
Hum, j'avoue que je suis perdu. Je viens de relire les pages du manuel
PHP concernant $_GET et $_POST sans y trouver d'indice concernant la
possibilité de passer des données dans $_GET avec une requête POST.

Quelqu'un peut-il m'expliquer (ou m'indiquer la partie de la doc PHP ou
de la RFC adéquate que j'ai manquée) ?

Merci,
--
Manuel Pégourié-Gonnard Institut de mathématiques de Jussieu
http://weblog.elzevir.fr/ http://people.math.jussieu.fr/~mpg/
John GALLET
2009-04-13 13:16:26 UTC
Permalink
Bonjour/soir,

Etant historiquement un des premiers casse-c***lles à avoir mis les pieds
dans le plat il y a bien des années, je me marre quand même de voir qu'on
a toujours pas avancé d'un iota sur ce genre de querelles de clocher.
La seule différence majeure entre ce que j'affirme et ce que déclare le
RFC, c'est je dis MUST NOT plutôt que SHOULD NOT. Ceci signifie simplement
que GET ne devrait pas être utilisé pour modifier des données.
Ne serait-ce qu'à cause des robots qui foutent le bordel partout, je suis
grosso merdo d'accord. Mais je trouve quand même franchement bourrin de
refuser un get juste pour les changements de "contexte de navigation" (par
exemple pour un site multilangue passer du français à l'anglais en
cliquant sur un drapeau, on va faire un JS pour forcer la méthode post ?
Mouarf !!).

En revanche, je sépare bien là aussi le SHOULD (côté html) du MUST
(re-vérifié côté serveur).
Cependant je pense que cet usage devrait être bannit de nos habitudes pour
des problèmes évidents (enfin, pas tant que ça visiblement :p ) de sécurité.
Je ne vois vraiment pas où se trouve le problème. Dans la couche de
présentation, on met la bonne méthode (get/post) en la générant. Et côté
serveur on s'en branle complètement de savoir si les données ont
effectivement été envoyées de la "bonne" manière parce que de toutes
façons c'est trop tard, elles sont reçues donc le problème c'est de savoir
si elles sont légitimes ou pas, et la méthode de transmission n'est pas,
loin de là, le facteur déterminant. Si ton propos est de dire qu'il faut
aussi revérifier côté serveur que ce qui devait être envoyé en post l'a
effectivement été, je pense que c'est plus que superflu et que ça génère
plus d'emmerdements que ça n'apporte quoi que ce soit (i.e: rien) mais
après tout c'est légitime.

Je ne parlerai même pas de tous les compteurs de visites et trucs à la
noix où un img src appelle (en post ?! arf !) un script php qui modifie
des données côté serveur avant de faire un bon vieux readfile sur
pouet.jpg
Car la méthode GET ne requiert pas d'action explicite de l'utilisateur.
Pas toujours en tous cas. Quand toto clique sur un href c'est bien du get
(sauf JS de wrapping) et c'est bien une action explicite. Et ça "peut"
légitimement changer des données côté serveur, en particulier tout ce que
j'appellerais "contextuelles" (i.e. qui meurent avec la session/fin de
navigation).

a++;
JG
Mickael Wolff
2009-04-22 20:04:08 UTC
Permalink
Post by John GALLET
Post by Mickael Wolff
La seule différence majeure entre ce que j'affirme et ce que déclare
le RFC, c'est je dis MUST NOT plutôt que SHOULD NOT. Ceci signifie
simplement que GET ne devrait pas être utilisé pour modifier des données.
Ne serait-ce qu'à cause des robots qui foutent le bordel partout, je
suis grosso merdo d'accord. Mais je trouve quand même franchement
bourrin de refuser un get juste pour les changements de "contexte de
navigation" (par exemple pour un site multilangue passer du français à
l'anglais en cliquant sur un drapeau, on va faire un JS pour forcer la
méthode post ? Mouarf !!).
Ah oui mais non. Dans l'idéal, il y à la négociation de contenu via
HTTP :p Mais personnellement, je pense que changer de langue correspond
à la sémantique de $_GET, parce que finalement, on ne fait qu'accéder à
une ressource spécialisée linquistiquement.
Post by John GALLET
Post by Mickael Wolff
Cependant je pense que cet usage devrait être bannit de nos habitudes
pour des problèmes évidents (enfin, pas tant que ça visiblement :p )
de sécurité.
Je ne vois vraiment pas où se trouve le problème. Dans la couche de
présentation, on met la bonne méthode (get/post) en la générant. Et côté
serveur on s'en branle complètement de savoir si les données ont
effectivement été envoyées de la "bonne" manière parce que de toutes
façons c'est trop tard, elles sont reçues donc le problème c'est de
savoir si elles sont légitimes ou pas, et la méthode de transmission
n'est pas, loin de là, le facteur déterminant.
Le requete soumise n'est pas forcément émise par notre bébé. lorsque
les données sont reçues, elles sont pretes à etre disséquées. Et le
canal de transmission est un INDICE d'attaque potentielle.
Post by John GALLET
Si ton propos est de dire
qu'il faut aussi revérifier côté serveur que ce qui devait être envoyé
en post l'a effectivement été, je pense que c'est plus que superflu et
que ça génère plus d'emmerdements que ça n'apporte quoi que ce soit
(i.e: rien) mais après tout c'est légitime.
Je ne suis pas un adepte du naturisme, effectivement ;) (Naked
Objects Pattern)
Post by John GALLET
Je ne parlerai même pas de tous les compteurs de visites et trucs à la
noix où un img src appelle (en post ?! arf !) un script php qui modifie
des données côté serveur avant de faire un bon vieux readfile sur pouet.jpg
Comment tu fais un HTTP POST avec un lien ?
Post by John GALLET
Post by Mickael Wolff
Car la méthode GET ne requiert pas d'action explicite de l'utilisateur.
Pas toujours en tous cas. Quand toto clique sur un href c'est bien du
get (sauf JS de wrapping) et c'est bien une action explicite. Et ça
"peut" légitimement changer des données côté serveur, en particulier
tout ce que j'appellerais "contextuelles" (i.e. qui meurent avec la
session/fin de navigation).
J'ai dit « ne requiert pas » et non pas « exclut ». Une balise img,
ou quel qu'autre balise référençant une ressource externe au document
HTML est chargé automatiquement. C'est autant de HTTP GET implicites.
Bien évidemment, pour que ça marche, il faut que l'utilisateur soit
logué dans l'application web visée.

La distinction entre $_GET et $_POST permet de maitriser la
provenance des données, ça ne peut qu'améliorer la sécurité.
--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org
Olivier Miakinen
2009-04-22 21:33:52 UTC
Permalink
[...] le canal de transmission est un INDICE d'attaque potentielle.
Oui, tu as raison, bien sûr. Et John a raison aussi. Le seul point de
désaccord concerne l'importance relative des « indices » en question.

Prenons une donnée dont il soit assez important d'assurer la sécurité.
Mettons par exemple qu'il soit acceptable qu'elle puisse être compromise
une fois toutes les 2^100 attaques par un pirate. Pour la protéger, on
génère un jeton unique de 128 bits, un pirate pouvant le deviner au
hasard environ une fois toutes les 2^128 requêtes. Bon, si l'on suppose
que ton serveur est très utilisé et qu'il y a un millier de tels jetons
valides au moment de l'attaque, cela fait une chance sur 2^128/2^10,
soit 2^118. On reste au dessus des 2^100.

Supposons maintenant que tu contrôles si les données sont dans $_GET ou
$_POST. En supposant que le pirate choisisse au hasard entre les deux
(oui, je sais que ce n'est pas comme ça que ça se passe, j'y reviens
tout de suite), tu multiplies le nombre d'essais nécessaires par 2^1,
soit donc 2^119 au lieu de 2^118. Bien sûr, en réalité le pirate ne
choisit pas au hasard : il peut très facilement savoir quel type de
requête il faut faire, et soit il sait le faire facilement (on reste à
2^118), soit ça lui rajoute des difficultés peut-être supérieures à 2^1
(et dans ce cas on dépassera les 2^119, mais je doute vraiment que le
cas soit si fréquent pour quelqu'un déjà capable de franchir le cap des
2^100).


En résumé :

1) Contrôler le canal de transmission peut être un INDICE d'attaque
potentielle.

2) Mais si la donnée à protéger est vraiment sensible, alors augmenter
le nombre de bits du jeton de contrôle devrait donner à cet INDICE une
importance suffisamment faible pour qu'il ne soit pas nécessaire de
distinguer $_GET de $_POST.


-------------------------------------------------------------------------
En résumé du résumé : tu peux bien contrôler $_GET et $_POST si ça te
chante, mais pas te moquer de ceux qui n'utilisent que $_REQUEST et qui
placent leurs contrôles de sécurité ailleurs.
-------------------------------------------------------------------------
Post by John GALLET
Je ne parlerai même pas de tous les compteurs de visites et trucs à la
noix où un img src appelle (en post ?! arf !) un script php qui modifie
des données côté serveur avant de faire un bon vieux readfile sur pouet.jpg
Comment tu fais un HTTP POST avec un lien ?
Euh... là, je crois bien que tu es passé à côté de l'humour (certes
particulier) de John : c'est justement parce que l'on ne peut pas faire
de HTTP POST avec un lien que l'on ne peut pas interdire de modifier des
données avec un GET. Quoique... ce n'est pas moi qui me plaindrais de
voir disparaître tous ces compteurs de visite à la noix (ça sert à quoi
que webalizer il se décarcasse ?)
La distinction entre $_GET et $_POST permet de maitriser la
provenance des données, ça ne peut qu'améliorer la sécurité.
Encore une fois tu as raison : toutes choses étant égales par ailleurs,
distinguer entre $_GET et $_POST ne peut pas diminuer la sécurité, ça ne
peut donc que l'améliorer. Simplement, la question que je pose est « de
combien ? ». Et l'effort fait pour se poser la question « à la ligne N,
dois-je écrire $_GET ou $_POST », aussi minime soit-il, n'est-il pas
supérieur au gain que l'on peut en retirer en terme de sécurité ?


Cordialement,
--
Olivier Miakinen
Denis Beauregard
2009-04-22 22:50:06 UTC
Permalink
Post by Olivier Miakinen
hasard environ une fois toutes les 2^128 requêtes. Bon, si l'on suppose
que ton serveur est très utilisé et qu'il y a un millier de tels jetons
valides au moment de l'attaque, cela fait une chance sur 2^128/2^10,
soit 2^118. On reste au dessus des 2^100.
Le hic c'est qu'une attaque ne se ferait pas au hasard de cette façon.

D'un côté, si un mot de passe peut contenir 10 chiffres, 52 lettres
(A-Z et a-z) et 10 autres symboles, sur 10 caractères, cela donne
3,74391E+18, ce qui est beaucoup plus petit que 2^100 ou 1,26765E+30.

D'un autre côté, une SESSIONID n'est pas un chiffre choisi au hasard.
Le nombre de requêtes possibles n'est pas 2^100 mais beaucoup moins.

De toutes façons, un pirate va probablement utiliser un sniffer et
rechercher des mots-clés et donc va se concentrer sur des sites plus
faciles à attaquer puisqu'il aura le mot de passe. De ce point de
vue, tout ce calcul ne donne rien puisqu'il ne tient pas compte du
chemin d'entrée le plus facile à utiliser.

De plus, les pirates vont plutôt utiliser des pièges pour obtenir ces
mots de passe (hameçonnage ou phishing par exemple) ou des exploits
dans les navigateurs en ayant par exemple un script qui recopie le
mot de passe sur une autre adresse.

Il ne faut pas oublier qu'en sécurité, ce qui compte, c'est le maillon
le plus faible, pas le plus fort...


Denis
Olivier Miakinen
2009-04-22 23:44:19 UTC
Permalink
Post by Denis Beauregard
Post by Olivier Miakinen
hasard environ une fois toutes les 2^128 requêtes. Bon, si l'on suppose
que ton serveur est très utilisé et qu'il y a un millier de tels jetons
valides au moment de l'attaque, cela fait une chance sur 2^128/2^10,
soit 2^118. On reste au dessus des 2^100.
Le hic c'est qu'une attaque ne se ferait pas au hasard de cette façon.
En effet, si le nombre de jetons possibles est trop important le pirate
abandonnera la force brute pour essayer de trouver un autre moyen. Mais
c'est justement parce que l'on choisit un nombre aléatoire suffisamment
grand qu'il devra chercher autre chose. Au pire : attaquer à main armée
quelqu'un qui a accès à l'application ; dans ce cas le contrôle $_GET /
$_POST ne sert à rien puisqu'on utilise l'application normalement avec
un navigateur tout ce qu'il y a de plus basique.
Post by Denis Beauregard
D'un côté, si un mot de passe peut contenir 10 chiffres, 52 lettres
(A-Z et a-z) et 10 autres symboles, sur 10 caractères, cela donne
3,74391E+18, ce qui est beaucoup plus petit que 2^100 ou 1,26765E+30.
Eh, je ne parlais pas du tout d'un mot de passe, lequel est choisi par
l'utilisateur, et a en général une durée de vie qui se compte en jours,
voire parfois en années ! Je parlais d'un jeton à usage unique, généré
aléatoirement, et dont la durée de vie peut être de quelques secondes ou
de quelques minutes.
Post by Denis Beauregard
D'un autre côté, une SESSIONID n'est pas un chiffre choisi au hasard.
Le nombre de requêtes possibles n'est pas 2^100 mais beaucoup moins.
Je ne parlais pas non plus d'une SESSIONID.
Post by Denis Beauregard
[...]
Il ne faut pas oublier qu'en sécurité, ce qui compte, c'est le maillon
le plus faible, pas le plus fort...
Absolument.
John GALLET
2009-04-24 13:58:58 UTC
Permalink
Post by Mickael Wolff
Je ne parlerai même pas de tous les compteurs de visites et trucs à la noix
où un img src appelle (en post ?! arf !) un script php qui modifie des
données côté serveur avant de faire un bon vieux readfile sur pouet.jpg
Comment tu fais un HTTP POST avec un lien ?
Olivier a parfaitement raison, c'était de l'humour. Mais pour répondre à
la question, il y a deux moyens par exemple:

document.forms[0].submit()

<form action... method="post"><img src="clickme.jpg"></form>
Post by Mickael Wolff
La distinction entre $_GET et $_POST permet de maitriser la provenance des
données, ça ne peut qu'améliorer la sécurité.
Ca ne peut pas la déteriorer intrinsèquement, mais c'est de la fausse
sécurité qui peut créer un faux sentiment de protection. Pour que ça
améliore vraiment la sécurité il faudrait que ça ne soit pas spoofable. Or
c'est l'enfance de l'art de le faire, donc ça ne sert à (quasiment) rien.

Maintenant loin de moi l'idée d'empêcher ceux qui ont du temps à perdre de
le faire, mais moi je l'investis autrement (en racontant des conneries sur
usenet par exemple).

a++;
JG

PS: en ce qui me concerne le sujet est clos, sauf si besoin de montrer
comment on force en deux secondes top chrono l'envoi des données que l'on
veut en même temps dans $_GET, $_POST et $_COOKIES en une seule ligne de
commande wget (Qui a dit "man wget" dans le fond de la salle ?)
Sylvain SF
2009-04-13 13:16:26 UTC
Permalink
Post by Mickael Wolff
Post by Sylvain SF
tu peux expliciter ce qui te parait manquer ?
Ben la distinction entre les méthodes. Utiliser $_REQUEST revient à
reproduire le comportement stupide de register_global, qui a entra^iné
tant de désillusions en compromettant la sécurité des données en raison
d'une erreur grave de conception.
ah ! c'est '$_REQUEST' qui t'embête !... il est nuisible et inutile
(en prod.) c'est une évidence.

toutefois lorsque que tu écrivais "Il faut traiter $_GET et $_POST",
je lisais $_GET *et* $_POST, or ma compréhension du protocole Internet
et que cela ne peut pas être les 2 simultanément pour une même requête.

en complément du point d'Olivier, je dirais que traiter $_COOKIE,
en plus des paramètres postés (en POST ou GET) n'est pas tordu,
une appli web classique définira couramment son contexte global
via $_COOKIE (pour des préférences globales), via $_SESSION (pour
l'état logique, dont authentification, historique des étapes, etc)
et $_POST *ou* $_GET (pour une requête particulière).

Sylvain.
Mickael Wolff
2009-04-22 18:29:17 UTC
Permalink
Post by Sylvain SF
ah ! c'est '$_REQUEST' qui t'embête !... il est nuisible et inutile
(en prod.) c'est une évidence.
\o/ on est d'accord.
Post by Sylvain SF
toutefois lorsque que tu écrivais "Il faut traiter $_GET et $_POST",
je lisais $_GET *et* $_POST, or ma compréhension du protocole Internet
et que cela ne peut pas être les 2 simultanément pour une même requête.
En fait, c'est le nommage de ces superglobales qui est traitre. Si
effectivement $_POST fournit bien les données obtenues par HTTP POST,
$_GET ne contient pas réellement les paramètres HTTP d'une requete GET,
mais les paramètres correspondant à la searchpart de la Request-URI.
Finalement, $_GET devrait s'appeler logiquement $_REQUEST :p (ça c'était
pour embrouiller ceux qui suivaient encore).
--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org
Mickael Wolff
2009-04-09 19:34:23 UTC
Permalink
Post by Eric Demeester
1. on initialise les variables
Complètement d'accord.
Post by Eric Demeester
2. on les récupère via $_REQUEST en vérifiant au passage si elles
existent et sont non vides)
Complètement pas d'accord. Il faut traiter $_GET (pour déterminer les
ressources consultées) et $_POST (pour déterminer les alterations des
ressources. Et je ne vois pas pourquoi une valeur vide serait incorrecte.
Post by Eric Demeester
3. on effectue les traitements associés aux variables (interrogation
de la base de données ou tout autre traitement)
Ce que je trouve dommage c'est que tu traites indistinctement les
données d'alteration et de consultation.
Post by Eric Demeester
4. on affiche les résultats
Certes.
Post by Eric Demeester
Même principe que ci-dessus, il faut récupérer les variables et les
traiter _avant_ de les afficher. Après, l'endroit et l'ordre dans
lequels elles seront affichées dans la page importe peu...
Ce qui est intéressant de préciser, c'est que cette méthode permet de
faciliter l'affichage de messages d'erreur.
Post by Eric Demeester
La vraie difficulté est de comprendre les effets de register_globals sur
le comportement de PHP en terme de transmission d'informations entre
pages, c'est très largement documenté dans des tutoriels disponibles en
ligne. L'essentiel est que tu ais compris le mécanisme et résolu ton
problème. Inutile je pense, compte tenu du grand nombre de sites
traitant déjà de cela, d'écrire une documentation supplémentaire, même
si cette proposition t'honore :)
Surtout que le problème est tellement commun et général qu'il existe
des ressources de partout ;)
--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org
Yannick
2009-04-13 13:16:26 UTC
Permalink
Bonjour,

Regardez ce fil et vous comprendrez ce que je DÉTESTE!
1 question pratique avec tous les éléments.
12 messages avec 1 personne pour arriver à la solution recherchée. Je
n'ai pas dit LA solution car vu les autres messages.
15 messages de geeks qui se battent pour dire qu'il a une meilleure
solution que son voisin. Aucun pour donner une solution pratique au cas
posé...
Je ne parle pas des messages reçus en privé pour ne rien faire avancé.
De ces derniers 1 seul a eu un effet constructif qui sera repris.

Pensez-vous décemment que vous attirez les néophites à faire des
efforts? Je vous réponds que non car c'est désolant.

Un grand merci à Olivier et Éric

Amitiés
--
Yannick VOYEAUD
John GALLET
2009-04-13 14:59:54 UTC
Permalink
Post by Yannick
Regardez ce fil et vous comprendrez ce que je DÉTESTE!
Moi il y a d'autres choses qui me défrisent, mais c'est un autre problème.
Post by Yannick
1 question pratique avec tous les éléments.
Non, avec les scripts en vrac, failles de sécurité incluses et
récupérées par les bretelles par l'équipe de modération sans qui tu
aurais donné l'accès à ta base à la terre entière, et débrouillez vous
pour comprendre ce qui merde. J'ajouterai même que ton message d'origine
est limite hors charte car incomplet.
Post by Yannick
12 messages avec 1 personne pour arriver à la solution recherchée. Je
n'ai pas dit LA solution car vu les autres messages.
Non, incroyable, il y aurait plusieurs solutions pour arriver au même
résultat ?
Post by Yannick
15 messages de geeks qui se battent pour dire qu'il a une meilleure
solution que son voisin. Aucun pour donner une solution pratique au cas
posé...
Peut-être que le cas posé ne les intéresse pas ? Peut-être qu'il y a des
tétrachiées de ressources qui couvent déjà le problème, que ceci a été
expliqué des centaines de fois ?
Post by Yannick
Pensez-vous décemment que vous attirez les néophites à faire des
efforts? Je vous réponds que non car c'est désolant.
Est-ce le rôle d'un forum de discussion usenet ? Ce qui est désolant
c'est de trouver encore des gens qui espèrent qu'on va résoudre tous
leurs problèmes en deux coups de cuillère à pot. C'est sur
fr.rec.oracle, qu'il faut poster dans ce cas.

Si tu avais commencé par lire la FAQ de ce forum, au hasard le point
2.7, tu aurais directement eu la bonne réponse. Pour rappel:
http://faqfclphp.free.fr/

Et si tu souhaites avoir la référence de tutoriaux à propos de PHP, il y
en a aussi dans cette FAQ et sur google.

a++;
JG
j***@wanadoo.fr
2009-04-13 15:11:30 UTC
Permalink
This message was cancelled from within Mozilla.
Patrick Mevzek
2009-04-13 14:59:54 UTC
Permalink
Post by Yannick
Regardez ce fil et vous comprendrez ce que je DÉTESTE!
Bienvenue sur Usenet à vous :-)
--
Patrick Mevzek . . . . . . . . . . . . . . Dot and Co
<http://www.dotandco.net/> <http://www.dotandco.com/>
<http://www.dotandco.net/ressources/icann_registrars/prices>
<http://icann-registrars-life.dotandco.net/>
Eric Demeester
2009-04-14 15:06:09 UTC
Permalink
dans (in) fr.comp.lang.php, Yannick <***@voyeaud.org> ecrivait (wrote) :

Bonjour Yannick,
Post by Yannick
Regardez ce fil et vous comprendrez ce que je DÉTESTE!
Comme le dit Patrick, bienvenue sur Usenet :)

Plus sérieusement, dans la mesure où le sujet/question/commentaire
abordé est en thème, ce forum accueille tout le monde, du débutant qui
pose une question jugée triviale par les plus chevronnés, aux gourous
(si si, il y en a ici) qui sont capable de générer des fils de dizaines
d'articles pour discuter par exemple de la pertinence de tel ou tel
point obscur de telle ou telle norme.
Post by Yannick
Pensez-vous décemment que vous attirez les néophites à faire des
efforts? Je vous réponds que non car c'est désolant.
Je conçois que cela soit déroutant au début, voire frustrant, mais il
faut faire la part des choses et ne pas te décourager, à mon avis.

Fais le tri de ce qui t'est utile (on a apporté la solution à ton
problème il me semble ?) et laisse les informaticiens barbus se
chamailler entre eux :)

Au fil du temps, tu trouveras peut-être comme moi que leurs échanges
sont passionnants, même si pour l'instant leurs discussions te semblent
bien ésotériques et éloignées de tes préoccupations.

Amicalement,
--
Eric
Mickaël Wolff
2009-04-22 18:29:17 UTC
Permalink
Post by Yannick
Pensez-vous décemment que vous attirez les néophites à faire des
efforts? Je vous réponds que non car c'est désolant.
Je ne crois pas que ce soit le but de usenet.

Désolé pour le lag, j'ai été occupé. Mais je vais répondre brièvement
au points qui m'ont été opposés.
--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org
Loading...