773 votes

Injection SQL qui contourne mysql_real_escape_string()

Y a-t-il une possibilité d'injection SQL même en utilisant mysql_real_escape_string() fonction ?

Considérez cet exemple de situation. Le SQL est construit en PHP comme ceci :

$login = mysql_real_escape_string(GetFromPost('login'));
$password = mysql_real_escape_string(GetFromPost('password'));

$sql = "SELECT * FROM table WHERE login='$login' AND password='$password'";

J'ai entendu de nombreuses personnes me dire que ce genre de code est toujours dangereux et qu'il est possible de le pirater même avec mysql_real_escape_string() fonction utilisée. Mais je ne vois pas d'exploitation possible ?

Des injections classiques comme celle-ci :

aaa' OR 1=1 --

ne fonctionnent pas.

Connaissez-vous une injection possible qui pourrait passer à travers le code PHP ci-dessus ?

0 votes

En général, il est préférable d'effectuer la validation du mot de passe dans le code PHP afin de pouvoir afficher une erreur plus explicite (utilisateur invalide / mot de passe invalide).

3 votes

@ThiefMaster Je sais, ce qui précède n'est qu'un simple exemple pour faire passer mon message.

0 votes

Utilisez toujours des déclarations préparées. La sécurité, les avantages en termes de performances de la réutilisation des instructions, le codage standardisé et la maintenance de la bibliothèque l'emportent toujours (à mon avis) sur toute autre méthode alternative "raccourcie".

742voto

ircmaxell Points 74865

La réponse courte est oui, oui il y a un moyen de contourner mysql_real_escape_string() . #Pour des CAS très OBSCURE EDGE !!!

La réponse longue n'est pas si facile. C'est basé sur une attaque démontré ici .

L'attaque

Alors, commençons par montrer l'attaque...

mysql_query('SET NAMES gbk');
$var = mysql_real_escape_string("\xbf\x27 OR 1=1 /*");
mysql_query("SELECT * FROM test WHERE name = '$var' LIMIT 1");

