{"id":54223,"date":"2025-08-28T07:47:18","date_gmt":"2025-08-28T11:47:18","guid":{"rendered":"https:\/\/www.kaspersky.com\/blog\/?p=54223"},"modified":"2025-08-28T07:47:18","modified_gmt":"2025-08-28T11:47:18","slug":"nx-build-s1ngularity-supply-chain-attack","status":"publish","type":"post","link":"https:\/\/www.kaspersky.com\/blog\/nx-build-s1ngularity-supply-chain-attack\/54223\/","title":{"rendered":"Serious NX build compromise \u2014 what you need to know about the s1ngularity attack"},"content":{"rendered":"<p>Packages of the popular build platform and CI\/CD optimization system, Nx, <a href=\"https:\/\/github.com\/nrwl\/nx\/security\/advisories\/GHSA-cxm3-wv7p-598c\" target=\"_blank\" rel=\"nofollow noopener\">were compromised on the night of August 26-27<\/a>. A malicious script was added to the system\u2019s packages, which, according to npm repository statistics, have more than five million weekly downloads. Thousands of developers that use Nx to accelerate and optimize application development had their sensitive data stolen: npm and GitHub tokens, SSH keys, cryptocurrency wallets, and API keys were uploaded to the public GitHub repositories. The massive leak of secrets poses a long-term threat of <a href=\"https:\/\/www.kaspersky.ru\/blog\/supply-chain-attacks-what-are-they-and-how-to-manage-the-risk\/38859\/\" target=\"_blank\" rel=\"noopener\">supply chain attacks<\/a>: even when malicious packages are removed from affected systems, attackers may still have the ability to compromise applications created by these thousands of developers.<\/p>\n<h2>Attack and response chronology<\/h2>\n<p>The attackers used a compromised token issued for one of the Nx package maintainers to publish multiple malicious versions of the Nx package and its plugins in the two hours between 22:32 UTC, August 26 and 0:37 UTC, August 27. Another two hours later, the npm platform removed all compromised versions of the packages, and another hour later, the Nx owners revoked the stolen token \u2014 so attackers lost access to the Nx repository. Meanwhile, thousands of public repositories containing data stolen by the malicious script began appearing on GitHub.<\/p>\n<p>At 9:05 UTC on August 27, GitHub responded by making all leaked repositories private and unsearchable. Nevertheless, the stolen data was publicly available for more than nine hours, and was downloaded multiple times by groups of cybercriminals and researchers. A total of 19 compromised versions of Nx and plugins were released:<\/p>\n<ul>\n<li>@nx, 20.9.0, 20.10.0, 20.11.0, 20.12.0, 21.5.0, 21.6.0, 21.7.0, 21.8.0<\/li>\n<li>@nx\/devkit, 20.9.0, 21.5.0<\/li>\n<li>@nx\/enterprise-cloud, 3.2.0<\/li>\n<li>@nx\/eslint, 21.5.0<\/li>\n<li>@nx\/js, 20.9.0, 21.5.0<\/li>\n<li>@nx\/key, 3.2.0<\/li>\n<li>@nx\/node, 20.9.0, 21.5.0<\/li>\n<li>@nx\/workspace, 20.9.0, 21.5.0.<\/li>\n<\/ul>\n<h2>How this attack was possible<\/h2>\n<p>For a short time starting from August 21, the Nx code used a <a href=\"https:\/\/github.com\/nrwl\/nx\/pull\/32458\/files\" target=\"_blank\" rel=\"nofollow noopener\">vulnerable workflow (GitHub action workflow)<\/a> that allowed arbitrary code injection. Attackers took advantage of this to modify publish.yml on August 24 and extract an npm token that grants rights to publish packages. Although the vulnerability was patched, the token leak was not noticed until it was exploited in an attack on August 26.<\/p>\n<h2>Malware features and targets<\/h2>\n<p>The Nx packets were trojanized using a malicious post-installation script called telemetry.js. It targets development environments on macOS and *nix (when run on Windows, the malicious script immediately terminates).<\/p>\n<p>Once run, the script searches the affected system for the following types of data:<\/p>\n<ul>\n<li>MetaMask, Electru, Ledger, Trezor, Exodus, Phantom, Solflare key storages and crypto wallets<\/li>\n<li>Random key storage files (*key, *keystore.json, UTC\u2013, IndexedDB)<\/li>\n<li>GitHub personal authentication tokens<\/li>\n<li>Access tokens for npm<\/li>\n<li>.env files<\/li>\n<li>RSA private keys (id_rsa).<\/li>\n<\/ul>\n<p>It\u2019s noteworthy that popular LLMs running via command line tools were used for the searches. If Anthropic Claude, Amazon Q or Google Gemini CLI tools were installed on the system, script made an insecure query that required finding all the listed data types.<\/p>\n<p>All found data was uploaded to GitHub in obfuscated form \u2014 encoded in base64 multiple times. To do this, the malware used stolen GitHub tokens, created a publicly accessible s1ngularity-repository, s1ngularity-repository-0, or s1ngularity-repository-1 on behalf of the victim, and uploaded a single results.b64 file there.<\/p>\n<p>The attackers probably aim to quickly exploit the stolen data; after all, the malicious script hasn\u2019t tried to be stealthy, but instead tried to aggressively isolate the victim from accessing working systems. To do this, it added the <em>sudo shutdown<\/em> command to~ \/.bashrc and ~\/.zshrc, resulting in new terminal sessions immediately initiating a system shutdown.<\/p>\n<h2>How to test your systems<\/h2>\n<p>Organizations using Nx should check their package versions, and audit their GitHub accounts and logs.<\/p>\n<ol>\n<li><strong> Check the Nx package versions in use with the <\/strong><em>npm ls nx<\/em> command<\/li>\n<li><strong>Check for any Nx packages in <\/strong>package-lock.json<\/li>\n<li><strong>Check for security events <\/strong><a href=\"https:\/\/github.com\/settings\/security-log\" target=\"_blank\" rel=\"nofollow noopener\"><strong>in the GitHub logs<\/strong><\/a><strong>.<\/strong><\/li>\n<\/ol>\n<p>If repositories named s1ngularity-repository* are found, download the results.b64 files from them for further investigation, and remove them from GitHub.<\/p>\n<p>When malicious repositories are detected:<\/p>\n<ol>\n<li><strong> Remove node_modules completely: <\/strong><em>rm -rf node_modules<\/em><\/li>\n<li><strong>Clean the npm cache: <\/strong><em>npm cache clean \u2013force<\/em><\/li>\n<li><strong>Check and clean out extraneous commands from <\/strong><em>~\/.bashrc<\/em> and <em>~\/.zshrc<\/em><\/li>\n<li><strong>Make an archive copy for investigation and delete the <\/strong><em>\/tmp\/inventory.txt<\/em> and <em>\/tmp\/inventory.txt.bak<\/em> <strong>files from the system <\/strong><\/li>\n<li><strong> Remove malicious package versions from <\/strong><em>package-lock.json<\/em><\/li>\n<li><strong> Reinstall the safe versions of the packages.<\/strong><\/li>\n<\/ol>\n<p><strong>The most critical and urgent action for compromised systems is to update all secrets that the malware may have accessed by the malware <\/strong>(GitHub PATs, npm tokens, SSH keys, API keys in .env files and Claude, Gemini and Q keys).<\/p>\n<p>You should also continue to monitor your GitHub repositories. First, even after all these steps, there may still be Trojanized versions of Nx on compromised systems that will continue to download stolen information. Second, if attackers have already managed to use the stolen tokens before they rotate them, this will most likely manifest itself in unauthorized commits or malicious changes to GitHub actions.<\/p>\n<input type=\"hidden\" class=\"category_for_banner\" value=\"mdr\">\n","protected":false},"excerpt":{"rendered":"<p>A popular developer tool has been trojanized and is uploading secrets to public GitHub repositories. We discuss what\u2019s important to know for both developers and cybersecurity services.<\/p>\n","protected":false},"author":2698,"featured_media":54224,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1999,3051,3052],"tags":[3965,4618,2918,422],"class_list":{"0":"post-54223","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","7":"category-business","8":"category-enterprise","9":"category-smb","10":"tag-incidents","11":"tag-response","12":"tag-supply-chain","13":"tag-threats"},"hreflang":[{"hreflang":"x-default","url":"https:\/\/www.kaspersky.com\/blog\/nx-build-s1ngularity-supply-chain-attack\/54223\/"},{"hreflang":"en-in","url":"https:\/\/www.kaspersky.co.in\/blog\/nx-build-s1ngularity-supply-chain-attack\/29499\/"},{"hreflang":"en-ae","url":"https:\/\/me-en.kaspersky.com\/blog\/nx-build-s1ngularity-supply-chain-attack\/24608\/"},{"hreflang":"en-gb","url":"https:\/\/www.kaspersky.co.uk\/blog\/nx-build-s1ngularity-supply-chain-attack\/29435\/"},{"hreflang":"ru","url":"https:\/\/www.kaspersky.ru\/blog\/nx-build-s1ngularity-supply-chain-attack\/40369\/"},{"hreflang":"ru-kz","url":"https:\/\/blog.kaspersky.kz\/nx-build-s1ngularity-supply-chain-attack\/29616\/"},{"hreflang":"en-au","url":"https:\/\/www.kaspersky.com.au\/blog\/nx-build-s1ngularity-supply-chain-attack\/35363\/"},{"hreflang":"en-za","url":"https:\/\/www.kaspersky.co.za\/blog\/nx-build-s1ngularity-supply-chain-attack\/34992\/"}],"acf":[],"banners":"","maintag":{"url":"https:\/\/www.kaspersky.com\/blog\/tag\/supply-chain\/","name":"supply chain"},"_links":{"self":[{"href":"https:\/\/www.kaspersky.com\/blog\/wp-json\/wp\/v2\/posts\/54223","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.kaspersky.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.kaspersky.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.kaspersky.com\/blog\/wp-json\/wp\/v2\/users\/2698"}],"replies":[{"embeddable":true,"href":"https:\/\/www.kaspersky.com\/blog\/wp-json\/wp\/v2\/comments?post=54223"}],"version-history":[{"count":2,"href":"https:\/\/www.kaspersky.com\/blog\/wp-json\/wp\/v2\/posts\/54223\/revisions"}],"predecessor-version":[{"id":54227,"href":"https:\/\/www.kaspersky.com\/blog\/wp-json\/wp\/v2\/posts\/54223\/revisions\/54227"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.kaspersky.com\/blog\/wp-json\/wp\/v2\/media\/54224"}],"wp:attachment":[{"href":"https:\/\/www.kaspersky.com\/blog\/wp-json\/wp\/v2\/media?parent=54223"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.kaspersky.com\/blog\/wp-json\/wp\/v2\/categories?post=54223"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.kaspersky.com\/blog\/wp-json\/wp\/v2\/tags?post=54223"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}