Предотвращение инъекции SQL в узел.js


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

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


Контекст:

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

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

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

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

вот фрагмент регистрационного кода пользователя, который использует дезинфицирующее средство модуль вместе с подготовленным синтаксисом оператора 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?
   });
5 65

5 ответов:

на node-mysql библиотека автоматически выполняет экранирование при использовании, как вы уже делаете. См.https://github.com/felixge/node-mysql#escaping-query-values

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

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

  • номера остаются нетронутыми
  • логические значения преобразуются в true/false строки
  • объекты даты преобразуются в 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");

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

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

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

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

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

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

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

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

Я знаю, что этот вопрос старый, но для всех, кто интересуется, Mysql-native устарел, поэтому он стал MySQL2 это новый модуль, созданный с помощью команды исходного модуля MySQL. Этот модуль имеет больше возможностей, и я думаю, что он имеет то, что вы хотите, как он подготовил заявления(с помощью.выполнить()) как в PHP для большей безопасности.

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