web-dev-qa-db-fra.com

Quels caractères doivent être échappés pour empêcher les injections (My) SQL?

J'utilise la fonction de l'API MySQL

mysql_real_escape_string()

Basé sur la documentation, il échappe aux caractères suivants:

\0
\n
\r
\
'
"
\Z

Maintenant, j'ai regardé dans la bibliothèque de sécurité ESAPI de OWASP.org et dans le port Python, il contenait le code suivant ( http://code.google.com/p/owasp-esapi-python/source/browse/esapi/codecs/ mysql.py ):

        """
        Encodes a character for MySQL.
        """
        lookup = {
        0x00 : "\\0",
        0x08 : "\\b",
        0x09 : "\\t",
        0x0a : "\\n",
        0x0d : "\\r",
        0x1a : "\\Z",
        0x22 : '\\"',
        0x25 : "\\%",
        0x27 : "\\'",
        0x5c : "\\\\",
        0x5f : "\\_",
        }

Maintenant, je me demande si tous ces personnages sont vraiment nécessaires pour être échappés. Je comprends pourquoi% et _ sont là, ce sont des méta-caractères dans l'opérateur LIKE, mais je ne comprends pas pourquoi ils ont ajouté des caractères de retour arrière et de tabulation (\ b\t)? Existe-t-il un problème de sécurité si vous effectuez une requête:

SELECT a FROM b WHERE c = '...user input ...';

Où l'entrée utilisateur contient des tabulateurs ou des caractères de retour arrière?

Ma question est la suivante: pourquoi ont-ils inclus\b\t dans la bibliothèque de sécurité ESAPI? Existe-t-il des situations any où vous pourriez avoir besoin d'échapper à ces caractères?

14
Tower

La page de manuel MySQL pour les chaînes de caractères dit:

  • \0 Un caractère ASCII NUL (0x00).
  • \' Un caractère guillemet simple («'»).
  • \" Caractère entre guillemets («"»).
  • \b Un caractère de retour arrière.
  • \n Un caractère de nouvelle ligne (saut de ligne).
  • \r Un caractère de retour chariot.
  • \t Un caractère de tabulation.
  • \Z ASCII 26 (Control-Z). Voir la note à la suite du tableau.
  • \\ Caractère de barre oblique inverse («\»).
  • \% Un caractère “%”. Voir la note à la suite du tableau.
  • \_ Un caractère “_”. Voir la note à la suite du tableau.
15
Gumbo

Une supposition concernant le caractère de retour arrière: Imaginez que je vous envoie un courrier électronique "Bonjour, voici la requête pour mettre à jour votre base de données comme vous le souhaitez" et un fichier texte joint avec

INSERT INTO students VALUES ("Bobby Tables",12,"abc",3.6);

Vous chattez le fichier, vous voyez que tout va bien, et il suffit de le diriger vers MySQL. Mais ce que vous ne saviez pas, c’est que j’ai mis

DROP TABLE students;\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b

avant l'INSERT DECLARATION que vous n'avez pas vu car sur la sortie de la console, les backspaces l'ont écrasé. Bamm!

Juste une supposition, cependant.

Edit (ne pouvait pas résister):

alt text

46
balpha

La mise en liste noire (identification des caractères incorrects) n'est jamais la solution, si vous avez d'autres options.

Vous devez utiliser une combinaison de listes blanches et, plus important encore, d’approches aux paramètres liés.

Alors que cette réponse particulière a un focus PHP, elle est toujours utile et expliquera que le simple fait d'exécuter une chaîne via un filtre de caractères ne fonctionne pas dans de nombreux cas. S'il vous plaît, s'il vous plaît voir Est-ce que htmlspecialchars et mysql_real_escape_string gardent mon code PHP à l'abri des injections?

4
Cheekysoft

Où l'entrée utilisateur contient des tabulateurs ou des caractères de retour arrière?

Il est assez remarquable de constater que, jusqu'à ce jour, la plupart des utilisateurs pensent que c'est l'entrée de l'utilisateur doit être échappée, et cet échappement " empêche les injections ".

0

Solution Java:

public static String filter( String s ) {
    StringBuffer buffer = new StringBuffer();
    int i;

    for( byte b : s.getBytes() ) {
        i = (int) b;

        switch( i ) {
            case  9 : buffer.append( "    " ); break;
            case 10 : buffer.append( "\\n"  ); break;
            case 13 : buffer.append( "\\r"  ); break;
            case 34 : buffer.append( "\\\"" ); break;
            case 39 : buffer.append( "\\'"  ); break;
            case 92 : buffer.append( "\\"   );

            if( i > 31 && i < 127 ) buffer.append( new String( new byte[] { b } ) );
        }
    }

    return buffer.toString();
}
0
crae