{"id":26303,"date":"2026-10-06T23:00:12","date_gmt":"2026-10-07T07:00:12","guid":{"rendered":"https:\/\/www.palada.net\/index.php\/2026\/10\/06\/dependency-installation-security-measure-already-defeated-on-npm\/"},"modified":"2026-10-06T23:00:12","modified_gmt":"2026-10-07T07:00:12","slug":"dependency-installation-security-measure-already-defeated-on-npm","status":"publish","type":"post","link":"http:\/\/www.palada.net\/index.php\/2026\/10\/06\/dependency-installation-security-measure-already-defeated-on-npm\/","title":{"rendered":"Dependency installation security measure already defeated on npm"},"content":{"rendered":"<div class=\"rich-text_richText__UyrDZ\" data-anchor-headings=\"true\" data-component=\"rich-text\" data-reader-view=\"false\">\n<div class=\"payload-richtext\">\n<div class=\"callout-block_highlight__zUB32\" data-accent-bar=\"true\" data-background=\"highlight-gray\" data-component=\"callout-block\">\n<p class=\"callout-block_heading__sSD7c\" data-subtitle=\"lg\">Key takeaways<\/p>\n<div class=\"rich-text_richText__UyrDZ\" data-component=\"rich-text\" data-reader-view=\"false\">\n<div class=\"payload-richtext\">\n<ul class=\"list-bullet\">\n<li class=\"\" value=\"1\"><strong>npm&#8217;s July fix has already been bypassed.<\/strong> Version 12 stopped running install scripts by default, but the malicious indexed-btree package hides its trigger in a prototype method. The malware runs when the app uses the library, not when it&#8217;s installed.<\/li>\n<li class=\"\" value=\"2\"><strong>A clean package.json is no longer a trust signal.<\/strong> Having no install hooks gave reviewers false comfort. This campaign targets that blind spot, and it backs the package with a fake GitHub repo and developer profile.<\/li>\n<li class=\"\" value=\"3\"><strong>Install-time checks aren&#8217;t enough.<\/strong> Malware that waits until the code runs blends into normal app behavior and gets the app&#8217;s credentials and network access. Defenders need to analyze runtime behavior and binaries, not just scan install scripts.<\/li>\n<li class=\"\" value=\"4\"><strong>Removing the package doesn&#8217;t fix the problem.<\/strong> Teams that pulled in indexed-btree should find out whether it ran, look for exposed credentials, and rebuild affected environments from trusted sources. The attackers&#8217; command-and-control infrastructure is still running.<\/li>\n<\/ul>\n<\/div>\n<\/div>\n<\/div>\n<p>New research shows that attackers have already routed around a measure that npm adopted in July to close a longstanding security gap. Version 12 of the package manager stopped running dependency install scripts by default in an attempt to shut down a vector for software supply chain attacks.<\/p>\n<p>Researchers have detected an ongoing npm supply chain campaign built on the malicious indexed-btree package, which mimics the legitimate sorted-btree library. Instead of a preinstall or postinstall script, the malware trigger is buried inside the package\u2019s own prototype method and fires the moment the library is used, <a href=\"https:\/\/www.linkedin.com\/in\/bruno-r-dias?originalSubdomain=pt\"><span style=\"text-decoration:underline\">Bruno Dias<\/span><\/a> <a href=\"https:\/\/checkmarx.com\/zero-post\/npm-btree-malware-campaign-affects-millions-of-downloads-no-need-for-install-script\/\" rel=\"noopener noreferrer\" target=\"_blank\"><span style=\"text-decoration:underline\">explained<\/span><\/a> in Checkmarx\u2019s application security testing blog.\u00a0<\/p>\n<p>The dependency install script change at npm was meant to cut off exactly this class of malware, said Darren Meyer, a research advocate at Checkmarx. However, once running, the malware fingerprints hosts, exfiltrates data via Slack and Telegram, and uses an Ethereum smart contract as a resilient command-and-control channel.<\/p>\n<p style=\"padding-inline-start:40px\"><em>\u00a0\u201cAttackers just moved to a new vector.\u201d <\/em><br \/>\u2014<a href=\"https:\/\/www.linkedin.com\/in\/darrenmeyer\/\"><span style=\"text-decoration:underline\">Darren Meyer<\/span><br \/><\/a><\/p>\n<p>Here\u2019s what you need to know about why npm\u2019s security measure could be so easily sidestepped.<\/p>\n<p><strong>[ See webinar: <\/strong><a href=\"https:\/\/www.reversinglabs.com\/webinar\/binary-analysis-third-party-software-risk\"><strong>Why Binary Analysis Is Becoming the New Standard<\/strong><\/a><strong> ]<\/strong><\/p>\n<h2 id=\"a-false-sense-of-comfort\"><strong>A false sense of comfort?<\/strong><\/h2>\n<p>Waseem Ahmed, head of engineering at Secure.com, noted that some researchers had warned when npm shipped the lifecycle script change that the code still has to run at some point. \u201cIf you close the door at install time, a patient attacker moves one step downstream and runs it at import time instead,\u201d he said.<\/p>\n<p>Ahmed also said that the absence of an install script had quietly become a trust signal: reviewers would glance at the <em>package.json<\/em>, see no hooks, and relax. This btree package has a completely clean <em>package.json<\/em>, with the malware sitting in the library\u2019s own prototype method.<\/p>\n<p style=\"padding-inline-start:40px\"><em>\u201cSo the single heuristic that npm\u2019s change encouraged people to rely on is exactly the heuristic this defeats.\u201d<\/em><br \/>\u2014<a href=\"https:\/\/www.linkedin.com\/in\/waseemahmedk\/\"><span style=\"text-decoration:underline\">Waseem Ahmed<\/span><br \/><\/a><\/p>\n<p>Sonu Kapoor, a senior Angular consultant at Solid Software Solutions, agreed that npm\u2019s July measure may have signaled to security teams that install time is the moment an npm package becomes dangerous. But a dependency doesn\u2019t need to misbehave during installation, he said; it can wait until the application uses it. By then it may be running in a production service with access to credentials, internal systems, and customer information.<\/p>\n<p style=\"padding-inline-start:40px\"><em>\u201cThat delay matters because the malicious activity can blend into normal application execution.\u201d<\/em><br \/>\u2014<a href=\"https:\/\/www.linkedin.com\/in\/sonu-kapoor\/\"><span style=\"text-decoration:underline\">Sonu Kapoor<\/span><br \/><\/a><\/p>\n<h2 id=\"a-malware-sleeper-cell\"><strong>A malware sleeper cell<\/strong><\/h2>\n<p>A clean install tells a user only that the package manager saw nothing suspicious, said <a href=\"https:\/\/www.linkedin.com\/in\/jacob-krell\/\"><span style=\"text-decoration:underline\">Jacob Krell<\/span><\/a>, senior director for secure AI solutions and cybersecurity at Suzu Labs. It says little about what will happen when the application uses the package. In this case, the loader was hidden inside <em>btree.prototype.set<\/em>, Krell said, so it ran in the application\u2019s normal execution context, with the same permissions and network access as the application itself.<\/p>\n<p>Jason Soroko, a senior fellow at Sectigo, said that, in simple terms, the attacker has moved from package installation to package use.<\/p>\n<p style=\"padding-inline-start:40px\"><em>\u201cThat makes relying solely on installation-time security checks insufficient.\u201d.<\/em><br \/>\u2014<a href=\"https:\/\/www.linkedin.com\/in\/jason-soroko-19b41920?originalSubdomain=ca\"><span style=\"text-decoration:underline\">Jason Soroko<\/span><\/a><\/p>\n<p>Aviram Jenik, CEO of KhaiCode, said this shift to activation upon use turns the malware into a \u201csleeper cell\u201d waiting for activation.\u00a0<\/p>\n<p style=\"padding-inline-start:40px\"><em>\u201cThis makes it borderline impossible to detect by any static analysis tools, which will not see this path activated. The only way to detect this is by actively running the application with dynamic analysis.\u201d<\/em><br \/><em>\u2014<\/em><a href=\"https:\/\/www.linkedin.com\/in\/aviramjenik\/\"><span style=\"text-decoration:underline\">Aviram Jenik<\/span><\/a><\/p>\n<p>The attackers also built cover for the package, Jenik noted, adding a fake but plausible-looking GitHub repository and commit history and a developer profile complete with photo. The public repository contains none of the malicious code, so scanning it turns up nothing.<\/p>\n<h2 id=\"attackers-never-give-up\"><strong>Attackers never give up<\/strong><\/h2>\n<p>This incident shows that attackers always adapt to security controls rather than simply giving up, said <a href=\"https:\/\/www.linkedin.com\/in\/boris-cipot-58a0a620\/\"><span style=\"text-decoration:underline\">Boris Cipot<\/span><\/a>, a security engineer at Black Duck Software. Blocking lifecycle scripts such as preinstall and postinstall removes an important attack route, he said, but it does not make the package itself trustworthy.<\/p>\n<p>Software composition analysis can help when combined with malicious-package intelligence and policy enforcement, by identifying and blocking known malicious dependencies before they progress further through the development process. But, Cipot said, it should be just one layer of a broader defense that also includes package validation, secure development environments, and monitoring of application behavior.\u00a0<\/p>\n<p>Complex binary analysis can <a href=\"https:\/\/www.reversinglabs.com\/blog\/the-power-of-complex-binary-analysis\"><span style=\"text-decoration:underline\">dissect and scrutinize the binary code<\/span><\/a> without the execution of \u2014 or even the need for \u2014 source code. The Enduring Security Framework group, a public-private working group led by the National Security Agency and the Cybersecurity and Infrastructure Security Agency, has published new guidelines focused heavily on practices for ensuring the security of open-source components in enterprise software. But within its guidance document, the ESF goes a step further, calling for application security testing tools that go beyond legacy testing by <a href=\"https:\/\/www.reversinglabs.com\/blog\/esf-steps-up-guidance-with-call-for-binary-analysis-reproducible-builds\"><span style=\"text-decoration:underline\">using complex binary analysis, as well as employing reproducible builds<\/span><\/a>.<\/p>\n<p>Matt Rose, former field CISO at ReversingLabs, said that binary code analysis can help organizations evaluate and verify the security of not just internally developed software, but also third-party commercial software in their environment.<\/p>\n<p style=\"padding-inline-start:40px\"><em>\u201cIt is the final examination of a package for software supply chain risk, which allows for trust in that piece of software that you are either developing for your customers or that you are buying to help operate your business.\u201d<\/em><br \/>\u2014<a href=\"https:\/\/www.linkedin.com\/in\/mattarose\/\"><span style=\"text-decoration:underline\">Matt Rose<\/span><\/a><\/p>\n<p>Organizations that pulled in indexed-btree or related packages from this campaign can\u2019t fix things by simply removing the dependency, Cipot warned. They should determine where the package was present and whether it executed, investigate affected systems for suspicious activity and possible exposure of credentials or secrets, and rebuild affected environments from trusted sources where necessary.<\/p>\n<h2 id=\"beyond-btree-watch-this-space\"><strong>Beyond btree: Watch this space<\/strong><\/h2>\n<p>Blocking lifecycle scripts is still useful, Krell said, but it is a speed bump rather than a package trust model. He would look at what a dependency does when its normal APIs are called, not just whether it carries a suspicious postinstall script. \u201cThis campaign shows why runtime behavior matters,\u201d he said, \u201cespecially for packages that appear to be ordinary utility libraries.\u201d<\/p>\n<p>The campaign is not limited to the btree packages, Checkmarx\u2019s Meyer said. The command-and-control infrastructure still exists, and researchers expect the threat actors to continue publishing and profiting from npm malware.\u00a0<\/p>\n<p style=\"padding-inline-start:40px\"><em>\u201cIt\u2019s good that npm disabled lifecycle scripts by default, as it does have security value, but it is important that organizations do not have a false sense of security. It doesn\u2019t stop infections. It just moves the vector.\u201d<\/em><br \/><em>\u2014<\/em>Darren Meyer<\/p>\n<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Key takeawaysnpm&#8217;s July fix has already been bypassed.Version 12 stopped running install scripts by default, but the malicious indexed-btree package hides its trigger in a prototype method. The malware runs when the app uses the library, not when it&#8217;s installed.A clean package.json is no longer a trust signal.Having no install hooks gave reviewers false comfort. This campaign targets that blind spot, and it backs the package with a fake GitHub repo and developer profile.Install-time checks aren&#8217;<\/p>\n","protected":false},"author":4,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"colormag_page_container_layout":"default_layout","colormag_page_sidebar_layout":"default_layout","footnotes":""},"categories":[32775],"tags":[],"class_list":["post-26303","post","type-post","status-publish","format-standard","hentry","category-reversinglabs"],"_links":{"self":[{"href":"http:\/\/www.palada.net\/index.php\/wp-json\/wp\/v2\/posts\/26303","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.palada.net\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.palada.net\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.palada.net\/index.php\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"http:\/\/www.palada.net\/index.php\/wp-json\/wp\/v2\/comments?post=26303"}],"version-history":[{"count":0,"href":"http:\/\/www.palada.net\/index.php\/wp-json\/wp\/v2\/posts\/26303\/revisions"}],"wp:attachment":[{"href":"http:\/\/www.palada.net\/index.php\/wp-json\/wp\/v2\/media?parent=26303"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.palada.net\/index.php\/wp-json\/wp\/v2\/categories?post=26303"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.palada.net\/index.php\/wp-json\/wp\/v2\/tags?post=26303"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}