{"id":456,"date":"2017-08-02T00:24:48","date_gmt":"2017-08-01T21:24:48","guid":{"rendered":"https:\/\/iamakulov.com\/notes\/?p=456"},"modified":"2017-08-18T17:37:51","modified_gmt":"2017-08-18T14:37:51","slug":"npm-malicious-packages","status":"publish","type":"post","link":"https:\/\/iamakulov.com\/notes\/npm-malicious-packages\/","title":{"rendered":"Malicious packages in npm. Here\u2019s what to do"},"content":{"rendered":"<p>Here\u2019s all the information I\u2019ve found.<\/p>\n<div class=\"bordered-highlight bordered-highlight_large\">\n?\u2620\ufe0f?\n<\/div>\n<h1 id=\"what-happened\">What happened?<a href=\"https:\/\/iamakulov.com\/notes\/npm-malicious-packages\/#what-happened\" class=\"heading-link\" aria-label=\"Link to this section\" title=\"Link to this section\">#<\/a><\/h1>\n<p>People found malicious packages in npm that work like real ones, are named similarly real ones, but collect and send your process environment to a third-party server when you install them: <\/p>\n<blockquote class=\"twitter-tweet\" data-lang=\"en\">\n<p lang=\"en\" dir=\"ltr\"><a href=\"https:\/\/twitter.com\/kentcdodds\">@kentcdodds<\/a> Hi Kent, it looks like this npm package is stealing env variables on install, using your cross-env package as bait: <a href=\"https:\/\/t.co\/REsRG8Exsx\">pic.twitter.com\/REsRG8Exsx<\/a><\/p>\n<p>&mdash; Oscar Bolmsten (@o_cee) <a href=\"https:\/\/twitter.com\/o_cee\/status\/892306836199800836\">August 1, 2017<\/a><\/p><\/blockquote>\n<p><script async src=\"\/\/platform.twitter.com\/widgets.js\" charset=\"utf-8\"><\/script><\/p>\n<p>This is dangerous because, on CI servers, the environment usually includes different secret tokens.<\/p>\n<h1 id=\"what-to-do-if-im-a-user\">What to do if I\u2019m a user?<a href=\"https:\/\/iamakulov.com\/notes\/npm-malicious-packages\/#what-to-do-if-im-a-user\" class=\"heading-link\" aria-label=\"Link to this section\" title=\"Link to this section\">#<\/a><\/h1>\n<p><mark>Regenerate the secret tokens<\/mark> if you installed any package from these as a dependency:<\/p>\n<div class='annotated-element annotated-element_has-code_no annotated-element_keep-size_no annotated-element_mobile-direction_content-then-annotation'>\n<div class='annotated-element__annotation'>\n<p><a href='http:\/\/imgur.com\/06bK0hj'>A screenshot<\/a> of the cached page with packages<\/p>\n<p>npm has also <a href='http:\/\/blog.npmjs.org\/post\/163723642530\/crossenv-malware-on-the-npm-registry'>confirmed this list<\/a><\/p>\n<\/div>\n<div class='annotated-element__content'>\n<pre><code class=\"text\">babelcli - v1.0.1 - Babel CLI for Nodejs\r\ncrossenv - v6.1.1 - Run scripts that set and use environment variables across platforms\r\ncross-env.js - v5.0.1\r\nd3.js - v1.0.1 - d3.js for Nodejs\r\nfabric-js - v1.7.18 - Object model for HTML5 canvas, and SVG-to-canvas parser. Backed by jsdom and node-canvas.\r\nffmepg - v0.0.1 - FFmpeg for Nodejs\r\ngruntcli - v1.0.1 - Grunt CLI for Nodejs\r\nhttp-proxy.js - v0.11.3 - Node.js proxy tools\r\njquery.js - v3.2.2-pre - jquery.js for Nodejs\r\nmariadb - v2.13.0 - A node.js driver for mysql. It is written in JavaScript, does not require compiling, and is 100% MIT licensed.\r\nmongose - v4.11.3 - Mongoose MongoDB ODM\r\nmssql.js - v4.0.5 - Microsoft SQL Server client for Node.js.\r\nmssql-node - v4.0.5 - Microsoft SQL Server client for Node.js.\r\nmysqljs - v2.13.0 - A node.js driver for mysql. It is written in JavaScript, does not require compiling, and is 100% MIT licensed.\r\nnodecaffe - v0.0.1 - caffe for Nodejs\r\nnodefabric - v1.7.18 - Object model for HTML5 canvas, and SVG-to-canvas parser. Backed by jsdom and node-canvas.\r\nnode-fabric - v1.7.18 - Object model for HTML5 canvas, and SVG-to-canvas parser. Backed by jsdom and node-canvas.\r\nnodeffmpeg - v0.0.1 - FFmpeg for Nodejs\r\nnodemailer-js - v4.0.1 - Easy as cake e-mail sending from your Node.js applications\r\nnodemailer.js - v4.0.1 - Easy as cake e-mail sending from your Node.js applications\r\nnodemssql - v4.0.5 - Microsoft SQL Server client for Node.js.\r\nnode-opencv - v1.0.1 - OpenCV for Nodejs\r\nnode-opensl - v1.0.1 - OpenSSL for Nodejs\r\nnode-openssl - v1.0.1 - OpenSSL for Nodejs\r\nnoderequest - v2.81.0 - Simplified HTTP request client.\r\nnodesass - v4.5.3 - Wrapper around libsass\r\nnodesqlite - v2.8.1 - SQLite client for Node.js applications with SQL-based migrations API\r\nnode-sqlite - v2.8.1 - SQLite client for Node.js applications with SQL-based migrations API\r\nnode-tkinter - v1.0.1 - Tkinter for Nodejs\r\nopencv.js - v1.0.1 - OpenCV for Nodejs\r\nopenssl.js - v1.0.1 - OpenSSL for Nodejs\r\nproxy.js - v0.11.3 - Node.js proxy tools\r\nshadowsock - v2.0.1 - A tunnel proxy that help you get through firewalls\r\nsmb - v1.5.1 - A Pure JavaScript SMB Server Implementation\r\nsqlite.js - v2.8.1 - SQLite client for Node.js applications with SQL-based migrations API\r\nsqliter - v2.8.1 - SQLite client for Node.js applications with SQL-based migrations API\r\nsqlserver - v4.0.5 - Microsoft SQL Server client for Node.js.\r\ntkinter - v1.0.1 - Tkinter for Nodejs\r\n<\/code><\/pre>\n<\/div>\n<\/div>\n<p>Here\u2019s also a one-liner that will list these packages if any of them was installed as a dependency:<\/p>\n<div class='annotated-element annotated-element_has-code_no annotated-element_keep-size_no annotated-element_mobile-direction_content-then-annotation'>\n<div class='annotated-element__annotation'>Twilio also listed one-liners <a href='https:\/\/www.twilio.com\/blog\/2017\/08\/find-projects-infected-by-malicious-npm-packages.html'>for checking the whole file system at once<\/a> (for bash and Powershell)<\/div>\n<div class='annotated-element__content'>\n<pre><code >npm ls | grep -E \"babelcli|crossenv|cross-env.js|d3.js|fabric-js|ffmepg|gruntcli|http-proxy.js|jquery.js|mariadb|mongose|mssql.js|mssql-node|mysqljs|nodecaffe|nodefabric|node-fabric|nodeffmpeg|nodemailer-js|nodemailer.js|nodemssql|node-opencv|node-opensl|node-openssl|noderequest|nodesass|nodesqlite|node-sqlite|node-tkinter|opencv.js|openssl.js|proxy.js|shadowsock|smb|sqlite.js|sqliter|sqlserver|tkinter\"\r\n<\/code><\/pre>\n<\/div>\n<\/div>\n<p>Always check the name of packages you\u2019re installing. You can look at the downloads number: if a package is popular but the downloads number is low, something is wrong.<\/p>\n<h1 id=\"what-to-do-if-im-a-library-developer\">What to do if I\u2019m a library developer?<a href=\"https:\/\/iamakulov.com\/notes\/npm-malicious-packages\/#what-to-do-if-im-a-library-developer\" class=\"heading-link\" aria-label=\"Link to this section\" title=\"Link to this section\">#<\/a><\/h1>\n<p>I see two options:<\/p>\n<ul>\n<li>Use scopes (<code>@scope\/package-name<\/code>) for your packages. <del datetime=\"2017-08-09T13:22:09+00:00\">With scopes, it\u2019s harder to install a wrong package accidentally: a user would have to misspell both the scope name and the package name.<\/del> Unfortunately, it\u2019s not: it\u2019s enough to misspell just the scope name (e.g <code>@babel\/babel-cli<\/code> \u2192 <code>@bable\/babel-cli<\/code>). Scopes <em>might<\/em> help a bit because they can have a simple name that\u2019s harder to misspell, but it\u2019s still not a universal solution.<\/li>\n<li>Take the most common misspellings of your packages by yourself. Think of the most common misspellings and publish empty packages under these names. You can also warn users about the right name with <a href=\"https:\/\/docs.npmjs.com\/cli\/deprecate\"><code>npm deprecate<\/code><\/a>.<\/li>\n<\/ul>\n<h1 id=\"is-this-even-ok\">Is this even OK?<a href=\"https:\/\/iamakulov.com\/notes\/npm-malicious-packages\/#is-this-even-ok\" class=\"heading-link\" aria-label=\"Link to this section\" title=\"Link to this section\">#<\/a><\/h1>\n<p>This isn\u2019t surprising \u2013 npm doesn\u2019t have any protection against this yet. In fact, that\u2019s why there could be other malicious packages. Stay careful and check package names.<\/p>\n<p>npm is working on a solution though:<\/p>\n<blockquote class=\"twitter-tweet\" data-lang=\"en\">\n<p lang=\"en\" dir=\"ltr\">I&#39;m working on a thing that uses quality metrics and prompts users. It would probably catch just about everything folks have brought up<\/p>\n<p>&mdash; \u591a\u5206\u25ef\u3061\u3083\u3093\u3088\u306d??\u200d\u2640\ufe0f (@maybekatz) <a href=\"https:\/\/twitter.com\/maybekatz\/status\/892501201551368192\">August 1, 2017<\/a><\/p><\/blockquote>\n<p><script async src=\"\/\/platform.twitter.com\/widgets.js\" charset=\"utf-8\"><\/script><\/p>\n<p>You can also participate in the Yarn\u2019s discussion <a href=\"https:\/\/github.com\/yarnpkg\/rfcs\/pull\/76\">about a white list for <code>preinstall<\/code>\/<code>postinstall<\/code> script packages<\/a>.<\/p>\n<hr \/>\n<p><!--p class=\"perf-consulting-snippet\">\n<mark>+1s in loading time of your app is \u22127% in conversion.<\/mark> I\u2019m launching consulting to help you make your React app or site load and run faster. Sign up as an early bird and get 10% discount: <a href=\"https:\/\/iamakulov.com\/perf-consulting\">iamakulov.com\/perf-consulting<\/a>\n<\/p-->\n","protected":false},"excerpt":{"rendered":"<p>Here\u2019s all the information I\u2019ve found. ?\u2620\ufe0f? What happened?# People found malicious packages in npm that work like real ones, are named similarly real ones, but collect and send your process environment to a third-party server when you install them: @kentcdodds Hi Kent, it looks like this npm package is stealing env variables on install, &hellip; <a href=\"https:\/\/iamakulov.com\/notes\/npm-malicious-packages\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Malicious packages in npm. Here\u2019s what to do&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[9],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v23.5 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Malicious packages in npm. Here\u2019s what to do - Ivan Akulov\u2019s blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/iamakulov.com\/notes\/npm-malicious-packages\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Malicious packages in npm. Here\u2019s what to do\" \/>\n<meta property=\"og:description\" content=\"If you\u2019re a user or a library author\" \/>\n<meta property=\"og:url\" content=\"https:\/\/iamakulov.com\/notes\/npm-malicious-packages\/\" \/>\n<meta property=\"og:site_name\" content=\"Ivan Akulov\u2019s blog\" \/>\n<meta property=\"article:publisher\" content=\"http:\/\/facebook.com\/iamakulov.page\" \/>\n<meta property=\"article:published_time\" content=\"2017-08-01T21:24:48+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2017-08-18T14:37:51+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/iamakulov.com\/notes2\/wp-content\/uploads\/2017\/08\/ApplicationFrameHost_2017-08-02_00-20-43-1.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1426\" \/>\n\t<meta property=\"og:image:height\" content=\"713\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Ivan Akulov\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:title\" content=\"Malicious packages in npm. Here\u2019s what to do\" \/>\n<meta name=\"twitter:description\" content=\"If you\u2019re a user or a library author\" \/>\n<meta name=\"twitter:image\" content=\"https:\/\/iamakulov.com\/notes2\/wp-content\/uploads\/2017\/08\/ApplicationFrameHost_2017-08-02_00-20-43-1.png\" \/>\n<meta name=\"twitter:creator\" content=\"@iamakulov\" \/>\n<meta name=\"twitter:site\" content=\"@iamakulov\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Ivan Akulov\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/iamakulov.com\/notes\/npm-malicious-packages\/\",\"url\":\"https:\/\/iamakulov.com\/notes\/npm-malicious-packages\/\",\"name\":\"Malicious packages in npm. Here\u2019s what to do - Ivan Akulov\u2019s blog\",\"isPartOf\":{\"@id\":\"https:\/\/iamakulov.com\/notes\/#website\"},\"datePublished\":\"2017-08-01T21:24:48+00:00\",\"dateModified\":\"2017-08-18T14:37:51+00:00\",\"author\":{\"@id\":\"https:\/\/iamakulov.com\/notes\/#\/schema\/person\/ebf7b61bf573e7be5fe438f50ebd9b81\"},\"breadcrumb\":{\"@id\":\"https:\/\/iamakulov.com\/notes\/npm-malicious-packages\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/iamakulov.com\/notes\/npm-malicious-packages\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/iamakulov.com\/notes\/npm-malicious-packages\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/iamakulov.com\/notes\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Malicious packages in npm. Here\u2019s what to do\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/iamakulov.com\/notes\/#website\",\"url\":\"https:\/\/iamakulov.com\/notes\/\",\"name\":\"Ivan Akulov\u2019s blog\",\"description\":\"Ivan Akulov writes about his front-end experience, React, webpack, and performance optimizations.\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/iamakulov.com\/notes\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/iamakulov.com\/notes\/#\/schema\/person\/ebf7b61bf573e7be5fe438f50ebd9b81\",\"name\":\"Ivan Akulov\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/iamakulov.com\/notes\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/f68e4cd477cef1577c339e6f09736d3a?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/f68e4cd477cef1577c339e6f09736d3a?s=96&d=mm&r=g\",\"caption\":\"Ivan Akulov\"},\"description\":\"I'm a software engineer specializing in web performance, JavaScript, and React. I\u2019m also a Google Developer Expert. I work at Framer.\",\"sameAs\":[\"http:\/\/iamakulov.com\",\"https:\/\/x.com\/iamakulov\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Malicious packages in npm. Here\u2019s what to do - Ivan Akulov\u2019s blog","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:\/\/iamakulov.com\/notes\/npm-malicious-packages\/","og_locale":"en_US","og_type":"article","og_title":"Malicious packages in npm. Here\u2019s what to do","og_description":"If you\u2019re a user or a library author","og_url":"https:\/\/iamakulov.com\/notes\/npm-malicious-packages\/","og_site_name":"Ivan Akulov\u2019s blog","article_publisher":"http:\/\/facebook.com\/iamakulov.page","article_published_time":"2017-08-01T21:24:48+00:00","article_modified_time":"2017-08-18T14:37:51+00:00","og_image":[{"width":1426,"height":713,"url":"https:\/\/iamakulov.com\/notes2\/wp-content\/uploads\/2017\/08\/ApplicationFrameHost_2017-08-02_00-20-43-1.png","type":"image\/png"}],"author":"Ivan Akulov","twitter_card":"summary_large_image","twitter_title":"Malicious packages in npm. Here\u2019s what to do","twitter_description":"If you\u2019re a user or a library author","twitter_image":"https:\/\/iamakulov.com\/notes2\/wp-content\/uploads\/2017\/08\/ApplicationFrameHost_2017-08-02_00-20-43-1.png","twitter_creator":"@iamakulov","twitter_site":"@iamakulov","twitter_misc":{"Written by":"Ivan Akulov","Est. reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/iamakulov.com\/notes\/npm-malicious-packages\/","url":"https:\/\/iamakulov.com\/notes\/npm-malicious-packages\/","name":"Malicious packages in npm. Here\u2019s what to do - Ivan Akulov\u2019s blog","isPartOf":{"@id":"https:\/\/iamakulov.com\/notes\/#website"},"datePublished":"2017-08-01T21:24:48+00:00","dateModified":"2017-08-18T14:37:51+00:00","author":{"@id":"https:\/\/iamakulov.com\/notes\/#\/schema\/person\/ebf7b61bf573e7be5fe438f50ebd9b81"},"breadcrumb":{"@id":"https:\/\/iamakulov.com\/notes\/npm-malicious-packages\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/iamakulov.com\/notes\/npm-malicious-packages\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/iamakulov.com\/notes\/npm-malicious-packages\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/iamakulov.com\/notes\/"},{"@type":"ListItem","position":2,"name":"Malicious packages in npm. Here\u2019s what to do"}]},{"@type":"WebSite","@id":"https:\/\/iamakulov.com\/notes\/#website","url":"https:\/\/iamakulov.com\/notes\/","name":"Ivan Akulov\u2019s blog","description":"Ivan Akulov writes about his front-end experience, React, webpack, and performance optimizations.","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/iamakulov.com\/notes\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/iamakulov.com\/notes\/#\/schema\/person\/ebf7b61bf573e7be5fe438f50ebd9b81","name":"Ivan Akulov","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/iamakulov.com\/notes\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/f68e4cd477cef1577c339e6f09736d3a?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/f68e4cd477cef1577c339e6f09736d3a?s=96&d=mm&r=g","caption":"Ivan Akulov"},"description":"I'm a software engineer specializing in web performance, JavaScript, and React. I\u2019m also a Google Developer Expert. I work at Framer.","sameAs":["http:\/\/iamakulov.com","https:\/\/x.com\/iamakulov"]}]}},"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/iamakulov.com\/notes\/wp-json\/wp\/v2\/posts\/456"}],"collection":[{"href":"https:\/\/iamakulov.com\/notes\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/iamakulov.com\/notes\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/iamakulov.com\/notes\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/iamakulov.com\/notes\/wp-json\/wp\/v2\/comments?post=456"}],"version-history":[{"count":26,"href":"https:\/\/iamakulov.com\/notes\/wp-json\/wp\/v2\/posts\/456\/revisions"}],"predecessor-version":[{"id":501,"href":"https:\/\/iamakulov.com\/notes\/wp-json\/wp\/v2\/posts\/456\/revisions\/501"}],"wp:attachment":[{"href":"https:\/\/iamakulov.com\/notes\/wp-json\/wp\/v2\/media?parent=456"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/iamakulov.com\/notes\/wp-json\/wp\/v2\/categories?post=456"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/iamakulov.com\/notes\/wp-json\/wp\/v2\/tags?post=456"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}