Question

À quel point ce code php est-il dangereux? Que peut-on faire à ce sujet?

$name = $_POST["user"];
$pwd = $_POST["pwd"];
$query = "SELECT name,pwd FROM users WHERE name = '$name' AND pwd = '$pwd'";
Était-ce utile?

La solution

Problèmes possibles:

  1. Injection SQL
  2. XSS Injection (si ce code était une requête d'insertion, ce serait un problème certain)
  3. Mot de passe en texte brut

Votre instruction SQL peut être problématique. C'est une mauvaise pratique de vous laisser ouvert pour l'injection SQL.

L'injection SQL est incorrecte . Croyez-moi.

Si vous souhaitez afficher l'utilisateur $ user sur une page HTML, vous ne voudrez peut-être pas inclure la possibilité pour les utilisateurs de & "Pirater &"; votre mise en page en tapant des commandes telles que

<H1>HI MOM</H1>

ou un groupe de javascript .

En outre, ne stockez jamais votre mot de passe en texte brut (bonne capture cagcowboy!). Cela donne trop de pouvoir aux personnes qui gèrent (ou piratent) votre base de données. Vous ne devriez jamais avoir besoin de connaître le mot de passe de quelqu'un.

Essayez des tactiques comme celles-ci:

// mostly pulled from http://snippets.dzone.com/posts/show/2738
function MakeSafe($unsafestring) 
{
    $unsafestring= htmlentities($unsafestring, ENT_QUOTES);

    if (get_magic_quotes_gpc()) 
    { 
        $unsafestring= stripslashes($unsafestring); 
    }

    $unsafestring= mysql_real_escape_string(trim($unsafestring));
    $unsafestring= strip_tags($unsafestring);
    $unsafestring= str_replace("\r\n", "", $unsafestring);

    return $unsafestring;
} 

// Call a function to make sure the variables you are 
// pulling in are not able to inject sql into your 
// sql statement causing massive doom and destruction.

$name = MakeSafe( $_POST["user"] );
$pwd = MakeSafe( $_POST["pwd"] );

// As suggested by cagcowboy: 
// You should NEVER store passwords decrypted.
// Ever.  
// sha1 creates a hash of your password
// pack helps to shrink your hash
// base64_encode turns it into base64
$pwd = base64_encode(pack("H*",sha1($pwd)))

Autres conseils

C'est ce dangereux: xkcd tables de bobby

À part l’injection SQL, il semble que vos mots de passe pourraient être stockés en texte brut, ce qui n’est pas terrible.

Ce code est très sûr si vous ne passez jamais $ query à une base de données SQL.

Si vous deviez publier 0';drop table users;-- un nom

votre commande finirait par être

select name, pwd form users where name='0'; 
drop table users; --'and pwd = '[VALUE OF PWD]'

Ainsi, il obtiendrait d'abord vos données, puis tuerait votre table d'utilisateurs, et ne ferait rien avec le reste puisqu'il s'agit d'un commentaire.

Certaines commandes mysql dans php effectueront plusieurs requêtes lorsqu’elles seront transmises à SQL, le meilleur moyen de l’éviter est les requêtes paramétrées.

J'utilise PDO pour tous mes accès à la base de données et le recommande vivement. Je n'ai aucun lien par cœur, mais je me souviens des tutoriels que j'ai utilisés en tête de Google.

Il n’est pas seulement sujet aux injections SQL, il échouera également dans les cas où une injection n’est même pas prévue:

Par exemple, un utilisateur veut le nom & "Guillaume Fran & # 231; ois Antoine, marquis de L & # 8217; Hôpital &" ;. Étant donné que le nom d'utilisateur contient une citation et que vous ne l'échappez pas, votre requête échouera, même si l'utilisateur n'a jamais voulu casser le système!

Utilisez AOP ou procédez de la manière suivante:

$query = sprintf(
                   "SELECT 1 FROM users WHERE name = '%s' AND password = '%s'",
                   mysql_real_escape_string($_POST['name']),
                   mysql_real_escape_string(md5($_POST['password']))
                 );

Croyez-le ou non, c'est sûr ... si magic_quotes_gpc est activé. Ce qui ne sera jamais en PHP6, donc le corriger avant cela est une bonne idée.

  1. $_POST['user'] = "' or 1=1; --"; Tout le monde obtient un accès instantané à votre application

  2. $_POST['user'] = "'; DROP TABLE user; --"; Dites adieu à votre liste d’utilisateurs (payante?)

  3. Si vous écrivez plus tard $ name dans votre sortie, cela peut entraîner une attaque par injection XSS

: Ne fais jamais ça jamais, Cela peut provoquer une attaque SQLInjection. Si, par exemple, une entrée d'utilisateur en quelque sorte:   "Utilisateurs de la table de modification - comme entrée dans $ username; ce code concaténera votre code original et laissera tomber votre table. Les pirates peuvent faire plus et peuvent pirater votre site Web.

Ceci est généralement très dangereux. Cela pourrait être atténué par les autorisations de base de données dans certains cas.

Vous ne validez pas l'entrée ($ name et $ pwd). Un utilisateur peut envoyer du SQL dans l’un ou l’autre de ces champs. Le SQL pourrait supprimer ou modifier d’autres données de votre base de données.

Très très dangereux. Une bonne idée pour les mots de passe est de convertir le mot de passe en hachage MD5 et de le stocker en tant que «mot de passe» de l'utilisateur.
1) protège les utilisateurs contre le vol de leurs mots de passe 2) si un utilisateur écrit une chaîne illicite, il pourrait effacer votre entrée / table / base de données

Vous devez également effectuer une expression de correspondance regex de base sur le nom pour vous assurer qu’il utilise uniquement le caractère A-Za-z0-9 et peut-être quelques caractères accentués (pas de caractères spéciaux, *, < 's , > en particulier).

Lorsque des données utilisateur sont impliquées dans une requête SQL, supprimez-les toujours avec mysql_real_escape_string .

De plus, vous ne devriez stocker qu'un hachage salé du mot de passe au lieu du mot de passe lui-même. Vous pouvez utiliser la fonction suivante pour générer et vérifier un hachage salé avec une valeur de sel aléatoire:

function saltedHash($data, $hash=null)
{
    if (is_null($hash)) {
        $salt = substr(md5(uniqid(rand())), 0, 8);
    } else {
        $salt = substr($hash, 0, 8);
    }
    $h = $salt.md5($salt.$data);
    if (!is_null($hash)) {
        return $h === $hash;
    }
    return $h;
}

Tous ensemble:

$query = 'SELECT pwd FROM users WHERE name = "'.mysql_real_escape_string($_POST['user']).'"';
$res = mysql_query($query);
if (mysql_num_rows($res)) {
   $row = mysql_fetch_assoc($res);
   if (saltedHash($_POST["pwd"], $row['pwd'])) {
       // authentic
   } else {
       // incorrect password
   }
} else {
   // incorrect username
}

Ce n’est pas sûr, vous voudrez peut-être examiner quelque chose comme PDO. ODP PHP

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top