Skip to content
This repository has been archived by the owner on Feb 14, 2023. It is now read-only.

Latest commit

 

History

History
297 lines (176 loc) · 4.64 KB

index.md

File metadata and controls

297 lines (176 loc) · 4.64 KB

title: Les scripts NPM et la sécurité class: animation-fade layout: true


class: impact

{{title}}


class: center

DISCLAIMER

⚠ Je ne suis pas un expert en sécurité ⚠


Petit récapitulatif

Dat "package.json"

Dans tous les projets node :

{
  "name": "my-project",
  "version": "1.0.0",
  "dependencies": {
	"yolo": "^1.2.3",
	"add": "~3.2.4",

    // le reste de l'internet
  }
}

Les scripts

{
  "name": "my-project",
  "scripts": {
    "say-hello": "echo hello",
    "say-goodbye": "echo goodbye"
  }
}

Pour faire tourner un script :

npm run say-hello

Les lifecycle scripts

  • à l'installation : [pre|post]install

  • à la publication : [pre|post]publish

  • l'execution est automatique par défaut :)


"[pre|post]install"

Installation d'une dépendance npm yolo :

  • npm install yolo

  • npm télécharge la dernière version de yolo

  • execute le script preinstall si il y en a un

  • installe les dépendances suivant toutes les étapes de cette liste

  • execute le script install ou postinstall si il y en a


class: center

What could go wrong


Idée 1 - Modifier curl

  • créer un alias curl vers notre script
{
	"bin": {
		"curl": "./my-custom-curl.js"
	}
}
  • faire tout ce qu'on veut

  • appeler vraiment curl


Idée 1 (bis)

{
	"name": "erase-npm",
	"bin": {
		"npm": "./not-so-nice-npm.js"
	}
}

--


Idée 2 - Remote terminal via socket

Le script de postinstall va :

  • exécuter un client socket vers un serveur qu'on contrôle

  • pour des messages spécifiques, le client executera la commande envoyée et remontera les résultats

  • c'est tout :)


Idée 3 - Self-replicating script

  • npm whoami
  • scraping de la page de l'utilisateur sur le site de npm
  • pour tous les modules :
    • npm install
    • cd my-module/
    • npm version patch
    • ajouter le script dans package.json
    • copier le script malicieux
    • npm publish
  • supprimer toutes traces du script malicieux

NOTE :

  • mitigé par le package-lock.json

class: center

Give me solutions


Précaution 1

Désactiver l'exécution automatique des scripts :

npm install --ignore-scripts <l'internet>

ou npm config set ignore-scripts true

Inconvénient :

  • on casse le bon fonctionnement de certains packages (PhantomJS ou autre).

Précaution 2

⚠ NE PAS FAIRE D'INSTALLATION EN ROOT ⚠

( aka sudo npm install ... )




-- Pourquoi ?

Les scripts sont exécutés avec les permissions de l'utilisateur courant.

{
	"scripts": {
		"postinstall": "rm -rf /"
	}
}

Précaution 3

Auditer TOUTES les dépendances du projet à la main (il suffit qu'un seul module soit impacté).

--

Inconvénient :

  • nombre de dépendances transitives conséquent

Auditer toutes les dépendances du projet automatiquement ?

  • JavaScript est très permissif

  • analyse de code difficile

  • beaucoup de faux négatifs


Précaution 4

Depuis la version 6 :

npm audit

--

Inconvénient :

  • potentiel délai avant qu'une faille soit déclarée

  • délai encore plus long pour que ça se propage dans toutes vos dépendances


Précaution 5

Dans le doute : npm logout


Autre piste potentielle

Signature des modules ?


Conclusion

  • "Les utilisateurs installent les packages les plus populaires" (ou pas)

  • une typo arrive vite (npm install bable)

  • Le problème n'est pas récent (2016) :

https://www.kb.cert.org/CERT_WEB/services/vul-notes.nsf/6eacfaeab94596f5852569290066a50b/018dbb99def6980185257f820013f175/$FILE/npmwormdisclosure.pdf

  • Le problème n'est pas trivial à résoudre

  • Les exploits sont assez fun à écrire :)


class: center fretlink

recrute

( React, NodeJS, PureScript, Haskell, ...)

https://www.fretlink.com/join-us


class: center

Des questions ?