Dans certaines circonstances, cela renverra plus d'une ligne. Décortiquons ce qui se passe ici :

  1. Sélection d'un jeu de caractères

    mysql_query('SET NAMES gbk');

    Pour que cette attaque fonctionne, nous avons besoin de l'encodage que le serveur attend de la connexion pour encoder à la fois ' comme en ASCII, c'est-à-dire 0x27 et pour avoir un caractère dont le dernier octet est un ASCII \ c'est-à-dire 0x5c . Il s'avère qu'il y a 5 encodages de ce type supportés par défaut dans MySQL 5.6 : big5 , cp932 , gb2312 , gbk et sjis . Nous choisirons gbk ici.

    Maintenant, il est très important de noter l'utilisation de SET NAMES ici. Ceci définit le jeu de caractères SUR LE SERVEUR . Si nous avons utilisé l'appel à la fonction de l'API C mysql_set_charset() nous n'avons rien à craindre (sur les versions de MySQL depuis 2006). Mais nous allons voir pourquoi dans une minute...

  2. La charge utile

    La charge utile que nous allons utiliser pour cette injection commence par une séquence d'octets 0xbf27 . Sur gbk il s'agit d'un caractère multi-octet non valide ; en latin1 c'est la chaîne ¿' . Notez que dans latin1 et gbk , 0x27 par lui-même est un littéral ' caractère.

    Nous avons choisi cette charge utile car, si nous appelions addslashes() sur elle, nous insérons un ASCII \ c'est-à-dire 0x5c avant que le ' caractère. Donc on se retrouvait avec 0xbf5c27 qui, en gbk est une séquence de deux caractères : 0xbf5c suivi par 0x27 . Ou en d'autres termes, un valide suivi d'un caractère non encodé ' . Mais nous n'utilisons pas addslashes() . Passons donc à l'étape suivante...

  3. mysql_real_escape_string()

    L'appel de l'API C à mysql_real_escape_string() diffère de addslashes() en ce sens qu'il connaît le jeu de caractères de la connexion. Il peut donc effectuer l'échappement correctement pour le jeu de caractères attendu par le serveur. Cependant, jusqu'à ce point, le client pense que nous utilisons toujours latin1 pour la connexion, parce qu'on ne lui a jamais dit le contraire. Nous avons dit à la serveur nous utilisons gbk mais le client pense toujours que c'est latin1 .

    Par conséquent, l'appel à mysql_real_escape_string() insère la barre oblique inversée, et nous avons une suspension libre. ' dans notre contenu "échappé" ! En fait, si l'on regarde $var dans le gbk le jeu de caractères, on verrait :

    ' OR 1=1 /\*

    Ce qui est exactement ce que que l'attaque requiert.

  4. La requête

    Cette partie est juste une formalité, mais voici la requête rendue :

    SELECT * FROM test WHERE name = '' OR 1=1 /*' LIMIT 1

Félicitations, vous venez de réussir à attaquer un programme en utilisant mysql_real_escape_string() ...

Le mauvais

C'est encore pire. PDO La valeur par défaut est émulant les déclarations préparées avec MySQL. Cela signifie que du côté client, il s'agit essentiellement d'un sprintf à travers mysql_real_escape_string() (dans la bibliothèque C), ce qui signifie que ce qui suit résultera en une injection réussie :

$pdo->query('SET NAMES gbk');
$stmt = $pdo->prepare('SELECT * FROM test WHERE name = ? LIMIT 1');
$stmt->execute(array("\xbf\x27 OR 1=1 /*"));

Il convient de noter que vous pouvez éviter ce problème en désactivant les instructions préparées émulées :

$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

Cela permettra généralement donne lieu à une véritable instruction préparée (c'est-à-dire que les données sont envoyées dans un paquet distinct de la requête). Cependant, il faut savoir que PDO va silencieusement solution de repli pour émuler les instructions que MySQL ne peut pas préparer nativement : celles qu'il peut préparer sont les suivantes répertorié dans le manuel, mais attention à sélectionner la version appropriée du serveur).

L'Affreux

J'ai dit au tout début que nous aurions pu éviter tout cela si nous avions utilisé mysql_set_charset('gbk') au lieu de SET NAMES gbk . Et cela est vrai à condition que vous utilisiez une version de MySQL depuis 2006.

Si vous utilisez une version antérieure de MySQL, alors un fichier bogue sur mysql_real_escape_string() signifie que les caractères multi-octets invalides, tels que ceux de notre charge utile, sont traités comme des octets simples à des fins d'échappement. même si le client avait été correctement informé de l'encodage de la connexion. et donc cette attaque réussirait quand même. Le bogue a été corrigé dans MySQL 4.1.20 , 5.0.22 et 5.1.11 .

Mais le pire c'est que PDO n'a pas exposé l'API C pour mysql_set_charset() jusqu'à la version 5.3.6, donc dans les versions antérieures il ne peut pas prévenir cette attaque pour toutes les commandes possibles ! C'est maintenant exposé comme un Paramètre DSN .

La grâce salvatrice

Comme nous l'avons dit au début, pour que cette attaque fonctionne, la connexion à la base de données doit être codée à l'aide d'un jeu de caractères vulnérable. utf8mb4 est non vulnérable et pourtant peut soutenir chaque Caractère Unicode : vous pouvez donc choisir de l'utiliser à la place, mais il n'est disponible que depuis MySQL 5.5.3. Une alternative est utf8 qui est aussi non vulnérable et peut prendre en charge l'ensemble de l'Unicode Plan de base multilingue .

Vous pouvez également activer l'option NO_BACKSLASH_ESCAPES le mode SQL, qui (entre autres) modifie le fonctionnement de mysql_real_escape_string() . Avec ce mode activé, 0x27 sera remplacé par 0x2727 plutôt que 0x5c27 et donc le processus d'échappement ne peut pas créer des caractères valides dans n'importe lequel des encodages vulnérables où ils n'existaient pas auparavant (c'est-à-dire 0xbf27 est toujours 0xbf27 etc.) - donc le serveur rejettera toujours la chaîne comme étant invalide. Cependant, voir Réponse de @eggyal pour une vulnérabilité différente qui peut survenir en utilisant ce mode SQL.

Exemples sûrs

Les exemples suivants sont sûrs :

mysql_query('SET NAMES utf8');
$var = mysql_real_escape_string("\xbf\x27 OR 1=1 /*");
mysql_query("SELECT * FROM test WHERE name = '$var' LIMIT 1");

Parce que le serveur attend utf8 ...

mysql_set_charset('gbk');
$var = mysql_real_escape_string("\xbf\x27 OR 1=1 /*");
mysql_query("SELECT * FROM test WHERE name = '$var' LIMIT 1");

Parce que nous avons correctement défini le jeu de caractères pour que le client et le serveur correspondent.

$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$pdo->query('SET NAMES gbk');
$stmt = $pdo->prepare('SELECT * FROM test WHERE name = ? LIMIT 1');
$stmt->execute(array("\xbf\x27 OR 1=1 /*"));

Parce que nous avons désactivé les déclarations préparées émulées.

$pdo = new PDO('mysql:host=localhost;dbname=testdb;charset=gbk', $user, $password);
$stmt = $pdo->prepare('SELECT * FROM test WHERE name = ? LIMIT 1');
$stmt->execute(array("\xbf\x27 OR 1=1 /*"));

Parce que nous avons défini le jeu de caractères correctement.

$mysqli->query('SET NAMES gbk');
$stmt = $mysqli->prepare('SELECT * FROM test WHERE name = ? LIMIT 1');
$param = "\xbf\x27 OR 1=1 /*";
$stmt->bind_param('s', $param);
$stmt->execute();

Parce que MySQLi fait de vraies déclarations préparées tout le temps.

Conclusion

Si vous :

  • Utilisez les versions modernes de MySQL (dernières 5.1, toutes les 5.5, 5.6, etc.) ET mysql_set_charset() / $mysqli->set_charset() / Le paramètre DSN charset de PDO (en PHP 5.3.6)

OU

  • N'utilisez pas un jeu de caractères vulnérable pour le codage de la connexion (vous utilisez seulement utf8 / latin1 / ascii / etc)

Vous êtes en sécurité à 100%.

Sinon, vous êtes vulnérable même si vous utilisez mysql_real_escape_string() ...

4 votes

PDO émule les instructions prepare pour MySQL, vraiment ? Je ne vois pas pourquoi il le ferait puisque le pilote le supporte nativement. Non ?

18 votes

C'est le cas. Ils disent dans la documentation que ce n'est pas le cas. Mais dans le code source, c'est clairement visible et facile à corriger. Je mets ça sur le compte de l'incompétence des développeurs.

7 votes

@TheodoreR.Smith : Ce n'est pas si facile à réparer. J'ai travaillé sur le changement de la valeur par défaut, mais elle échoue à un grand nombre de tests lorsqu'elle est changée. C'est donc un changement plus important qu'il n'y paraît. J'espère toujours l'avoir terminé pour la 5.5...

420voto

Wesley van Opdorp Points 8536

Considérons la requête suivante :

$iId = mysql_real_escape_string("1 OR 1=1");    
$sSql = "SELECT * FROM table WHERE id = $iId";

mysql_real_escape_string() ne vous protégera pas contre cela. Le fait que vous utilisiez des guillemets simples ( ' ' ) autour de vos variables dans votre requête est ce qui vous protège contre cela. L'option suivante est également possible :

$iId = (int)"1 OR 1=1";
$sSql = "SELECT * FROM table WHERE id = $iId";

1 votes

Que se passe-t-il si les utilisateurs transmettent une seule citation comme partie de la valeur : 1'; DROP TABLE -- le commentaire de fin de phrase fera en sorte que le moteur ignore l'autre guillemet simple de l'énoncé

0 votes

@wesley $iId = mysql_real_escape_string((int)"1; DROP table"); ou `$dirty = "1 ; DROP table";$iId = mysql_real_escape_string((int)$dirty) ; serait un meilleur exemple que ce que vous avez, je pense.

10 votes

Mais ce ne serait pas un vrai problème, parce que mysql_query() n'exécute pas de déclarations multiples, non ?

208voto

eggyal Points 60363

TL;DR

mysql_real_escape_string() sera ne fournissent aucune protection (et pourrait en outre détruire vos données) si :

  • L'interface de MySQL NO_BACKSLASH_ESCAPES Le mode SQL est activé (ce qu'il pourrait être, à moins que vous explicitement sélectionner un autre mode SQL à chaque fois que vous vous connectez ) ; et

  • vos chaînes de caractères SQL sont citées à l'aide de guillemets doubles. " des personnages.

Ceci a été classé comme bogue #72458 et a été corrigé dans MySQL v5.7.6 (voir la section intitulée " La grâce salvatrice ", ci-dessous).

Il s'agit d'une autre (peut-être moins ?) obscure affaire EDGE ! !!

En hommage à L'excellente réponse de @ircmaxell (vraiment, c'est censé être de la flatterie et non du plagiat !), je vais adopter son format :

L'attaque

En commençant par une démonstration...

mysql_query('SET SQL_MODE="NO_BACKSLASH_ESCAPES"'); // could already be set
$var = mysql_real_escape_string('" OR 1=1 -- ');
mysql_query('SELECT * FROM test WHERE name = "'.$var.'" LIMIT 1');

Cela renverra tous les enregistrements de l test table. Une dissection :

  1. Sélection d'un mode SQL

    mysql_query('SET SQL_MODE="NO_BACKSLASH_ESCAPES"');

    Comme indiqué dans le document Littéraux de chaîne :

    Il existe plusieurs façons d'inclure des caractères guillemets dans une chaîne de caractères :

    • A " ' "à l'intérieur d'une chaîne de caractères citée avec " ' "peut être écrit comme " '' ".

    • A " " "à l'intérieur d'une chaîne de caractères citée avec " " "peut être écrit comme " "" ".

    • Faire précéder le caractère de citation par un caractère d'échappement (" \ ").

    • A " ' "à l'intérieur d'une chaîne de caractères citée avec " " "ne nécessite pas de traitement particulier et ne doit pas être doublé ou échappé. De la même manière, " " "à l'intérieur d'une chaîne de caractères citée avec " ' "n'a pas besoin d'un traitement spécial.

    Si le mode SQL du serveur comprend NO_BACKSLASH_ESCAPES alors la troisième de ces options, qui est l'approche habituelle adoptée par l'UE, est la suivante mysql_real_escape_string() -n'est pas disponible : l'une des deux premières options doit être utilisée à la place. Notez que l'effet de la quatrième puce est que l'on doit nécessairement connaître le caractère qui sera utilisé pour citer le littéral afin d'éviter d'abîmer ses données.

  2. La charge utile

    " OR 1=1 -- 

    La charge utile initie cette injection de manière tout à fait littérale avec l'instruction " caractère. Pas d'encodage particulier. Pas de caractères spéciaux. Pas d'octets bizarres.

  3. mysql_real_escape_string()

    $var = mysql_real_escape_string('" OR 1=1 -- ');

    Heureusement, mysql_real_escape_string() vérifie le mode SQL et adapte son comportement en conséquence. Voir libmysql.c :

    ulong STDCALL
    mysql_real_escape_string(MYSQL *mysql, char *to,const char *from,
                 ulong length)
    {
      if (mysql->server_status & SERVER_STATUS_NO_BACKSLASH_ESCAPES)
        return escape_quotes_for_mysql(mysql->charset, to, 0, from, length);
      return escape_string_for_mysql(mysql->charset, to, 0, from, length);
    }

    Donc une fonction sous-jacente différente, escape_quotes_for_mysql() est invoqué si le NO_BACKSLASH_ESCAPES Le mode SQL est utilisé. Comme mentionné ci-dessus, une telle fonction doit savoir quel caractère sera utilisé pour citer le littéral afin de le répéter sans provoquer la répétition de l'autre caractère de citation.

    Cependant, cette fonction est arbitrairement suppose que que la chaîne de caractères sera citée en utilisant le guillemet simple. ' caractère. Voir charset.c :

    /*
      Escape apostrophes by doubling them up
    
    // [ deletia 839-845 ]
    
      DESCRIPTION
        This escapes the contents of a string by doubling up any apostrophes that
        it contains. This is used when the NO_BACKSLASH_ESCAPES SQL_MODE is in
        effect on the server.
    
    // [ deletia 852-858 ]
    */
    
    size_t escape_quotes_for_mysql(CHARSET_INFO *charset_info,
                                   char *to, size_t to_length,
                                   const char *from, size_t length)
    {
    // [ deletia 865-892 ]
    
        if (*from == '\'')
        {
          if (to + 2 > to_end)
          {
            overflow= TRUE;
            break;
          }
          *to++= '\'';
          *to++= '\'';
        }

    Donc, il laisse les guillemets " intactes (et double tous les guillemets simples). ' personnages) quel que soit le caractère utilisé pour citer le littéral. ! Dans notre cas $var reste exactement le même que l'argument qui a été fourni à mysql_real_escape_string() -C'est comme si aucune fuite n'avait eu lieu. du tout .

  4. La requête

    mysql_query('SELECT * FROM test WHERE name = "'.$var.'" LIMIT 1');

    Une sorte de formalité, la requête rendue est :

    SELECT * FROM test WHERE name = "" OR 1=1 -- " LIMIT 1

Comme l'a dit mon ami : félicitations, vous venez de réussir à attaquer un programme en utilisant mysql_real_escape_string() ...

Le mauvais

mysql_set_charset() ne peut pas vous aider, car cela n'a rien à voir avec les jeux de caractères. mysqli::real_escape_string() puisqu'il s'agit simplement d'une enveloppe différente pour cette même fonction.

Le problème, si ce n'est pas déjà évident, est que l'appel à mysql_real_escape_string() ne peut pas savoir avec quel caractère le littéral sera cité, car c'est au développeur d'en décider ultérieurement. Ainsi, dans NO_BACKSLASH_ESCAPES mode, il y a littéralement pas du tout que cette fonction peut échapper en toute sécurité à chaque entrée pour être utilisée avec une citation arbitraire (du moins, pas sans doubler les caractères qui ne nécessitent pas de doublage et donc sans altérer vos données).

L'Affreux

C'est encore pire. NO_BACKSLASH_ESCAPES n'est peut-être pas si rare dans la nature en raison de la nécessité de l'utiliser pour assurer la compatibilité avec le langage SQL standard (voir par exemple la section 5.3 de la directive sur l'accès à l'information). Spécification SQL-92 à savoir le <quote symbol> ::= <quote><quote> la production de la grammaire et l'absence de toute signification spéciale donnée au backslash). En outre, son utilisation était explicitement recommandé comme solution de contournement à la (corrigée depuis longtemps) bogue que décrit le post d'ircmaxell. Qui sait, certains DBAs pourraient même configurer cette option pour qu'elle soit activée par défaut afin de décourager l'utilisation de méthodes d'échappement incorrectes telles que addslashes() .

