Подтвердить что ты не робот

Предотвращение SQL-инъекций в Node.js

Можно ли предотвратить инъекции SQL в Node.js(желательно с помощью модуля) таким же образом, что у PHP были подготовленные заявления, защищенные от них.

Если да, то как? Если нет, какие примеры, которые могут обойти предоставленный мной код (см. Ниже).


Контекст:

Я создаю веб-приложение с фоновым стеком, состоящим из Node.js + MySql, используя модуль node-mysql, С точки зрения юзабилити, модуль замечательный, но он еще не реализовал нечто похожее на PHP Подготовленные отчеты (хотя я знаю, что он включен todo).

С моей точки зрения, PHP-реализация подготовленных заявлений, в частности, помогла значительно в предотвращении инъекций SQL. Я беспокоюсь, однако, что мое приложение Node.js может быть открыто для подобных атак, даже при условии, что строка escaping предоставляется по умолчанию ( как в фрагменте кода ниже).

node -mysql, по-видимому, является самым популярным разъемом mysql для Node.js, поэтому мне было интересно, что могут делать другие люди (если есть), чтобы учесть эту проблему - или если это даже проблема с Node.js для начала (не уверен, как этого не будет, так как вход пользователя/клиентской стороны задействован).

Должен ли я переключиться на node -mysql-native в настоящее время, поскольку он предоставляет подготовленные заявления? Я не решаюсь это сделать, потому что он не так активен, как node -mysql (хотя это может означать, что оно завершено).

Вот фрагмент кода регистрации пользователя, в котором используется модуль sanitizer, а также node -mysql, подготовленный оператор-подобный синтаксис (который, как я упоминал выше, приводит к экранированию персонажа), для предотвращения межсайтового скриптинга и SQL-инъекций соответственно:

// Prevent xss
var clean_user = sanitizer.sanitize(username);

// assume password is hashed already
var post = {Username: clean_user, Password: hash};

// This just uses connection.escape() underneath
var query = connection.query('INSERT INTO users SET ?', post,
   function(err, results)
   {
       // Can a Sql injection happen here?
   });
4b9b3361

Ответ 2

Библиотека содержит раздел в файле readme об экранировании. Это Javascript-native, поэтому я не предлагаю переключиться на node -mysql-native. В документации указаны эти рекомендации по экранированию:

Изменить: node -mysql-native также является чистым решением Javascript.

  • Номера остаются нетронутыми
  • Булевы преобразуются в строки true/false
  • Объекты Date преобразуются в строки YYYY-mm-dd HH:ii:ss
  • Буферы преобразуются в шестнадцатеричные строки, например. X'0fa5'
  • Строки безопасно экранированы
  • Массивы превращаются в список, например. ['a', 'b'] превращается в 'a', 'b'
  • Вложенные массивы превращаются в сгруппированные списки (для объемных вставок), например. [['a', 'b'], ['c', 'd']] превращается в ('a', 'b'), ('c', 'd')
  • Объекты превращаются в пары key = 'val'. Вложенные объекты передаются в строки.
  • undefined/null преобразуются в null
  • NaN/Infinity остаются как-есть. MySQL не поддерживает их, и попытки вставить их в качестве значений вызовут ошибки MySQL до тех пор, пока они не реализуют поддержку.

Это позволяет делать так:

var userId = 5;
var query = connection.query('SELECT * FROM users WHERE id = ?', [userId], function(err, results) {
  //query.sql returns SELECT * FROM users WHERE id = '5'
});

Кроме того:

var post  = {id: 1, title: 'Hello MySQL'};
var query = connection.query('INSERT INTO posts SET ?', post, function(err, result) {
  //query.sql returns INSERT INTO posts SET `id` = 1, `title` = 'Hello MySQL'
});

Помимо этих функций вы также можете использовать escape-функции:

connection.escape(query);
mysql.escape(query);

Чтобы избежать идентификаторов запроса:

mysql.escapeId(identifier);

И как ответ на ваш комментарий к подготовленным заявлениям:

С точки зрения юзабилити, модуль замечательный, но он еще не реализовал нечто похожее на подготовленные заявления PHP.

Подготовленные заявления находятся в списке todo для этого коннектора, но этот модуль по крайней мере позволяет вам указать пользовательские форматы, которые могут быть очень похожими на подготовленные операторы, Вот пример из readme:

connection.config.queryFormat = function (query, values) {
  if (!values) return query;
  return query.replace(/\:(\w+)/g, function (txt, key) {
    if (values.hasOwnProperty(key)) {
      return this.escape(values[key]);
    }
    return txt;
  }.bind(this));
};

Это изменяет формат запроса для подключения, поэтому вы можете использовать такие запросы:

connection.query("UPDATE posts SET title = :title", { title: "Hello MySQL" });
//equivalent to
connection.query("UPDATE posts SET title = " + mysql.escape("Hello MySQL");

Ответ 3

Я понимаю, что это более старая должность, но кажется, что ответ не был отмечен, поэтому я его выброшу.

Что касается проверки того, защищен ли модуль, который вы используете, или нет, вы можете взять несколько маршрутов. Я коснусь плюсов и минусов каждого, чтобы вы могли принять более обоснованное решение.

В настоящее время нет уязвимостей для используемого модуля, однако это часто может привести к ложному пониманию безопасности, так как очень хорошо может быть уязвимость, в которой в настоящее время используется модуль/пакет программного обеспечения, который вы используете, t быть предупрежденным о проблеме до тех пор, пока поставщик не применит исправление/исправление.

  • Чтобы быть в курсе уязвимостей, вам нужно будет следить за списками рассылки, форумами, IRC и другими обсуждениями, связанными с взломом. PRO: Вы часто можете узнать о потенциальных проблемах в библиотеке до того, как поставщик был предупрежден или выпустил исправление/исправление, чтобы исправить потенциальный аспект атаки на их программное обеспечение. CON: Это может быть очень трудоемким и ресурсоемким. Если вы поедете по этому маршруту, бот с помощью RSS-каналов, разбора журнала (журналы IRC-чата) и веб-скребок с использованием ключевых фраз (в данном случае node -mysql-native) и уведомлений может помочь сократить время, затрачиваемое на троллирование этих ресурсов.

  • Создайте fuzzer, используйте fuzzer или другую инфраструктуру уязвимости, такую ​​как metasploit., sqlMap и т.д., чтобы помочь проверить проблемы, которые поставщик, возможно, не искал. PRO: Это может оказаться верным методом пожарной безопасности на приемлемом уровне, независимо от того, безопасен ли модуль/программное обеспечение для открытого доступа. CON: Это также становится трудоемким и дорогостоящим. Другая проблема будет связана с ложными срабатываниями, а также необразованным обзором результатов, в которых проблема остается, но не замечена.

В действительности безопасность и безопасность приложений в целом могут быть очень трудоемкими и ресурсоемкими. Одна вещь, которую менеджеры всегда будут использовать, - это формула для определения экономической эффективности (рабочей силы, ресурсов, времени, оплаты и т.д.) Для выполнения указанных выше двух вариантов.

В любом случае, я понимаю, что это не ответ "да" или "нет", на который, возможно, надеялись, но я не думаю, что кто-то может дать это вам, пока они не проведут анализ данного программного обеспечения.