Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Passage php4 vers php5

61 réponses
Avatar
Yannick
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>

10 réponses

3 4 5 6 7
Avatar
John GALLET
Bonjour/soir,

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.

À 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 -+-
Avatar
Mickael Wolff
Sylvain SF wrote:

ah ! c'est '$_REQUEST' qui t'embête !... il est nuisible et inutile
(en prod.) c'est une évidence.


o/ on est d'accord.

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
Avatar
Mickaël Wolff
Yannick wrote:

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
Avatar
Mickael Wolff
Sylvain SF wrote:
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.


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.


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.


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.


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.


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.


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


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
Avatar
Mickael Wolff
John GALLET wrote:

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.

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.


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)

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 ?


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
Avatar
Mickael Wolff
John GALLET wrote:

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

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 ?


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.


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.


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.



Faut que je termine mon tutoriel :D

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
Avatar
Mickael Wolff
Olivier Miakinen wrote:

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.


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.

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 ;)


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.


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.

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
Avatar
Olivier Miakinen
Le 22/04/2009 22:04, Mickael Wolff répondait à John Gallet :

[...] 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.
-------------------------------------------------------------------------


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
Avatar
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 ?



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>

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 ?)
Avatar
John GALLET
>> 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é. -+-
3 4 5 6 7