Parse error: syntax error, unexpected T_IF in

musatge Messages postés 2 Date d'inscription mardi 7 avril 2009 Statut Membre Dernière intervention 3 juin 2009 - 3 juin 2009 à 07:51
nautilus99 Messages postés 661 Date d'inscription vendredi 26 septembre 2008 Statut Membre Dernière intervention 18 septembre 2009 - 3 juin 2009 à 22:24
Bonjour

Je recoit le message suivant:
Parse error: syntax error, unexpected T_IF in

pour la ligne:
if ($gravatar != 'http://www.gravatar.com/avatar/')

dans le contexte:
$avatar = strip_tags($_POST['avatar']);    // Supprime les balises HTML et PHP d'une chaine de caractère
$avatar = sprintf("%s",$avatar);         // $avatar sera une chaîne de caractères
$avatar = trim($avatar);                     // Enlève les espaces inutiles à droite et à gauche
$gravatar = substr($avatar    , 0, 31)     // Retourne la partie extraite de la chaîne.
if ($gravatar != 'http://www.gravatar.com/avatar/')
{ header("Location:utilisateur_creer.php?erreur=gravatar"); }

En fait je veux vérifier si on me met bien le lien vers le site gravatar

Est ce possible? si oui ou est l'erreur?
Merci

7 réponses

musatge Messages postés 2 Date d'inscription mardi 7 avril 2009 Statut Membre Dernière intervention 3 juin 2009
3 juin 2009 à 08:09
J'ai trouvé le parse error, j'avais oublié le; dans
$gravatar = substr($avatar    , 0, 31)     // Retourne la partie extraite de la chaîne.

J'ai corrigé et j'ai rajouté :
if (strlen ($avatar)<31)  { header("Location:utilisateur_creer.php?erreur=gravatar"); }

ce qui donne:

$avatar = strip_tags($_POST['avatar']);    // Supprime les balises HTML et PHP d'une chaine de caractère
$avatar = sprintf("%s",$avatar);         // $avatar sera une chaîne de caractères
$avatar = trim($avatar);                     // Enlève les espaces inutiles à droite et à gauche
if (strlen ($avatar)<31) 
   { header("Location:utilisateur_creer.php?erreur=gravatar"); }                    
$gravatar = substr($avatar    , 0, 31);     // Retourne la partie extraite de la chaîne.
if ($gravatar != 'http://www.gravatar.com/avatar/')
   { header("Location:utilisateur_creer.php?erreur=gravatar"); } 

mais si je saisi aa pour avatar il valide quand même la saisie pourtant la chaine est plus petite que 31.

Une idée? merci   
0
TychoBrahe Messages postés 1309 Date d'inscription samedi 31 janvier 2009 Statut Membre Dernière intervention 5 juin 2013 12
3 juin 2009 à 09:43
Salut,

Pour gérer les erreurs je saurait que te conseiller d'utiliser les exceptions au lieux de telles redirections.

Sinon deux petites remarques au sujet de ta ligne «$avatar = sprintf("%s",$avatar);» :

1. Dans le cas présent ça ne sert strictement a rien. En effet, les variables passées par get et post sont toujours du type string. De plus, les fonctions strip_tags et trim que tu utilises retournent un string, donc $avatar sera forcément de ce type. On peut aussi indiquer que php redéfinit le type de chaque variable en fonction de l'utilisation que l'on en fait, l'usage d'un cast est donc assez rare. Un test souvent important est de savoir si une entrée utilisateur représente bien un type différent du string (souvent un entier), j'ai déjà vu des possibilités d'injections de sql a cause de ça malgré l'utilisation de mysql_real_escape_string. Pour ceci il utilise des fonctions telles que is_numeric, permettant ainsi de lever une exception en cas de résultat non attendu, ce qui est plus efficace qu'un cast qui prendra une valeur plus ou moins contrôlée.

2. Si tu étais ammené a quand même caster en string, il est préférable d'utiliser $avatar = (string)$avatar; (idem pour els autres types)
0
kohntark Messages postés 3705 Date d'inscription lundi 5 juillet 2004 Statut Membre Dernière intervention 27 avril 2012 30
3 juin 2009 à 12:05
Salut,

@TychoBrahe :
Une injection sql malgré l'utilisation de mysql_real_escape_string ?
As tu un exemple en tête ?

Cordialement,

Kohntark -
0
TychoBrahe Messages postés 1309 Date d'inscription samedi 31 janvier 2009 Statut Membre Dernière intervention 5 juin 2013 12
3 juin 2009 à 14:03
Salut,

«Une injection sql malgré l'utilisation de mysql_real_escape_string ?
As tu un exemple en tête ?»

Un exemple (a regarder avec une police a chasse fixe) :

mysql> DESCRIBE hotel;
+------------+------------------+------+-----+---------+----------------+
| Field      | Type             | Null | Key | Default | Extra          |
+------------+------------------+------+-----+---------+----------------+
| id_hotel   | int(11)          | NO   | PRI | NULL    | auto_increment |
| nb_etoiles | int(10) unsigned | YES  |     | NULL    |                |
| nom        | varchar(25)      | NO   |     | NULL    |                |
| ville      | varchar(25)      | NO   |     | NULL    |                |
+------------+------------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

<?php$conf array('mysql_host'> 'host',
              'mysql_user' => 'user',
              'mysql_pass' => 'password',
              'mysql_db' => 'database');
