Ответ 1
Библиотека node-mysql
автоматически выполняет экранирование при использовании, как вы уже делаете. См. https://github.com/felixge/node-mysql#escaping-query-values
Можно ли предотвратить инъекции 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?
});
Библиотека node-mysql
автоматически выполняет экранирование при использовании, как вы уже делаете. См. https://github.com/felixge/node-mysql#escaping-query-values
Библиотека содержит раздел в файле readme об экранировании. Это Javascript-native, поэтому я не предлагаю переключиться на node -mysql-native. В документации указаны эти рекомендации по экранированию:
Изменить: 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");
Я понимаю, что это более старая должность, но кажется, что ответ не был отмечен, поэтому я его выброшу.
Что касается проверки того, защищен ли модуль, который вы используете, или нет, вы можете взять несколько маршрутов. Я коснусь плюсов и минусов каждого, чтобы вы могли принять более обоснованное решение.
В настоящее время нет уязвимостей для используемого модуля, однако это часто может привести к ложному пониманию безопасности, так как очень хорошо может быть уязвимость, в которой в настоящее время используется модуль/пакет программного обеспечения, который вы используете, t быть предупрежденным о проблеме до тех пор, пока поставщик не применит исправление/исправление.
Чтобы быть в курсе уязвимостей, вам нужно будет следить за списками рассылки, форумами, IRC и другими обсуждениями, связанными с взломом. PRO: Вы часто можете узнать о потенциальных проблемах в библиотеке до того, как поставщик был предупрежден или выпустил исправление/исправление, чтобы исправить потенциальный аспект атаки на их программное обеспечение. CON: Это может быть очень трудоемким и ресурсоемким. Если вы поедете по этому маршруту, бот с помощью RSS-каналов, разбора журнала (журналы IRC-чата) и веб-скребок с использованием ключевых фраз (в данном случае node -mysql-native) и уведомлений может помочь сократить время, затрачиваемое на троллирование этих ресурсов.
Создайте fuzzer, используйте fuzzer или другую инфраструктуру уязвимости, такую как metasploit., sqlMap и т.д., чтобы помочь проверить проблемы, которые поставщик, возможно, не искал. PRO: Это может оказаться верным методом пожарной безопасности на приемлемом уровне, независимо от того, безопасен ли модуль/программное обеспечение для открытого доступа. CON: Это также становится трудоемким и дорогостоящим. Другая проблема будет связана с ложными срабатываниями, а также необразованным обзором результатов, в которых проблема остается, но не замечена.
В действительности безопасность и безопасность приложений в целом могут быть очень трудоемкими и ресурсоемкими. Одна вещь, которую менеджеры всегда будут использовать, - это формула для определения экономической эффективности (рабочей силы, ресурсов, времени, оплаты и т.д.) Для выполнения указанных выше двух вариантов.
В любом случае, я понимаю, что это не ответ "да" или "нет", на который, возможно, надеялись, но я не думаю, что кто-то может дать это вам, пока они не проведут анализ данного программного обеспечения.