Est-il possible d'empêcher les injections SQL dans Node.js (de préférence avec un module) de la même manière que PHP avait préparé des instructions qui les protégeaient.
Si c'est le cas, comment? Sinon, quels sont quelques exemples qui pourraient contourner le code que j'ai fourni (voir ci-dessous).
Un certain contexte:
Je crée une application Web avec une pile back-end composée de Node.js + MySql en utilisant le module node-mysql . Du point de vue de la convivialité, le module est génial, mais il n'a pas encore implémenté quelque chose qui ressemble aux instructions préparées de PHP (bien que je sache que c'est sur le todo ).
D'après ce que je comprends, l'implémentation par PHP d'instructions préparées, entre autres, a grandement contribué à la prévention des injections SQL. Je crains cependant que mon application node.js ne soit ouverte à des attaques similaires, même avec la chaîne d'échappement fournie par défaut (comme dans l'extrait de code ci-dessous).
node-mysql semble être le connecteur mysql le plus populaire pour node.js, donc je me demandais ce que d'autres personnes pourraient faire (le cas échéant) pour expliquer ce problème - ou si c'est même un problème avec node.js pour commencer (je ne sais pas comment cela ne serait pas, car l'entrée côté utilisateur / client est impliquée).
Dois-je passer à node-mysql-native pour le moment, car il fournit des instructions préparées? J'hésite à le faire, car il ne semble pas être aussi actif que node-mysql (bien que cela puisse simplement signifier qu'il est complet).
Voici un extrait de code d'enregistrement de l'utilisateur, qui utilise le module sanitizer , ainsi que la syntaxe de type instruction préparée de node-mysql (qui, comme je l'ai mentionné ci-dessus, échappe les caractères), pour empêcher respectivement les scripts intersites et les injections 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?
});
la source
La bibliothèque a une section dans le readme sur l'échappement. C'est Javascript natif, donc je ne suggère pas de passer à node-mysql-native . La documentation indique ces instructions pour s'échapper:
Edit: node-mysql-native est aussi une solution purement Javascript.
true
/false
stringsYYYY-mm-dd HH:ii:ss
chaînesX'0fa5'
['a', 'b']
en'a', 'b'
[['a', 'b'], ['c', 'd']]
se transforment en('a', 'b'), ('c', 'd')
key = 'val'
paires. Les objets imbriqués sont convertis en chaînes.undefined
/null
sont convertis enNULL
NaN
/Infinity
sont laissés tels quels. MySQL ne les prend pas en charge et essayer de les insérer en tant que valeurs déclenchera des erreurs MySQL jusqu'à ce qu'elles implémentent le support.Cela vous permet de faire des choses comme ceci:
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' });
Ainsi que cette:
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' });
En plus de ces fonctions, vous pouvez également utiliser les fonctions d'échappement:
connection.escape(query); mysql.escape(query);
Pour échapper les identificateurs de requête:
mysql.escapeId(identifier);
Et en réponse à votre commentaire sur les déclarations préparées:
Les instructions préparées sont sur la liste des tâches pour ce connecteur, mais ce module vous permet au moins de spécifier des formats personnalisés qui peuvent être très similaires aux instructions préparées. Voici un exemple du 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)); };
Cela modifie le format de requête de la connexion afin que vous puissiez utiliser des requêtes comme celle-ci:
connection.query("UPDATE posts SET title = :title", { title: "Hello MySQL" }); //equivalent to connection.query("UPDATE posts SET title = " + mysql.escape("Hello MySQL");
la source
Je me rends compte que c'est un article plus ancien, mais il semble qu'une réponse n'a jamais été marquée, alors je vais la jeter là-bas.
En ce qui concerne le test si un module que vous utilisez est sécurisé ou non, vous pouvez emprunter plusieurs itinéraires. Je vais aborder les avantages / inconvénients de chacun afin que vous puissiez prendre une décision plus éclairée.
Actuellement, il n'y a aucune vulnérabilité pour le module que vous utilisez, cependant, cela peut souvent conduire à un faux sentiment de sécurité car il pourrait très bien y avoir une vulnérabilité exploitant actuellement le module / progiciel que vous utilisez et vous ne seriez pas alerté à un problème jusqu'à ce que le fournisseur applique un correctif / correctif.
Pour vous tenir au courant des vulnérabilités, vous devrez suivre les listes de diffusion, les forums, les IRC et autres discussions liées au piratage. PRO: Vous pouvez souvent prendre conscience de problèmes potentiels au sein d'une bibliothèque avant qu'un fournisseur n'ait été alerté ou n'ait publié un correctif / correctif pour remédier à la voie potentielle d'attaque sur son logiciel. CONTRE: Cela peut prendre beaucoup de temps et de ressources. Si vous suivez cette route, un bot utilisant des flux RSS, une analyse des journaux (journaux de discussion IRC) et / ou un scrapper Web utilisant des phrases clés (dans ce cas, node-mysql-native) et des notifications peuvent aider à réduire le temps passé à troller ces ressources.
Créez un fuzzer, utilisez un fuzzer ou un autre framework de vulnérabilité tel que metasploit , sqlMap etc. pour aider à tester les problèmes que le fournisseur n'a peut-être pas recherchés. PRO: Cela peut s'avérer être une méthode sûre pour garantir à un niveau acceptable si le module / logiciel que vous implémentez est sûr pour l'accès public. INCONVÉNIENTS: Cela prend également du temps et est coûteux. L'autre problème proviendra de faux positifs ainsi que d'un examen sans instruction des résultats là où un problème réside mais n'est pas remarqué.
La sécurité réelle et la sécurité des applications en général peuvent être très longues et gourmandes en ressources. Une chose que les gestionnaires utiliseront toujours est une formule pour déterminer la rentabilité (main-d'œuvre, ressources, temps, rémunération, etc.) de l'exécution des deux options ci-dessus.
Quoi qu'il en soit, je me rends compte que ce n'est pas une réponse «oui» ou «non» qui aurait pu être espérée, mais je ne pense pas que quiconque puisse vous la donner jusqu'à ce qu'il effectue une analyse du logiciel en question.
la source
Je sais que cette question est ancienne mais pour toute personne intéressée, Mysql-native est obsolète, il est donc devenu MySQL2 qui est un nouveau module créé avec l'aide de l'équipe du module MySQL d'origine. Ce module a plus de fonctionnalités et je pense qu'il a ce que vous voulez car il a préparé des déclarations (en utilisant.execute ()) comme en PHP pour plus de sécurité.
C'est aussi très actif (le dernier changement était de 2-1 jours) Je ne l'ai pas essayé avant mais je pense que c'est ce que vous voulez et plus.
la source
Le moyen le plus simple est de gérer toutes les interactions de votre base de données dans son propre module que vous exportez vers vos itinéraires. Si votre route n'a pas de contexte de la base de données, SQL ne peut pas y toucher de toute façon.
la source