De nos jours, les services Web sont constamment exposés à une variété d'attaques. Par conséquent, la sécurité est quelque chose à retenir à toutes les étapes du cycle de vie du projet. Les auteurs du matériel, dont nous publions la traduction aujourd'hui, maintiennent un
référentiel sur GitHub contenant environ 80 recommandations pour sécuriser les applications s'exécutant sur la plate-forme Node.js. Ce matériel, basé sur de nombreuses publications de sécurité, contient plus de deux douzaines de recommandations concernant Node.js et quelques conseils généraux. De plus, ce matériel couvre les 10 principales vulnérabilités de la liste du projet OWASP.

1. Utilisez les rÚgles du linter, visant à vérifier la sécurité du code
Recommandations
Pendant le développement, utilisez un plug-in de sécurité pour le linter, tel que
eslint-plugin-security . Cela vous permet d'identifier trÚs tÎt les vulnérabilités et les problÚmes de sécurité - au moment de la rédaction du code approprié. Cette approche permet de détecter les faiblesses de la sécurité du programme. Parmi eux, l'utilisation de la commande
eval
, l'invocation de processus enfants, l'importation de modules avec le transfert à la commande correspondante de quelque chose de différent d'un littéral de chaßne (par exemple, une certaine chaßne formée sur la base de données transmises au serveur par l'utilisateur).
â
Voici quelques informations utiles sur les rĂšgles de linter
Adam Baldwin dit ce qui suit sur le peluchage: «Linter ne devrait pas ĂȘtre juste un outil qui suit mĂ©ticuleusement les rĂšgles concernant le nombre d'espaces utilisĂ©s, les points-virgules et l'utilisation de la commande eval. ESLint fournit au dĂ©veloppeur une plate-forme puissante qui peut dĂ©tecter et Ă©liminer un large Ă©ventail de modĂšles potentiellement dangereux dans le code. Nous parlons, par exemple, d'expressions rĂ©guliĂšres, de la vĂ©rification des entrĂ©es utilisateur, etc. Je crois que le linter offre aux dĂ©veloppeurs qui sont prĂ©occupĂ©s par les problĂšmes de sĂ©curitĂ© un nouvel outil puissant qui mĂ©rite d'ĂȘtre Ă©tudiĂ©. »
ProblĂšmes possibles
Ce qui ressemble à une faille de sécurité mineure pendant le développement devient une grave vulnérabilité dans la production. De plus, si tous les développeurs de projets ne respectent pas des rÚgles de sécurité uniformes lorsqu'ils travaillent avec du code, cela peut entraßner des vulnérabilités dans celui-ci ou, par exemple, la pénétration de données confidentielles dans des référentiels publics.
2. Limitez le nombre de demandes de serveur simultanées
Recommandations
Les attaques DoS sont trÚs populaires parmi les cybercriminels et elles sont relativement faciles à réaliser. Vous pouvez implémenter un systÚme pour limiter le nombre de demandes à une application à l'aide d'un service externe, tel qu'un équilibreur de charge cloud, un pare-feu cloud, un serveur nginx ou, pour les petites applications qui ne sont pas critiques, utiliser un middleware pour limiter le nombre de demandes comme le
débit express -limit .
â
Voici le matĂ©riel sur la mise en place du systĂšme de limitation de la frĂ©quence des requĂȘtes au serveur
ProblĂšmes possibles
Une application qui ne fournit pas de systĂšme pour limiter le nombre de requĂȘtes simultanĂ©es peut ĂȘtre attaquĂ©e, ce qui entraĂźnera son Ă©chec. Cela se traduit par le fait que les utilisateurs d'une telle application auront soit des difficultĂ©s Ă travailler avec elle, soit ne pourront pas du tout interagir avec elle.
3. Supprimez les informations confidentielles des fichiers de configuration ou chiffrez-les
Recommandations
Ne stockez jamais de donnĂ©es sensibles en texte brut dans des fichiers de configuration ou dans du code. Utilisez plutĂŽt des systĂšmes de gestion des donnĂ©es sensibles tels que les produits Vault ou les systĂšmes Kubernetes / Docker Secrets, ou utilisez des variables d'environnement pour stocker ces donnĂ©es. Les donnĂ©es confidentielles stockĂ©es dans le systĂšme de contrĂŽle de version doivent ĂȘtre cryptĂ©es, des mesures doivent ĂȘtre prises pour leur stockage et leur utilisation en toute sĂ©curitĂ©. Parmi ces mesures figurent l'utilisation de clĂ©s dynamiques, l'utilisation de dates d'expiration de mot de passe, des audits de sĂ©curitĂ©, etc. Utilisez des systĂšmes pour vĂ©rifier le code avant de le valider ou avant de l'envoyer au rĂ©fĂ©rentiel pour Ă©viter l'envoi accidentel de donnĂ©es sensibles au rĂ©fĂ©rentiel public.
â
Voici des informations sur la gestion des données sensibles
ProblĂšmes possibles
MĂȘme si le code est stockĂ© dans un rĂ©fĂ©rentiel fermĂ©, un jour, par erreur, il peut devenir accessible au public. Ă ce stade, toutes les donnĂ©es confidentielles qui y sont stockĂ©es deviendront du domaine public. Par consĂ©quent, un accĂšs tiers au rĂ©fĂ©rentiel avec le code les conduira par inadvertance Ă accĂ©der aux systĂšmes qui lui sont associĂ©s (bases de donnĂ©es, API, services, etc.).
4. EmpĂȘchez les vulnĂ©rabilitĂ©s d'injection de code
Recommandations
Afin d'empĂȘcher les injections SQL / NoSQL et autres attaques similaires, utilisez toujours des bibliothĂšques ORM / ODM ou des mĂ©canismes SGBD visant Ă nettoyer les donnĂ©es ou Ă prendre en charge des requĂȘtes paramĂ©trĂ©es nommĂ©es ou indexĂ©es et Ă vĂ©rifier ce qui vient de l'utilisateur. N'utilisez jamais, pour incorporer certaines valeurs dans des textes de requĂȘte, uniquement des chaĂźnes JavaScript de modĂšle ou une concatĂ©nation de chaĂźnes, car cette approche ouvre votre application Ă un large Ă©ventail de vulnĂ©rabilitĂ©s. Toutes les bibliothĂšques respectables pour Node.js utilisĂ©es pour travailler avec des donnĂ©es (par exemple,
Sequelize ,
Knex ,
mangouste ) contiennent une protection intégrée contre les attaques par
injection de code.
â
Voici le matériel sur la prévention des injections à l'aide des bibliothÚques ORM / ODM
ProblĂšmes possibles
L'utilisation de donnĂ©es non vĂ©rifiĂ©es et non nettoyĂ©es reçues de l'utilisateur dans les requĂȘtes peut entraĂźner une attaque en introduisant un opĂ©rateur lors de l'utilisation d'une base de donnĂ©es NoSQL telle que MongoDB. Si vous n'utilisez pas de systĂšme de nettoyage de donnĂ©es ou de bibliothĂšque ORM lorsque vous travaillez avec une base de donnĂ©es SQL, cela entraĂźnera la possibilitĂ© d'une attaque par injection SQL, ce qui crĂ©e un Ă©norme trou de sĂ©curitĂ© dans l'application.
5. Ăvitez les attaques DoS en dĂ©finissant explicitement les conditions de fin anormale du processus
Recommandations
Le processus Node se bloque lorsqu'une erreur non gĂ©rĂ©e se produit. Mais dans de nombreuses recommandations reflĂ©tant les meilleures pratiques pour Node, il est recommandĂ© de mettre fin aux processus mĂȘme lorsqu'une erreur a Ă©tĂ© interceptĂ©e et traitĂ©e. Express, par exemple, se bloque lorsqu'une erreur asynchrone se produit - Ă moins que les routes ne soient enveloppĂ©es dans
catch
expressions
catch
. Ce fait offre aux attaquants une opportunitĂ© trĂšs intĂ©ressante. AprĂšs avoir dĂ©couvert que lorsqu'une certaine demande arrive, le processus se bloque, ils commencent Ă lui envoyer de telles demandes. Il n'y a aucune recommandation qui rĂ©soudrait ce problĂšme d'un seul coup, cependant, certaines astuces peuvent l'attĂ©nuer. Ainsi, Ă la fin du processus en raison d'une erreur non gĂ©rĂ©e, vous devez en informer l'administrateur, en accordant Ă cette notification la plus haute prioritĂ©. Il est nĂ©cessaire de vĂ©rifier ce qui vient au processus dans les demandes et d'Ă©viter les situations de fin anormale du processus en raison de demandes qui, accidentellement ou intentionnellement, sont mal formĂ©es. Toutes les routes doivent ĂȘtre enveloppĂ©es dans
catch
expressions
catch
et le systĂšme doit ĂȘtre configurĂ© de sorte que, si la demande Ă©tait la cause de l'erreur, le processus ne se bloque pas (contrairement Ă ce qui se passe au niveau de l'application globale).
ProblĂšmes possibles
Analysons la situation suivante. Il existe de nombreuses applications Node.js. Que se passe-t-il si nous commençons Ă leur envoyer des requĂȘtes POST avec JSON vide comme corps de requĂȘte? Cela entraĂźnera le blocage de bon nombre de ces applications.
Maintenant, si nous devions jouer le rĂŽle de cybercriminels, pour que nous empĂȘchions les applications de se bloquer, il suffirait de continuer Ă leur envoyer des demandes similaires.
6. Configurer les en-tĂȘtes de rĂ©ponse HTTP pour augmenter la sĂ©curitĂ© du projet
Recommandations
Une application doit utiliser des en-tĂȘtes HTTP orientĂ©s sĂ©curitĂ© pour empĂȘcher les attaquants de recourir Ă des techniques d'attaque courantes telles que le scriptage intersite (XSS), le dĂ©tournement de clics et autres. La personnalisation des en-tĂȘtes est facile en utilisant des modules spĂ©ciaux tels que le
casque .
â
Voici des informations sur l'utilisation des en-tĂȘtes sĂ»rs
ProblĂšmes possibles
Si des en-tĂȘtes HTTP sĂ©curisĂ©s ne sont pas utilisĂ©s, les attaquants pourront effectuer des attaques contre les utilisateurs de vos applications, ce qui entraĂźne d'Ă©normes vulnĂ©rabilitĂ©s.
7. En continu, automatiquement, vérifiez vos projets pour l'utilisation des dépendances vulnérables en eux
Recommandations
Dans l'Ă©cosystĂšme NPM, les projets avec de nombreuses dĂ©pendances sont trĂšs courants. Les dĂ©pendances doivent toujours ĂȘtre contrĂŽlĂ©es, compte tenu de la dĂ©couverte de nouvelles vulnĂ©rabilitĂ©s. Utilisez des outils tels que
npm audit ,
nsp ou
snyk pour détecter, surveiller et corriger les dépendances vulnérables. Intégrez ces outils dans votre systÚme d'intégration continue. Cela vous permettra de détecter les dépendances vulnérables avant leur mise en production.
â
Voici des informations sur la sécurité des dépendances du projet
ProblĂšmes possibles
Un attaquant peut déterminer le framework web utilisé dans le projet et mener des attaques contre toutes les vulnérabilités connues.
8. Essayez de ne pas utiliser le module cryptographique Node.js standard pour le traitement des mots de passe, utilisez plutĂŽt Bcrypt
Recommandations
Les mots de passe ou autres donnĂ©es sensibles (clĂ©s API, par exemple) doivent ĂȘtre stockĂ©s en les traitant avec des fonctions cryptographiques utilisant du «sel», comme Bcrypt. Il vaut la peine d'utiliser exactement quelque chose de similaire, et non le module de
crypto
Node.js standard pour des raisons de sécurité et de performances.
â
Voici le matériel sur Bcrypt
ProblĂšmes possibles
Les mots de passe ou certaines données confidentielles qui sont stockés sans l'application de mesures appropriées pour les protéger sont vulnérables aux attaques par force brute et aux attaques de dictionnaire, qui, par conséquent, conduisent à la divulgation de ces données.
9. Utilisez des systÚmes d'échappement de caractÚres dans les données HTML, JS et CSS envoyées à l'utilisateur
Recommandations
Si certaines donnĂ©es sont envoyĂ©es au navigateur de l'utilisateur Ă partir d'une source non fiable, mĂȘme si elles doivent simplement ĂȘtre affichĂ©es, ces donnĂ©es peuvent ĂȘtre un code qui peut ĂȘtre exĂ©cutĂ©. Ceci est communĂ©ment appelĂ© script intersite (XSS). Vous pouvez rĂ©duire le risque que de telles attaques soient possibles en utilisant des bibliothĂšques spĂ©ciales qui traitent les donnĂ©es afin qu'elles ne puissent pas ĂȘtre exĂ©cutĂ©es. C'est ce qu'on appelle l'encodage ou le blindage des donnĂ©es.
â
Voici des informations sur le blindage de la sortie
ProblĂšmes possibles
Si vous ne vous souciez pas du blindage des donnĂ©es, un attaquant peut, par exemple, enregistrer du code JavaScript malveillant dans votre base de donnĂ©es, qui peut ĂȘtre transmis aux clients inchangĂ© et lancĂ©.
10. Vérifiez les données JSON arrivant sur le serveur
Recommandations
ContrĂŽlez le contenu des corps des demandes entrantes, en vĂ©rifiant si elles correspondent Ă ce que vous attendez de voir dans de telles demandes. Si la demande ne se prĂ©sente pas comme prĂ©vu, arrĂȘtez rapidement de la traiter. Afin d'Ă©viter l'opĂ©ration fastidieuse d'Ă©criture du code de vĂ©rification des demandes pour chaque itinĂ©raire, vous pouvez utiliser des outils JSON lĂ©gers pour la validation des donnĂ©es, tels que
jsonschema ou
joi .
â
Voici le matériel sur la vérification des données JSON entrantes
ProblĂšmes possibles
Si le serveur accepte les demandes cordialement sans les examiner minutieusement, cela augmente considérablement la surface d'attaque de l'application et incite les attaquants à essayer de trouver bon nombre d'entre elles qui conduisent à un «plantage» du systÚme.
11. Maintenir les jetons JWT sur liste noire
Recommandations
Lorsque vous utilisez des jetons JWT (par exemple, si vous travaillez avec
Passport.js ), par dĂ©faut, il n'existe aucun mĂ©canisme standard pour rĂ©voquer les privilĂšges d'accĂšs au systĂšme pour les jetons dĂ©jĂ Ă©mis. MĂȘme si vous constatez qu'un certain utilisateur fait quelque chose de manifestement anormal, vous n'avez aucun moyen, par le biais du mĂ©canisme de jeton, de bloquer son accĂšs au systĂšme, tant qu'il a un jeton valide. Ce problĂšme peut ĂȘtre attĂ©nuĂ© en implĂ©mentant une liste noire de jetons non approuvĂ©s, dont la validation est effectuĂ©e Ă chaque demande.
â
Voici le matériel sur les jetons JWT sur liste noire
ProblĂšmes possibles
Les jetons qui tombent entre de mauvaises mains peuvent ĂȘtre utilisĂ©s par un attaquant. Il pourra accĂ©der Ă l'application et se faire passer pour un utilisateur ordinaire - le propriĂ©taire du jeton.
12. Limitez le nombre de tentatives de connexion
Recommandations
Dans les applications basées sur express, pour se protéger contre les attaques par force brute et les attaques par dictionnaire, il vaut la peine d'utiliser le middleware approprié, comme
express-brute . De mĂȘme, vous devez protĂ©ger les itinĂ©raires critiques tels que
/admin
ou
/login
. La protection doit ĂȘtre basĂ©e sur l'analyse des propriĂ©tĂ©s de la requĂȘte, telles que le nom d'utilisateur utilisĂ© dans la requĂȘte ou d'autres identificateurs, tels que les paramĂštres du corps de la requĂȘte.
â
Voici le matériel sur la limitation du nombre de tentatives de connexion
ProblĂšmes possibles
Si l'application ne limite pas le nombre de tentatives de connexion, l'attaquant peut envoyer automatiquement un nombre illimité de demandes de connexion à votre systÚme, par exemple, en essayant d'accéder à un compte privilégié.
13. Exécutez Node.js en tant qu'utilisateur non root
Recommandations
Un scĂ©nario extrĂȘmement courant est lorsque Node.js est exĂ©cutĂ© en tant qu'utilisateur root avec des privilĂšges illimitĂ©s. Par exemple, voici comment tout est configurĂ© par dĂ©faut dans les conteneurs Docker. Il est recommandĂ© de crĂ©er un utilisateur qui ne dispose pas des privilĂšges root et de l'intĂ©grer dans l'image Docker ou de dĂ©marrer le processus au nom de cet utilisateur en appelant le conteneur avec l'indicateur
-u username
.
â
Voici le matériel sur le lancement de Node.js en tant qu'utilisateur non root
ProblĂšmes possibles
Si Node.js est exécuté sous le compte d'utilisateur root, un attaquant qui a pu exécuter un script sur le serveur obtient des possibilités illimitées sur la machine locale. Disons qu'il peut modifier les paramÚtres
iptable
et rediriger le trafic vers son propre ordinateur.
14. Limitez la quantité de données transmises dans les demandes à l'aide d'un serveur proxy inverse ou d'un middleware
Recommandations
Plus la quantitĂ© de donnĂ©es dans le corps de la demande est grande, plus il est difficile pour un serveur Ă thread unique de traiter une telle demande. L'utilisation de requĂȘtes volumineuses donne Ă un attaquant la possibilitĂ© d'inonder le serveur de travaux inutiles sans lui envoyer un grand nombre de requĂȘtes (c'est-Ă -dire sans effectuer d'attaque DoS / DDoS). Vous pouvez rĂ©duire le risque de telles attaques en limitant la taille des corps des demandes entrantes sur un certain systĂšme de frontiĂšre (sur un pare-feu ou sur un Ă©quilibreur de charge), ou en configurant
body-parser express pour recevoir uniquement les paquets contenant une petite quantité de données.
â
Voici des informations sur la limitation de la quantitĂ© de donnĂ©es transmises dans les requĂȘtes
ProblĂšmes possibles
Si vous ne limitez pas la quantitĂ© de donnĂ©es transmises dans les requĂȘtes, un attaquant peut charger l'application en traitant des requĂȘtes volumineuses. Pour le moment, il ne pourra pas rĂ©soudre les tĂąches pour lesquelles il est conçu. Cela entraĂźne de mauvaises performances et rend l'application vulnĂ©rable aux attaques DoS.
15. Ăvitez d'utiliser la fonction eval en JavaScript
Recommandations
La fonction
eval
est mauvaise car elle vous permet d'exécuter du code JS arbitraire qui lui est transmis pendant l'exécution du programme. De plus, ce n'est pas seulement que ce code peut ralentir l'application. Cette fonction pose un grave risque pour la sécurité, car du code JS malveillant envoyé au serveur par un attaquant pourrait y pénétrer.
En outre, vous devez éviter le
new Function
constructeur
new Function
. Les fonctions
setTimeout
et
setInterval
n'ont jamais besoin de transmettre du code JS généré dynamiquement.
â
Voici les informations sur eval
ProblĂšmes possibles
Si quelqu'un trouve un moyen de transférer du code JS malveillant, sous forme de texte, d'une fonction
eval
ou d'un autre moteur JS similaire, il aura un accĂšs complet Ă la page, Ă tout ce qui peut ĂȘtre fait en utilisant JavaScript. Cette vulnĂ©rabilitĂ© est souvent associĂ©e aux attaques XSS.
16. Ne surchargez pas les applications Node.js à thread unique avec des expressions réguliÚres malveillantes
Recommandations
Les expressions rĂ©guliĂšres, bien que pratiques, constituent une menace pour les applications JavaScript en gĂ©nĂ©ral, et en particulier pour la plate-forme Node.js. Le traitement avec une expression rĂ©guliĂšre de ce qui vient de l'utilisateur peut crĂ©er une Ă©norme charge sur le processeur. Par exemple, le traitement des expressions rĂ©guliĂšres peut ĂȘtre si inefficace que la vĂ©rification de dix mots peut bloquer le cycle des Ă©vĂ©nements pendant plusieurs secondes et surcharger le processeur. Par consĂ©quent, il est prĂ©fĂ©rable d'utiliser des packages tiers pour vĂ©rifier les donnĂ©es de chaĂźne, telles que
validator.js , au lieu d'écrire vos propres expressions réguliÚres. Vous pouvez utiliser le package
safe-regex pour détecter les modÚles
regex vulnérables.
â
Voici le matériel d'expression rationnelle anti-malware
ProblĂšmes possibles
Les expressions rĂ©guliĂšres mal Ă©crites peuvent ĂȘtre sujettes Ă un type particulier d'attaques DoS, au cours desquelles la boucle d'Ă©vĂ©nements est complĂštement bloquĂ©e. Par exemple, en novembre 2017, il a Ă©tĂ© dĂ©couvert que le package de
moment
populaire était vulnérable à de telles attaques.
17. Ăvitez de charger des modules Ă l'aide de variables
Recommandations
Ăvitez d'importer des fichiers dont le chemin est spĂ©cifiĂ© en tant que paramĂštre, en fonction des considĂ©rations selon lesquelles ce paramĂštre peut ĂȘtre dĂ©fini en fonction des donnĂ©es de l'utilisateur. Cette rĂšgle peut ĂȘtre Ă©tendue pour inclure ici et, en gĂ©nĂ©ral, l'accĂšs aux fichiers (Ă l'aide de
fs.readFile()
) et l'accÚs à toute autre ressource importante à l'aide des paramÚtres reçus de l'utilisateur. L'utilisation de
eslint-plugin-security permet de détecter trÚs tÎt de tels modÚles dangereux.
â
Voici des informations sur le chargement sécurisé des modules
ProblĂšmes possibles
Les donnĂ©es envoyĂ©es au serveur par un attaquant peuvent se trouver dans les paramĂštres chargĂ©s d'importer certains fichiers, parmi lesquels peut ĂȘtre un fichier malveillant qui a Ă©tĂ© prĂ©cĂ©demment tĂ©lĂ©chargĂ© sur le serveur. Ces donnĂ©es peuvent Ă©galement ĂȘtre utilisĂ©es pour accĂ©der aux fichiers systĂšme dĂ©jĂ sur l'ordinateur.
18.
, (, ), «», . , (
cluster.fork()
), npm-, .
â
, , . â , , , .
19.
, , . , , , .
child_process.execFile
, , , , , .
â
,
, , , , .
20.
express, , . , , ,
Error
( ). , , , - , .
â
, , , , , , .
21. npm Yarn
, -, (MFA, multi-factor authentication). npm Yarn , . , , , . , . , , npm, .
, ?
eslint, .
22. ,
- . , â , - . , ,
X-Powered-By
, , . , ( , , Node.js express).
â
-
- . , , -, â . .
23.
, . â , Node.js.
,
OWASP .
- root- .
- ( SSH-).
- , , , . OWASP, .
- , . , .
- OAuth, OpenID, . Basic Authentication.
- . , ( â ), X , Y .
- â , â . , .
- , , . ( â GitHub, AWS, Jenkins, ).
Résumé
. , Node.js-.
Chers lecteurs! -, ?
