Voici un script anti-hack pour site

Petit nouveau ! | 5 Messages

04 nov. 2007, 12:41

Je demandais de la documentation pertinente choisie par un connaisseur d'où ma question car c'est bien de taper sur google mais il te sort 3 000 000 de pages.

Merci zeus. :wink:

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

04 nov. 2007, 12:48

Mais de rien.

Sauf que tu as cru voir une montagne là où il n'y avait qu'une bosse puisque le terme de "PDO" a été cité à plusieurs reprise ;)
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

Administrateur PHPfrance
Administrateur PHPfrance | 3131 Messages

04 nov. 2007, 18:10

Je vais zapper le débat, mais je tenais quand-même à dire que perso je ne connais pas la doc par cœur. Je sais pas vous mais à chaque fois que j'utilise in_array(), array_walk(), array_map(), strpos(), etc… je vais vérifier l'ordre des paramètres (merci l'homogénéité de PHP…).

Cela dit, et j'espère que ça ne fera pas débat parce que ça c'est vraiment la base de la sécurité (comprendre l'ultra-minimum) si vous n'utilisez pas PDO et aucun système d'abstraction, il faut toujours au moins passer par un système permettant de protéger vos requêtes.

Voici la fonction que je file à mes collègues qui travaillent un peu à l'arrache (php4, pas d'abstraction, bref du site jetable) histoire de sécuriser un minimum les sites. C'est un peu merdique mais ça a le mérite de marcher et de ne pas nécessiter un manuel d'utilisation de 12 pages.
/**
 * @var mixed $var
 * @return string Conversion de $var en expression utilisable dans une requête
 **/
function var2sql($var) {
  if (is_string($var)) {
    return '"' . mysql_real_escape_string($var) . '"';
  } elseif (is_numeric($var)) {
    return $var;
  } elseif (is_array($var)) {
    return '(' . implode(',', array_map('var2sql', $var)) . ')';
  } else {
    return strval($var);
  }
}

/**
 * Retourne le résultat d'une requête
 * @var string $sql Requête
 * @var array $params Tableau de paramètres à insérer dans la requête, les mots-clé
 * #{clé} seront remplacé par $params[clé] protégé.
 * @var boolean $expand_select Si la requête est un SELECT et que ce paramètre
 * est à true, alors la fonction renverra le tableau des résultats (tableaux associatifs)
 * @return resource|array Résultat de la requête
 **/
function query($sql, $params, $expand_select = true) {
  foreach ($params as $key => $param) {
    $sql = str_replace('#{' . $key '}', var2sql($param)
  }
  $result = mysql_query($sql);
  if ($expand_select && strtoupper(substr(ltrim($sql), 0, 6)) == 'SELECT') {
    $items = array();
    while ($item = mysql_fetch_assoc($result)) {
      $items[] = $item;
    }
    return $items;
  } else {
    return $result;
  }
}
Cela permet non seulement d'avoir un peu de sérénité (tout ce qui est passé dans $params est automatiquement échappé au besoin) et aussi de simplifier grandement l'écriture des requêtes (les tableaux sont automatiquement transformés, les chaines ont leurs guillemets ajoutés).

Exemple :
// Trouver un utilisateur sur certains critères
$params = array(
  'ids' => array(1, 2, 3), // Son ID est parmi ceux-là
  'nom' => 'Bob%', // Nom d'utilisateur commence par Bob
  'age_min' = 13, // Age minimum
);

$result = query('SELECT * FROM users WHERE nom LIKE #{nom} AND id IN #{ids} AND age >= #{age_min}', $params);

Petit nouveau ! | 5 Messages

04 nov. 2007, 20:40

Merci naholyr pour ta contribution ! :wink: