[signet] 23 recommandations pour protéger les applications Node.js

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! -, ?

Source: https://habr.com/ru/post/fr419719/


All Articles