Czy można zapobiec iniekcjom SQL w Node.js (najlepiej za pomocą modułu) w taki sam sposób, w jaki PHP miał przygotowane instrukcje, które chroniły przed nimi.
Jeśli tak to jak? Jeśli nie, to jakie przykłady mogą ominąć podany przeze mnie kod (patrz poniżej).
Jakiś kontekst:
Tworzę aplikację internetową ze stosem zaplecza składającym się z Node.js + MySql przy użyciu modułu node-mysql . Z punktu widzenia użyteczności moduł jest świetny, ale nie zaimplementował jeszcze czegoś podobnego do gotowych instrukcji PHP (chociaż wiem, że jest to w todo ).
Z mojego zrozumienia wynika, że implementacja w PHP gotowych instrukcji, między innymi, bardzo pomogła w zapobieganiu wstrzyknięciom SQL. Martwię się jednak, że moja aplikacja node.js może być podatna na podobne ataki, nawet jeśli domyślnie wprowadzono znaki ucieczki (jak we fragmencie kodu poniżej).
node-mysql wydaje się być najpopularniejszym łącznikiem mysql dla node.js, więc zastanawiałem się, co inne osoby mogą robić (jeśli cokolwiek), aby rozwiązać ten problem - lub czy jest to nawet problem z node.js na początek (nie jestem pewien, jak by to nie wyglądało, ponieważ w grę wchodzą dane wejściowe po stronie użytkownika / klienta).
Czy powinienem na razie przełączyć się na node-mysql-native , skoro zapewnia on przygotowane instrukcje? Waham się, czy to zrobić, ponieważ nie wydaje się być tak aktywny jak node-mysql (choć może to po prostu oznaczać, że jest kompletny).
Oto fragment kodu rejestracji użytkownika, który używa modułu sanitizer , wraz z przygotowaną składnią podobną do instrukcji node-mysql (która, jak wspomniałem powyżej, wykonuje znaki ucieczki), aby zapobiec odpowiednio skryptom krzyżowym i wstrzyknięciom 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?
});
źródło
Biblioteka zawiera sekcję w pliku Readme o ucieczce. Jest natywny dla Javascript, więc nie sugeruję przełączania się na node-mysql-native . Dokumentacja zawiera wskazówki dotyczące ucieczki:
Edycja: node-mysql-native jest również rozwiązaniem opartym wyłącznie na Javascript.
true
/false
stringsYYYY-mm-dd HH:ii:ss
ciągiX'0fa5'
['a', 'b']
Zamienia się w'a', 'b'
[['a', 'b'], ['c', 'd']]
Zamienia się w('a', 'b'), ('c', 'd')
key = 'val'
pary. Zagnieżdżone obiekty są rzutowane na ciągi.undefined
/null
są konwertowane naNULL
NaN
/Infinity
są pozostawione bez zmian. MySQL ich nie obsługuje, a próba wstawienia ich jako wartości spowoduje błędy MySQL, dopóki nie zaimplementują obsługi.Dzięki temu możesz robić takie rzeczy:
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' });
Tak dobrze jak to:
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' });
Oprócz tych funkcji możesz również użyć funkcji ucieczki:
connection.escape(query); mysql.escape(query);
Aby uniknąć identyfikatorów zapytań:
mysql.escapeId(identifier);
A w odpowiedzi na Twój komentarz do przygotowanych wypowiedzi:
Przygotowane instrukcje znajdują się na liście rzeczy do zrobienia dla tego konektora, ale ten moduł pozwala przynajmniej na określenie niestandardowych formatów, które mogą być bardzo podobne do przygotowanych instrukcji. Oto przykład z pliku 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)); };
Spowoduje to zmianę formatu zapytania połączenia, dzięki czemu możesz używać takich zapytań:
connection.query("UPDATE posts SET title = :title", { title: "Hello MySQL" }); //equivalent to connection.query("UPDATE posts SET title = " + mysql.escape("Hello MySQL");
źródło
Zdaję sobie sprawę, że to starszy post, ale wygląda na to, że odpowiedź nigdy nie została zaznaczona, więc wyrzucę ją tam.
Jeśli chodzi o testowanie, czy moduł, którego używasz, jest bezpieczny, czy nie, istnieje kilka ścieżek, które możesz wybrać. Opowiem o zaletach / wadach każdego z nich, abyś mógł podjąć bardziej świadomą decyzję.
Obecnie nie ma żadnych luk w zabezpieczeniach modułu, którego używasz, jednak często może to prowadzić do fałszywego poczucia bezpieczeństwa, ponieważ bardzo dobrze może istnieć luka w zabezpieczeniach aktualnie wykorzystująca moduł / pakiet oprogramowania, z którego korzystasz i nie zostaniesz ostrzeżony do problemu, dopóki dostawca nie zastosuje poprawki / poprawki.
Aby być na bieżąco z lukami w zabezpieczeniach, będziesz musiał śledzić listy mailingowe, fora, IRC i inne dyskusje dotyczące hakowania. PRO: Często zdarza się, że zdasz sobie sprawę z potencjalnych problemów w bibliotece, zanim sprzedawca zostanie ostrzeżony lub wyda poprawkę / łatkę, aby zaradzić potencjalnej drodze ataku na jego oprogramowanie. CON: Może to być bardzo czasochłonne i wymagające dużych zasobów. Jeśli wybierzesz tę trasę, bot za pomocą kanałów RSS, analizowania dzienników (dzienniki czatu IRC) i / lub narzędzia internetowego używającego fraz kluczowych (w tym przypadku node-mysql-native) i powiadomienia mogą pomóc skrócić czas spędzony na trollowaniu tych zasobów.
Utwórz fuzzer, użyj fuzzera lub innej struktury luk w zabezpieczeniach, takiej jak metasploit , sqlMap itp., Aby pomóc w testowaniu problemów, których sprzedawca mógł nie szukać. PRO: To może okazać się niezawodną metodą przeciwpożarową zapewniającą do akceptowalnego poziomu, czy moduł / oprogramowanie, które wdrażasz, są bezpieczne dla publicznego dostępu. CON: To również staje się czasochłonne i kosztowne. Drugi problem będzie wynikał z fałszywych trafień, a także z niewykształconego przeglądu wyników, w przypadku których występuje problem, ale nie został zauważony.
Naprawdę bezpieczeństwo i ogólnie bezpieczeństwo aplikacji może być bardzo czasochłonne i wymagające dużej ilości zasobów. Menadżerowie zawsze będą używać wzoru do określania opłacalności (siły roboczej, zasobów, czasu, wynagrodzenia itp.) Realizacji dwóch powyższych opcji.
W każdym razie zdaję sobie sprawę, że nie jest to odpowiedź „tak” lub „nie”, na którą można było mieć nadzieję, ale nie sądzę, aby ktokolwiek mógł ci jej udzielić, dopóki nie przeprowadzi analizy danego oprogramowania.
źródło
Wiem, że to pytanie jest stare, ale dla każdego zainteresowanego Mysql-native jest przestarzały, więc stał się MySQL2 , czyli nowym modułem stworzonym z pomocą zespołu oryginalnego modułu MySQL. Ten moduł ma więcej funkcji i myślę, że ma to, czego chcesz, ponieważ przygotował instrukcje (używając.execute ()) jak w PHP dla większego bezpieczeństwa.
Jest również bardzo aktywny (ostatnia zmiana była od 2-1 dni) Nie próbowałem tego wcześniej, ale myślę, że tego chcesz i więcej.
źródło
Najłatwiej jest obsłużyć wszystkie interakcje z bazą danych we własnym module, który można wyeksportować do swoich tras. Jeśli twoja trasa nie ma kontekstu bazy danych, SQL i tak nie może jej dotknąć.
źródło