В настоящее время я работаю над внутренним скриптом NodeJS, который анализирует входящие HTTP-запросы на запись и чтение из базы данных MySQL для работы.Я пытался защитить его от SQL-инъекций, используя своего рода двухслойную защиту.
Для записи в базу данных пользователю необходимо предоставить valid JSON.Вот как ключи JSON должны быть , чтобы скрипт записывал в БД.Если это не так, запрос будет отменен.
{
"uuid": "1234-5678-abcd-efgh",
"product_id": 6,
"product_extras": "color=red",
"product_count": 2,
"buyer_name": "X Y",
"shipping_address": "XY Street 5"
}
Первый слой, который проверяет этот вход, является очень простым черным списком.Здесь переменная USER_INPUT
- это приведенный выше JSON, который уже прошел процесс проверки.
let BLACKLIST = ["DROP ", "DELETE ", "INSERT ", "UPDATE ", "SELECT ", "WHERE ", "ALTER "];
let dont_execute = false;
for(var i = 0; i < BLACKLIST.length; i++) {
if(JSON.stringify(USER_INPUT).toUpperCase().includes(BLACKLIST[i].toUpperCase())) {
console.log("\x1b[31mreceived blacklisted command - aborting");
dont_execute = true;
return false;
}
}
После этой проверки, если dont_execute
все еще имеет значение false, будет вызван второй уровень и запрос будет экранирован и отправлен следующим образом:
// setting.sqlconnection.table_name is equal to "orders" in this case. Also this variable can't be changed or specified by the user. It's pulled from a settings.json file
sql.sendQuery("INSERT INTO " + setting.sqlconnection.table_name + " (uuid, productid, orderid, productextras, productcount, buyername, shippingaddress) VALUES (" + sqlconnection.escape(uuid) + ", " + sqlconnection.escape(parseddata.product_id) + ", " + null + ", " + sqlconnection.escape(parseddata.product_extras) + ", " + sqlconnection.escape(parseddata.product_count) + ", " + sqlconnection.escape(parseddata.buyer_name) + ", " + sqlconnection.escape(parseddata.shipping_address) + ")");
Я пробовал много разных инъекций, подобных этой:
{
"uuid": "1234-5678-abcd-efgh",
"product_id": 6,
"product_extras": "color=red",
"product_count": 2,
"buyer_name": "X Y",
"shipping_address": "');DROP orders;--"
}
И так же, как яОжидается, что это не сработало, потому что прежде всего это было отражено в первом слое черного списка.Но после его отключения только для того, чтобы проверить все, весь SQL-запрос был просто интерпретирован как строка, поскольку апостроф был экранирован ('
стал \'
), и это именно то, что я хотел.Насколько мне известно, запрос, который будет отправлен с зараженным SLQI JSON, будет выглядеть следующим образом:
INSERT INTO orders (guid, productid, orderid, productextras, productcount, buyername, shippingaddress) VALUES ("1234-5678-abcd-efgh", 6, null, "color=red", 2, "X Y", "\');DROP orders--")
Но проблема в том, что, показав это своему боссу, он сказал, чтоне быть в безопасности, и он все еще уязвим для SQLI.Поэтому мой вопрос: прав ли он, и если да, то что я могу сделать, чтобы улучшить его.
Дополнительная информация:
Я использую пакет npm mysql
для подключения к базе данных
Я использую XAMPP с MySQL для локального размещения базы данных
Извините, если не могу предоставить больше информации, но я довольноуверен, что мне не разрешено публиковать больше материалов, чем это.