it-swarm.com.ru

Делаем строку JavaScript дружественной к SQL

Можно ли сделать строку JavaScript, передаваемую в NodeJS, дружественной для MySQL? Я пытаюсь передать адрес электронной почты на мой сервер NodeJS и выполнить запрос в базу данных MySQL. При выполнении обычного текста, такого как имя пользователя, работает нормально, а адрес электронной почты - нет. Использование escape явно не является правильным ответом, так как оно не предназначено для вставки SQL. Я предполагаю, что мне нужно что-то в строках функции PHP mysql_real_escape_string()

41
Bobby

Оказывается, что mysql_real_escape_string () довольно тривиально. Согласно документации

mysql_real_escape_string () вызывает библиотечную функцию MySQL mysql_real_escape_string, которая добавляет обратную косую черту к следующим символам:\x00,\n,\r, \, ', "и\x1a.

Звучит довольно просто, на самом деле. Вы могли бы сделать что-то вроде этого:

function mysql_real_escape_string (str) {
    return str.replace(/[\0\x08\x09\x1a\n\r"'\\\%]/g, function (char) {
        switch (char) {
            case "\0":
                return "\\0";
            case "\x08":
                return "\\b";
            case "\x09":
                return "\\t";
            case "\x1a":
                return "\\z";
            case "\n":
                return "\\n";
            case "\r":
                return "\\r";
            case "\"":
            case "'":
            case "\\":
            case "%":
                return "\\"+char; // prepends a backslash to backslash, percent,
                                  // and double/single quotes
        }
    });
}

NOTE: я не проходил через какие-либо юнит-тесты или тесты безопасности, но, похоже, он работает - и, в качестве дополнительного бонуса, он ускользает от вкладок, клавиш возврата и «%» поэтому его также можно использовать в запросах LIKE согласно рекомендациям OWASP (в отличие от оригинала PHP).

Я знаю, что mysql_real_escape_string() поддерживает набор символов, но я не уверен, какую пользу это дает.

Есть хорошее обсуждение этих вопросов здесь .

52
Paul d'Aoust

В случае, если кто-то ищет, escapeString () в CUBRID RDBMS работает следующим образом:

var _escapeString = function (val) {
  val = val.replace(/[\0\n\r\b\t\\'"\x1a]/g, function (s) {
    switch (s) {
      case "\0":
        return "\\0";
      case "\n":
        return "\\n";
      case "\r":
        return "\\r";
      case "\b":
        return "\\b";
      case "\t":
        return "\\t";
      case "\x1a":
        return "\\Z";
      case "'":
        return "''";
      case '"':
        return '""';
      default:
        return "\\" + s;
    }
  });

  return val;
};

Это выдержка из драйвера CUBRID Node.js .

8
Eye

Изучил трудный способ, которым передача чисел в эту функцию приводит к тому, что весь процесс, в котором она используется, тихо умирает. Итак, я добавляю небольшой тест:

function mysql_real_escape_string (str) {
    if (typeof str != 'string')
        return str;

    return str.replace(/[\0\x08\x09\x1a\n\r"'\\\%]/g, function (char) {
        switch (char) {
            case "\0":
                return "\\0";
            case "\x08":
                return "\\b";
            case "\x09":
                return "\\t";
            case "\x1a":
                return "\\z";
            case "\n":
                return "\\n";
            case "\r":
                return "\\r";
            case "\"":
            case "'":
            case "\\":
            case "%":
                return "\\"+char; // prepends a backslash to backslash, percent,
                                  // and double/single quotes
        }
    });
}
7
Simon H

Использование массивов вместо оператора case:

var regex = new RegExp(/[\0\x08\x09\x1a\n\r"'\\\%]/g)
var escaper = function escaper(char){
    var m = ['\\0', '\\x08', '\\x09', '\\x1a', '\\n', '\\r', "'", '"', "\\", '\\\\', "%"];
    var r = ['\\\\0', '\\\\b', '\\\\t', '\\\\z', '\\\\n', '\\\\r', "''", '""', '\\\\', '\\\\\\\\', '\\%'];
    return r[m.indexOf(char)];
};

//Implementation
"Some Crazy String that Needs Escaping".replace(regex, escaper);
4
Justin

Для тех, кто приходит к этому ответу начиная с 2018 года, также стоит отметить, что ряд структур баз данных javascript теперь содержат метод connection.escape. 

Например: 

var mysql = require('mysql')

var connection = mysql.createConnection( // your connection string here 

var query = "SELECT THING FROM THING WHERE FRED= " + connection.escape( your_string_here ); 
2
sien

Если вы играете с персонажами CJK http://en.wikipedia.org/wiki/CJK_characters или какими-то особыми эмоциональными иконками iOS/Android/других мобильных телефонов ... таких как " ‡ ‰ ™ © ??? ?» или decodeURIComponent ("\ xF3\xBE\xAD\xA0").

Вам нужно будет установить ваш my.cnf следующим образом

[client]
default-character-set = utf8mb4

[mysqld]
character-set-server = utf8mb4
skip-character-set-client-handshake
0
Soyoes

Почему бы просто не использовать встроенную функцию escapeКак это:

var escaped_str = escape(your_unescaped_string);

Это работает для меня, используя MySQL на серверной части.

0
wbartussek