En outre, le Mode SQL d'une nouvelle connexion est défini par le serveur en fonction de sa configuration (qu'une SUPER l'utilisateur peut changer à tout moment) ; ainsi, pour être certain du comportement du serveur, vous devez toujours spécifier explicitement le mode souhaité après la connexion.

La grâce salvatrice

Tant que tu as toujours explicitement définir le mode SQL à ne pas inclure NO_BACKSLASH_ESCAPES ou de citer des chaînes de caractères MySQL en utilisant le caractère guillemet simple, ce bogue ne pourra pas se manifester : respectivement escape_quotes_for_mysql() ne sera pas utilisé, ou son hypothèse sur les caractères de citation à répéter sera correcte.

Pour cette raison, je recommande à toute personne utilisant NO_BACKSLASH_ESCAPES permet également ANSI_QUOTES car cela forcera l'utilisation habituelle des chaînes de caractères entre guillemets. Notez que cela n'empêche pas l'injection SQL dans le cas où des littéraux entre guillemets seraient utilisés - cela réduit simplement la probabilité que cela se produise (car les requêtes normales et non malveillantes échouent).

Dans l'AOP, sa fonction équivalente PDO::quote() et son émulateur de déclaration préparée font appel à mysql_handle_quoter() -qui fait exactement cela : il s'assure que le littéral échappé est cité entre guillemets simples, de sorte que vous pouvez être certain que PDO est toujours à l'abri de ce bogue.

