2009-08-09 5 views
3

$ Peut-être que je fais quelque chose de mal dès le début, et si oui, je vais travailler sur ça aussi ...

J'ai un élément de menu qui passe comme partie de l'URL un numéro d'identification d'événement. Dans mon cas spécifique, il amène l'utilisateur à une page d'information pour cet événement. Ensuite, il y a un bouton qui leur permet de s'inscrire à l'événement. Cliquez et ils sont inscrits à l'événement et ramenés à la même page d'information qui indique maintenant qu'ils sont inscrits et leur permet de voir quelques éléments supplémentaires.

La première fois qu'ils frappent la page j'utilise un $ _GET pour comprendre l'ID d'événement qui est ensuite renvoyé à la page s'ils cliquent sur le bouton d'inscription comme un champ de saisie caché. Mais cette fois, je dois utiliser $ _POST pour déterminer le numéro d'identification de l'événement. Ainsi, le code dans ma requête a une partie booléenne qui ressemble à

SELECT stuff FROM ... WHERE eventID = ($_GET["ID"] ? $_GET["ID"] : $_POST["ID"]) 

Il fonctionne, mais il se sent comme il peut être fait mieux ...

+12

qui pleure pour l'injection sql. –

Répondre

3

Il peut sûrement faire mieux. Tout d'abord, désinfectez l'entrée utilisateur avant d'interroger la base de données comme vous l'avez fait. Vous vous êtes ouvert à SQL Injection.

8
  1. Désinfectez les entrées de votre base de données. mysql_real_escape_string() est un moyen rapide et facile d'y parvenir (ou, si l'ID est toujours numérique, vous pouvez simplement utiliser intval()). Ne soyez pas comme l'école qui est tombé pour Bobby Tables.
  2. Si vous n'êtes pas sûr de la méthode de requête utilisée, utilisez la superglobale $_REQUEST, qui contient les variables GET et POST (exemple: $_REQUEST['ID']). Je n'utilise normalement pas $_REQUEST, puisque j'aime être clair sur l'origine de mes données, mais ce serait une situation idéale pour l'utiliser.

Comme Nick Presta a souligné, $_REQUEST comprend également des variables cookie, et en fait, l'ordre par défaut * de priorité pour les conflits de noms est $_COOKIE, $_POST, puis $_GET. À la lumière de cela, avant de brancher les données dans la requête, vous pouvez soit faire ce que vous faites maintenant, ou utilisez $_SERVER['REQUEST_METHOD'] à la place:

// You can use mysql_real_escape_string() instead if you want 
$id = ($_SERVER['REQUEST_METHOD'] == 'POST') ? intval($_POST['id']) : intval($_GET['id']); 

En outre, comme Outis noté, gardez à l'esprit que vous avez la possibilité d'utiliser prepared statements au lieu de requêtes SQL brutes.

* - La commande est configurable via la directive de configuration variables_order, comme Stewart mentionné dans les commentaires.

+6

L'alternative moderne à la désinfection consiste à utiliser des instructions préparées: http://us2.php.net/manual/fr/pdo.prepared-statements.php – outis

+0

L'utilisation de $ _REQUEST facilite grandement le piratage. On devrait toujours être spécifique. –

+0

Et n'oubliez pas de désactiver gpc_magic_quotes, l'une des fonctionnalités de sécurité les plus stupides jamais inventées. –

1

En plus de la réponse de htw, si l'ID d'événement disponible pour les utilisateurs est basé sur des autorisations, assurez-vous de revalider qu'ils ont reçu cet ID particulier.
Ce n'est pas parce que c'est dans un champ caché qu'ils ne peuvent pas le changer.

2

Pour l'amour de simplicités, combinant les suggestions précédentes pour vous:

"SELECT stuff FROM ... WHERE eventID = '" . mysql_real_escape_string($_REQUEST['id']) . "';" 

Et pour l'enregistrement, ne pas utiliser des guillemets doubles pour la clé du tableau, sauf si vous allez inclure toutes les variables ou les évasions qui doivent être analysé, il prend plus de temps à traiter.Par exemple:

$_POST['id'] and not $_POST["id"] unless you're doing something like $_POST["post_$id"] 

Espérons que cela aide.

+0

Vous semblez avoir une faute de frappe: dans l'instruction SQL, il devrait y avoir une seule citation des deux côtés ou sur aucune des deux, selon que eventID est une chaîne ou un nombre. (Ceci devient également un non-problème si vous utilisez une instruction préparée et liez la valeur.) – Stewart

+0

Bon sang, ramassez ça, merci pour l'endroit! C'est ce qui arrive quand j'essaie de taper pendant que je jongle avec un verre et que je regarde la télé. xD Comme la question ne stipulait pas nécessairement si l'ID était une chaîne de caractères ou numérique, je pensais qu'il était préférable de citer la valeur pour quelqu'un qui ne protégeait pas contre l'injection SQL. ;] –

0

Vous devez séparer la sélection de l'ID fourni de l'endroit où il est placé dans la base de données. En d'autres termes, dès que la page sait si elle a été appelée via GET ou POST, elle connaîtra le super-global correct pour récupérer l'ID. En fait, il peut y avoir des pages qui seront toujours appelées avec POST et d'autres toujours avec GET.

Si cela n'a pas vraiment d'importance, utilisez $ _REQUEST.