if (empty($_GET['nb_etoiles']))
  die('Aucun nombre d\'étoiles indiqué.');
mysql_connect($conf['mysql_host'], $conf['mysql_user'], $conf['mysql_pass']);
mysql_select_db($conf['mysql_db']);$q 'SELECT * FROM hotel WHERE nb_etoiles ' . mysql_real_escape_string($_GET\
['nb_etoiles']);
$result = mysql_query($q) or die(mysql_error());
echo 'Nos choix d\'hotels :
';
while ($data = mysql_fetch_array($result))
  {
    echo '';
    echo 'Hotel : ', $data['nom'], '
';
    echo 'Ville : ', $data['ville'], '
';
    echo 'Nombre d\'étoiles : ', $data['nb_etoiles'], '
';
    echo '

';
  }
?>

?nb_etoiles=-42%20UNION%20SELECT%20NOW(),%20DATA_TYPE,%20TABLE_NAME,%20COLUMN_NAME%20FROM%20information_schema.COLUMNS%20WHERE%20TABLE_SCHEMA=DATABASE()

Ce que j'envoie ne contient aucun caractère échapé par mysql_real_escape_string. Ça fonctionne car on attend un int : il n'y a pas de quote a fermer pour injecter ce que l'on veux. Du coup, en utilisant les fonctions de MySQL on a tout ce qu'il nous faut pour injecter les divers chaînes dont on a besoin (merci CHAR). Un attaquat peux commencer a dumper toutes ta base comme je l'ai fait ici, puis recommencer pour aller chercher toutes les valeurs contenues dans tes tables. Autant te dire que si tu stocke des mots de passes en clair ton site est mort, si c'est du md5 ou sha1 ça va dépendre de sa complexité (un mot de passe simple est trouvé immédiatement avec les rainbow tables). Bien entendu, le mysql_error() sert a l'attaquant a ajuster sa requête pour arriver progressivement a en générer une correcte.

Solutions pour s'en protéger :
 - Être un gros porc et mettre des quotes autours de la valeur de l'int dans la reqête sql. C'est super moche et bouffeur de ressources.
 - Prendre le intval() de la valeur. C'est cool mais ça ne prévient pas l'administrateur de ce qui se passe.
 - Utiliser is_numeric() pour lancer une exception. Loguer le timestamp, l'adresse ip du client et la requête complète peux être bien pour savoir ce qui se passe et éventuellement engager des poursuites si on a affaire a une tentative de piratage.
 - Ne pas donner les erreurs détaillées a l'utilisateur permet de retarder voire décourager un attaquant.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
kohntark Messages postés 3705 Date d'inscription lundi 5 juillet 2004 Statut Membre Dernière intervention 27 avril 2012 30
3 juin 2009 à 21:24
Ok, je pensai que tu voulais parler d'autre chose.
Pour ma part je fais souvent le "gros porc" : c'est efficace et très simple ... et je ne suis pas certain que ça nuise tant que ça aux perfs (du moins pour des requêtes "basiques")  chui un peu fainéant des fois, pas envie de me retaper des dizaines de lignes alors que 2 ' suffissent
Cela étant tu as raison, c'est un peu crade.

Pour élargir encore les solutions :
- (lorsque cela est possible)
comparer les données utilisateur avec celles attendues (select, checkbox, ...) Pour reprendre ton exemple :
Si nb_etoiles est différent de 0,1,2,3,4 ou 5 => on vire, on consigne, etc ...

- paramétrer correctement l'utilisateur de la DB en lui octroyant juste les droits nécessaires.
A ce propos sais tu si l'on peut interdire l'accès à information_schema ? J'avais fait il y a qq temps des recherches sans résultat.

Cordialement,

Kohntark -
0
TychoBrahe Messages postés 1309 Date d'inscription samedi 31 janvier 2009 Statut Membre Dernière intervention 5 juin 2013 12
3 juin 2009 à 22:06
Remplacer ton mysql_real_escape_string() par un intval() n'est pas bien compliqué et ne prend pas de lignes en plus, ça prend même quelques caractères en moins ^^ Pour ce qui est des perfs, bien entendu c'est quasi négligeable vu qu'il ne s'agit que de temps superflut de parsing d'une chaîne de caractère.

Pour ce qui est de changer les droits de l'utilisateur de la db, ce genre d'injection ne se fait qu'avec un SELECT (détourné de son usage), il n'est donc pas possible d'ajuster les droits pour se protéger de cette faille particulière. Après, empêcher l'accès à information_schema ne pourrais que limiter les dégâts si une telle chose était possible (je manque également de renseignements sur sa fesabilité).
0
nautilus99 Messages postés 661 Date d'inscription vendredi 26 septembre 2008 Statut Membre Dernière intervention 18 septembre 2009 1
3 juin 2009 à 22:24
Bonsoir,

Information_schema, on ne peut pas en interdire l'accès. Mais suivant les droits du user de la base, l'accès peut être très limité. Il faut au moins un accès en lecture pour résoudre les requêtes du genre SHOW TABLES, SHOW COLUMNS et surtout, si on utilise le moteur InnoDB, il faut accéder au Information_schema pour avoir les liste des pré-requis (les contrainte ssur clés étrangères). Idem si on utilise de sprocédures stockées.

La sécurisation contre l'injection est loin d'être une tâche simple.
0
Rejoignez-nous