À partir de MySQL v5.7.6, ce bogue a été corrigé. Voir journal des modifications :

Fonctionnalité ajoutée ou modifiée

Exemples sûrs

Avec le bogue expliqué par ircmaxell, les exemples suivants sont tout à fait sûrs (en supposant que l'on utilise MySQL après 4.1.20, 5.0.22, 5.1.11 ; ou que l'on n'utilise pas un encodage de connexion GBK/Big5) :

mysql_set_charset($charset);
mysql_query("SET SQL_MODE=''");
$var = mysql_real_escape_string('" OR 1=1 /*');
mysql_query('SELECT * FROM test WHERE name = "'.$var.'" LIMIT 1');

...parce que nous avons explicitement sélectionné un mode SQL qui n'inclut pas NO_BACKSLASH_ESCAPES .

mysql_set_charset($charset);
$var = mysql_real_escape_string("' OR 1=1 /*");
mysql_query("SELECT * FROM test WHERE name = '$var' LIMIT 1");

...parce que nous citons notre chaîne littérale avec des guillemets simples.

$stmt = $pdo->prepare('SELECT * FROM test WHERE name = ? LIMIT 1');
$stmt->execute(["' OR 1=1 /*"]);

...car les instructions préparées de PDO sont à l'abri de cette vulnérabilité (et celles d'ircmaxell aussi, à condition que vous utilisiez PHP5.3.6 et que le jeu de caractères ait été correctement défini dans le DSN ; ou que l'émulation des instructions préparées ait été désactivée).

$var  = $pdo->quote("' OR 1=1 /*");
$stmt = $pdo->query("SELECT * FROM test WHERE name = $var LIMIT 1");

...parce que les PDO quote() non seulement échappe le littéral, mais le cite également (entre guillemets). ' caractères) ; notez que pour éviter le bug d'ircmaxell dans ce cas, il faut doit utiliser PHP5.3.6 et que vous avez correctement défini le jeu de caractères dans le DSN.

$stmt = $mysqli->prepare('SELECT * FROM test WHERE name = ? LIMIT 1');
$param = "' OR 1=1 /*";
$stmt->bind_param('s', $param);
$stmt->execute();

...car les instructions préparées de MySQLi sont sûres.

Conclusion

Ainsi, si vous :

  • utilisation des déclarations préparées par les autochtones

OU

  • utiliser MySQL v5.7.6 ou une version ultérieure

OU

  • sur ajout pour employer l'une des solutions du résumé de ircmaxell, utilisez au moins l'une d'entre elles :

    • AOP ;
    • des chaînes de caractères littéraux entre guillemets ; ou
    • un mode SQL explicitement défini qui n'inclut pas NO_BACKSLASH_ESCAPES

...alors vous devrait être complètement sûr (vulnérabilités en dehors de la portée de l'échappement des chaînes de caractères mises à part).

11 votes

Donc, le TL;DR serait comme "il y a un mode serveur mysql NO_BACKSLASH_ESCAPES qui peut causer une injection si vous n'utilisez pas de guillemets simples.

0 votes

Je ne suis pas en mesure d'accéder bugs.mysql.com/bug.php?id=72458 J'obtiens juste une page d'accès refusé. Est-ce qu'il est caché au public en raison d'un problème de sécurité ? Par ailleurs, ai-je bien compris de cette réponse que vous êtes le découvreur de la vulnérabilité ? Si oui, félicitations.

0 votes

@MarkAmery : Er, je pense que la réponse à ces deux questions est "oui" - même si je pense que beaucoup ne considèrent pas cela comme une vulnérabilité. en soi mais plutôt un défaut de conception dans la séparation entre l'échappement et la citation. Dans le rapport de bogue, j'ai proposé une correction, mais comme elle modifie le protocole (bien que de manière sûre), je ne sais pas si elle sera adoptée.

22voto

Slava Points 1393

Eh bien, il n'y a rien qui puisse vraiment passer à travers ça, à part % joker. Cela pourrait être dangereux si vous utilisiez LIKE car l'attaquant pourrait mettre juste % comme identifiant si vous ne le filtrez pas, et vous devrez forcer brutalement le mot de passe de n'importe lequel de vos utilisateurs. Les gens suggèrent souvent d'utiliser des instructions préparées pour que la sécurité soit totale, car les données ne peuvent pas interférer avec la requête elle-même de cette façon. Mais pour des requêtes aussi simples, il serait probablement plus efficace de faire quelque chose comme $login = preg_replace('/[^a-zA-Z0-9_]/', '', $login);

2 votes

+1, mais les jokers sont pour la clause LIKE, pas pour une simple égalité.

8 votes

A quel point considérez-vous qu'un simple remplacement more efficient que d'utiliser des déclarations préparées ? (Les instructions préparées fonctionnent toujours, la bibliothèque peut être rapidement corrigée en cas d'attaques, elle n'expose pas à l'erreur humaine [telle que la saisie erronée de la chaîne de remplacement complète] et présente des avantages significatifs en termes de performances si l'instruction est réutilisée).

8 votes

@Slava : Vous limitez effectivement les noms d'utilisateur et les mots de passe aux seuls caractères de mot. La plupart des gens qui s'y connaissent en sécurité considèrent que c'est une mauvaise idée, car cela réduit considérablement l'espace de recherche. Bien sûr, ils considéreraient également comme une mauvaise idée de stocker des mots de passe en clair dans la base de données, mais nous n'avons pas besoin d'aggraver le problème :)

-7voto

zawdd Points 46

Il y a encore un autre caractère sur lequel la fonction ne fonctionne pas. c'est le backtick qui se trouve à gauche du chiffre 1. comme ceci ` vous pouvez utiliser backtick comme ' dans l'injection mysql.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X