{"id":99965,"date":"2025-01-14T11:54:33","date_gmt":"2025-01-14T09:54:33","guid":{"rendered":"https:\/\/staging.checkmarx.com\/?p=99965"},"modified":"2025-01-23T11:11:24","modified_gmt":"2025-01-23T09:11:24","slug":"npm-command-confusion","status":"publish","type":"zero-post","link":"https:\/\/checkmarx.com\/blog\/npm-command-confusion\/","title":{"rendered":"NPM command confusion\u00a0"},"content":{"rendered":"<h2 class=\"wp-block-heading article-anchor\" id=\"article-anchor-1\">\n<strong>Intro<\/strong>&nbsp;<\/h2>\n\n\n\n<p>Managing dependencies in JavaScript projects can quickly become a complex undertaking. Tasks include keeping track of versions, ensuring compatibility, and handling updates . npm provides a robust solution to these problems, through a centralized system for managing project dependencies. Primarily accessed through its command-line interface (CLI), npm enables developers to seamlessly install, manage, and share code dependencies.&nbsp;<\/p>\n\n\n\n<h2 class=\"wp-block-heading article-anchor\" id=\"article-anchor-2\">\n<strong>The story<\/strong>&nbsp;<\/h2>\n\n\n\n<p>About a decade ago, the npm CLI&nbsp; <a href=\"https:\/\/github.com\/npm\/cli\/commit\/f0bf684a87ea5eea03432a17f38678fed4960d43\" target=\"_blank\" rel=\"noreferrer noopener\">added aliases<\/a> to the commands to reduce the time spent typing the heavily used ones. For example, \u201cnpm install\u201d was shortened to \u201cnpm i&#8221;. This feature kept evolving, trying to add all possible permutations and attempting to catch typos: add-user for npm adduser, \u201cinstal\u201d or \u201cinsta\u201d for npm install.&nbsp;<\/p>\n\n\n\n<p>When yet another alias &#8211; \u201cnpm add\u201d for npm install &#8211; <a href=\"https:\/\/github.com\/npm\/cli\/pull\/160\" target=\"_blank\" rel=\"noreferrer noopener\">was added<\/a>, everyone overlooked the potential confusion with the existing &#8220;npm adduser&#8221; command (which already had the alias &#8220;add-user&#8221;).&nbsp;&nbsp;<\/p>\n\n\n\n<p>When carefully reading \u201cnpm adduser\u201d and \u201cnpm add user\u201d, we can clearly see the difference, but when we swiftly type it, the chance of hitting a whitespace is extremely high.&nbsp;<\/p>\n\n\n\n<p>In the PR that added this new alias to the documentation, the user ahasall pointed out this issue, but their warning went unnoticed.&nbsp;&nbsp;<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img decoding=\"async\" width=\"1024\" height=\"860\" src=\"https:\/\/checkmarx.com\/wp-content\/uploads\/2025\/01\/image-9-1024x860.png\" alt=\"NPN CLI page \" class=\"wp-image-99968\" style=\"width:640px\" srcset=\"https:\/\/checkmarx.com\/wp-content\/uploads\/2025\/01\/image-9-1024x860.png 1024w, https:\/\/checkmarx.com\/wp-content\/uploads\/2025\/01\/image-9-300x252.png 300w, https:\/\/checkmarx.com\/wp-content\/uploads\/2025\/01\/image-9-768x645.png 768w, https:\/\/checkmarx.com\/wp-content\/uploads\/2025\/01\/image-9.png 1426w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading article-anchor\" id=\"article-anchor-3\">\n<strong>The issue<\/strong>&nbsp;<\/h2>\n\n\n\n<p>NPM has two commands that look almost identical but do completely different things: \u201cnpm add user\u201d and \u201cnpm adduser\u201d.&nbsp;<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><img decoding=\"async\" width=\"1024\" height=\"597\" src=\"https:\/\/checkmarx.com\/wp-content\/uploads\/2025\/01\/image-8-1024x597.png\" alt=\"NPN Docs screenshot \" class=\"wp-image-99967\" srcset=\"https:\/\/checkmarx.com\/wp-content\/uploads\/2025\/01\/image-8-1024x597.png 1024w, https:\/\/checkmarx.com\/wp-content\/uploads\/2025\/01\/image-8-300x175.png 300w, https:\/\/checkmarx.com\/wp-content\/uploads\/2025\/01\/image-8-768x448.png 768w, https:\/\/checkmarx.com\/wp-content\/uploads\/2025\/01\/image-8.png 1426w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n<\/div>\n\n\n<p><\/p>\n\n\n\n<p>The \u201cnpm add <em>example-package&#8221;<\/em> command is an alias of \u201cnpm install\u201d and simply installs the <strong><em>examplepackage<\/em><\/strong><strong> <\/strong>package, while \u201cnpm adduser\u201d creates a new user in the specified registry.&nbsp;<\/p>\n\n\n\n<p>When you set up the npm cli, you need to type \u201cnpm adduser\u201d to log into the registry. What is the chance of typing \u201cnpm add user\u201d instead of \u201cadduser\u201d? Apparently, it\u2019s very high. According to npm-stat.com, downloads of the \u201cuser\u201d package\u2019 have risen dramatically, reaching nearly 12 million in total.&nbsp;<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img decoding=\"async\" width=\"1024\" height=\"597\" src=\"https:\/\/checkmarx.com\/wp-content\/uploads\/2025\/01\/image-7-1024x597.png\" alt=\"screenshot showing packages download chart\" class=\"wp-image-99966\" style=\"width:640px\" srcset=\"https:\/\/checkmarx.com\/wp-content\/uploads\/2025\/01\/image-7-1024x597.png 1024w, https:\/\/checkmarx.com\/wp-content\/uploads\/2025\/01\/image-7-300x175.png 300w, https:\/\/checkmarx.com\/wp-content\/uploads\/2025\/01\/image-7-768x448.png 768w, https:\/\/checkmarx.com\/wp-content\/uploads\/2025\/01\/image-7.png 1426w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Judging by the statistics, many developers have made this typo and inadvertently installed the package. NPM reports that there are 2760 dependent packages, at least 20 of which were added in December 2024.&nbsp;<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large is-resized\"><img decoding=\"async\" width=\"1024\" height=\"800\" src=\"https:\/\/checkmarx.com\/wp-content\/uploads\/2025\/01\/image-10-1024x800.png\" alt=\"NPM 2760 dependent packages\" class=\"wp-image-99969\" style=\"width:640px\" srcset=\"https:\/\/checkmarx.com\/wp-content\/uploads\/2025\/01\/image-10-1024x800.png 1024w, https:\/\/checkmarx.com\/wp-content\/uploads\/2025\/01\/image-10-300x234.png 300w, https:\/\/checkmarx.com\/wp-content\/uploads\/2025\/01\/image-10-768x600.png 768w, https:\/\/checkmarx.com\/wp-content\/uploads\/2025\/01\/image-10.png 1426w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n<\/div>\n\n\n<p><\/p>\n\n\n\n<p>Currently the package itself is benign and is simply a hello-world app. However, future versions of it could potentially contain malicious code, leading to infection of the unsuspecting victims who will make this typing error.&nbsp;&nbsp;<\/p>\n\n\n\n<p>Therefore, while whoever has the current benign version in their package.json is safe,&nbsp; those who upgrade or install it for the first time could be exposed to malware.&nbsp;&nbsp;<\/p>\n\n\n\n<h2 class=\"wp-block-heading article-anchor\" id=\"article-anchor-4\">Conclusion\u00a0<\/h2>\n\n\n\n<p>Tool designers must carefully consider all existing commands to prevent any potential confusion between them.\u00a0                                                                                                                                                            The package remains a ticking bomb for the thousands of developers who inadvertently installed it.\u00a0<\/p>\n\n\n\n<p><strong>The issue has been reported to npm; the post will be updated with the response.<\/strong>&nbsp;<\/p>","protected":false},"excerpt":{"rendered":"<p>Intro&nbsp; Managing dependencies in JavaScript projects can quickly become a complex undertaking. Tasks include keeping track of versions, ensuring compatibility, and handling updates . npm provides a robust solution to these problems, through a centralized system for managing project dependencies. Primarily accessed through its command-line interface (CLI), npm enables developers to seamlessly install, manage, and [&hellip;]<\/p>\n","protected":false},"author":18,"featured_media":99970,"template":"","zero-category":[1067],"zero-tag":[1068],"class_list":["post-99965","zero-post","type-zero-post","status-publish","has-post-thumbnail","hentry","zero-category-blog","zero-tag-checkmarx-security-research-team"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.1.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>NPM command confusion\u00a0 - Checkmarx<\/title>\n<meta name=\"description\" content=\"NPM two commands that look identical but do completely different things: \u201cnpm add user\u201d and \u201cnpm adduser\u201d. Holds a potential security risk\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/checkmarx.com\/blog\/npm-command-confusion\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"NPM command confusion\u00a0 - Checkmarx\" \/>\n<meta property=\"og:description\" content=\"NPM two commands that look identical but do completely different things: \u201cnpm add user\u201d and \u201cnpm adduser\u201d. Holds a potential security risk\" \/>\n<meta property=\"og:url\" content=\"https:\/\/checkmarx.com\/blog\/npm-command-confusion\/\" \/>\n<meta property=\"og:site_name\" content=\"Checkmarx\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/Checkmarx.Source.Code.Analysis\" \/>\n<meta property=\"article:modified_time\" content=\"2025-01-23T09:11:24+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/checkmarx.com\/wp-content\/uploads\/2025\/01\/Frame-11527659.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1024\" \/>\n\t<meta property=\"og:image:height\" content=\"512\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:site\" content=\"@checkmarx\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"2 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/checkmarx.com\/blog\/npm-command-confusion\/\",\"url\":\"https:\/\/checkmarx.com\/blog\/npm-command-confusion\/\",\"name\":\"NPM command confusion\u00a0 - Checkmarx\",\"isPartOf\":{\"@id\":\"https:\/\/checkmarx.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/checkmarx.com\/blog\/npm-command-confusion\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/checkmarx.com\/blog\/npm-command-confusion\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/checkmarx.com\/wp-content\/uploads\/2025\/01\/Frame-11527659.png\",\"datePublished\":\"2025-01-14T09:54:33+00:00\",\"dateModified\":\"2025-01-23T09:11:24+00:00\",\"description\":\"NPM two commands that look identical but do completely different things: \u201cnpm add user\u201d and \u201cnpm adduser\u201d. Holds a potential security risk\",\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/checkmarx.com\/blog\/npm-command-confusion\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/checkmarx.com\/blog\/npm-command-confusion\/#primaryimage\",\"url\":\"https:\/\/checkmarx.com\/wp-content\/uploads\/2025\/01\/Frame-11527659.png\",\"contentUrl\":\"https:\/\/checkmarx.com\/wp-content\/uploads\/2025\/01\/Frame-11527659.png\",\"width\":1024,\"height\":512},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/checkmarx.com\/#website\",\"url\":\"https:\/\/checkmarx.com\/\",\"name\":\"Checkmarx\",\"description\":\"The world runs on code. We secure it.\",\"publisher\":{\"@id\":\"https:\/\/checkmarx.com\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/checkmarx.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/checkmarx.com\/#organization\",\"name\":\"Checkmarx\",\"url\":\"https:\/\/checkmarx.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/checkmarx.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/checkmarx.com\/wp-content\/uploads\/2024\/02\/logo-dark.svg\",\"contentUrl\":\"https:\/\/checkmarx.com\/wp-content\/uploads\/2024\/02\/logo-dark.svg\",\"width\":1,\"height\":1,\"caption\":\"Checkmarx\"},\"image\":{\"@id\":\"https:\/\/checkmarx.com\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/Checkmarx.Source.Code.Analysis\",\"https:\/\/x.com\/checkmarx\",\"https:\/\/www.youtube.com\/user\/CheckmarxResearchLab\",\"https:\/\/www.linkedin.com\/company\/checkmarx\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"NPM command confusion\u00a0 - Checkmarx","description":"NPM two commands that look identical but do completely different things: \u201cnpm add user\u201d and \u201cnpm adduser\u201d. Holds a potential security risk","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/checkmarx.com\/blog\/npm-command-confusion\/","og_locale":"en_US","og_type":"article","og_title":"NPM command confusion\u00a0 - Checkmarx","og_description":"NPM two commands that look identical but do completely different things: \u201cnpm add user\u201d and \u201cnpm adduser\u201d. Holds a potential security risk","og_url":"https:\/\/checkmarx.com\/blog\/npm-command-confusion\/","og_site_name":"Checkmarx","article_publisher":"https:\/\/www.facebook.com\/Checkmarx.Source.Code.Analysis","article_modified_time":"2025-01-23T09:11:24+00:00","og_image":[{"width":1024,"height":512,"url":"https:\/\/checkmarx.com\/wp-content\/uploads\/2025\/01\/Frame-11527659.png","type":"image\/png"}],"twitter_card":"summary_large_image","twitter_site":"@checkmarx","twitter_misc":{"Est. reading time":"2 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/checkmarx.com\/blog\/npm-command-confusion\/","url":"https:\/\/checkmarx.com\/blog\/npm-command-confusion\/","name":"NPM command confusion\u00a0 - Checkmarx","isPartOf":{"@id":"https:\/\/checkmarx.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/checkmarx.com\/blog\/npm-command-confusion\/#primaryimage"},"image":{"@id":"https:\/\/checkmarx.com\/blog\/npm-command-confusion\/#primaryimage"},"thumbnailUrl":"https:\/\/checkmarx.com\/wp-content\/uploads\/2025\/01\/Frame-11527659.png","datePublished":"2025-01-14T09:54:33+00:00","dateModified":"2025-01-23T09:11:24+00:00","description":"NPM two commands that look identical but do completely different things: \u201cnpm add user\u201d and \u201cnpm adduser\u201d. Holds a potential security risk","inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/checkmarx.com\/blog\/npm-command-confusion\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/checkmarx.com\/blog\/npm-command-confusion\/#primaryimage","url":"https:\/\/checkmarx.com\/wp-content\/uploads\/2025\/01\/Frame-11527659.png","contentUrl":"https:\/\/checkmarx.com\/wp-content\/uploads\/2025\/01\/Frame-11527659.png","width":1024,"height":512},{"@type":"WebSite","@id":"https:\/\/checkmarx.com\/#website","url":"https:\/\/checkmarx.com\/","name":"Checkmarx","description":"The world runs on code. We secure it.","publisher":{"@id":"https:\/\/checkmarx.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/checkmarx.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/checkmarx.com\/#organization","name":"Checkmarx","url":"https:\/\/checkmarx.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/checkmarx.com\/#\/schema\/logo\/image\/","url":"https:\/\/checkmarx.com\/wp-content\/uploads\/2024\/02\/logo-dark.svg","contentUrl":"https:\/\/checkmarx.com\/wp-content\/uploads\/2024\/02\/logo-dark.svg","width":1,"height":1,"caption":"Checkmarx"},"image":{"@id":"https:\/\/checkmarx.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/Checkmarx.Source.Code.Analysis","https:\/\/x.com\/checkmarx","https:\/\/www.youtube.com\/user\/CheckmarxResearchLab","https:\/\/www.linkedin.com\/company\/checkmarx"]}]}},"_links":{"self":[{"href":"https:\/\/checkmarx.com\/wp-json\/wp\/v2\/zero-post\/99965","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/checkmarx.com\/wp-json\/wp\/v2\/zero-post"}],"about":[{"href":"https:\/\/checkmarx.com\/wp-json\/wp\/v2\/types\/zero-post"}],"author":[{"embeddable":true,"href":"https:\/\/checkmarx.com\/wp-json\/wp\/v2\/users\/18"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/checkmarx.com\/wp-json\/wp\/v2\/media\/99970"}],"wp:attachment":[{"href":"https:\/\/checkmarx.com\/wp-json\/wp\/v2\/media?parent=99965"}],"wp:term":[{"taxonomy":"zero-category","embeddable":true,"href":"https:\/\/checkmarx.com\/wp-json\/wp\/v2\/zero-category?post=99965"},{"taxonomy":"zero-tag","embeddable":true,"href":"https:\/\/checkmarx.com\/wp-json\/wp\/v2\/zero-tag?post=99965"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}