{"slug": "how-deno-protects-against-npm-exploits", "title": "How Deno protects against npm exploits", "summary": "The article explains that Node.js and npm have a permissive default security model, allowing any installed package code, including malicious scripts, full system access. In contrast, Deno is designed with security as a default, running code in a sandbox with no file, network, or environment access unless explicitly granted via permission flags. Deno also offers features like the `--allow-scripts` flag to control postinstall script execution and permission auditing logs to help mitigate npm security exploits.", "body_md": "How Deno protects against npm exploits\nTwo major security breaches happened in npm this month: the\n@ctrl/tinycolor\npackage\n(along with 40+ packages across multiple maintainers and 2+ million weekly\ndownloads) was compromised likely via a hijacked postinstall script, and\ndebug\n, chalk\n, among 18 other packages\ntotaling billions of weekly downloads via a phishing email attack. These\nsecurity exploits have happened and will continue to happen to the world’s\nlargest open source registry due to Node/npm’s reckless approach to dependency\nmanagement (your Node app and npm have unfettered access to everything — your\nfilesystem, the internet, environment variables, etc. — when you install them).\nHowever, there is hope. You can use Deno to run your Node apps (without any code change) to help mitigate these security vulnerabilities.\nNode and npm’s unfettered access\nNode.js and npm’s default security model is very permissive. When you run\nnpm install\nor import a package in Node, any code in that package (even deeply\nnested depdencies) runs with full access to your system by default. This\nincludes install scripts like postinstall\nhooks, which npm executes\nautomatically. Someone even showed that running npm install\non a compromised\npackage\ncould execute an npx\ncommand that exfiltrates your entire bash history to a remote server\nwithout any special privileges or consent needed.\nThis “run everything with no limits” approach means a single malicious\ndependency can, for examlpe, scan your filesystem for API keys and upload them\nto a remote server, as what happened in the tinycolor\nattack.\nSecure by default\nDeno, designed explicitly with security in mind, approaches permissions opposite of Node. By default, Deno executes code in a sandbox with no OS access. Unless you explicitly grant permission, a Deno program cannot:\n- read or write files to your file system\n- open network connections or send/receive data over the network\n- access environment variables\n- spawn subprocesses to run other programs\nThat means if you run or install some third-party code with Deno, it will block access to reading or writing to your local system, environment variables, or your network. Deno won’t let code escalate privileges at runtime either: the developer must deliberately opt-in. With Deno, you get a powerful safety net that lets you run untrusted or new code with much less fear of it doing harm.\nGranting explicit access to your Deno program is simple via permission flags:\nYou can even get more granular over the control you have over Deno’s access. For instance, you can give partial access to the file system:\ndeno --allow-read=/path/to/specific/file.txt your_script.ts\nOr even allow access to only a single network endpoint:\ndeno --allow-net=api.stripe.com app.ts\nAnd if juggling permission flags clutters your command line, you can define\nmultiple\npermission sets in your deno.json\nthat you can invoke with --permission-set\n(or -P\n). This is great if your\npermissions vary among running your app, running tests,\ndeno compile\n, and so\non.\nWe’re continuing to improve on our security features. For instance, we will soon ship a filter to only install npm packages of a certain age.\n--allow-scripts\nOpt into postinstall scripts with Deno can also be used as a package manager, with\ndeno add\n,\ndeno install\n,\ndeno outdated\nand\ndeno remove\n. However,\nunlike npm, Deno doesn’t automatically run postinstall scripts.\nTo permit specific packages to run their postinstall scripts, use the\n--allow-scripts\nflag:\ndeno install --allow-scripts=npm:sqlite3\nThis command will allow npm:sqlite3\nto run its postinstall script, while\nblocking others. This setup gives you more control over which scripts, if any,\ncan execute, protecting your system for potentially harmful or untrusted code.\nSecurity through transparency\nDeno can log every permission\na program uses for auditing. By setting the environment variable\nDENO_AUDIT_PERMISSIONS\nto a file path, you get a detailed log of all\npermission checks and uses:\n{\n\"v\": 1,\n\"datetime\": \"2025-09-05T12:12:35Z\",\n\"permission\": \"env\",\n\"value\": \"FOO\"\n}\n{\n\"v\": 1,\n\"datetime\": \"2025-09-05T12:14:18Z\",\n\"permission\": \"read\",\n\"value\": \"data.csv\"\n}\n{\n\"v\": 1,\n\"datetime\": \"2025-09-05T12:14:26Z\",\n\"permission\": \"write\",\n\"value\": \"log.txt\"\n}\nThis means you could run a new module with auditing on and see exactly what it\ntried to do (a great way to catch unexpected behaviors). For even more\nobservability, you can enable environment variable\nDENO_TRACE_PERMISSIONS=1\nto include stack traces for where in the code the access was attempted.\nA standard library for JavaScript\nAnother main criticism of npm is the proliferation of micro-libraries, which creates sprawling yet brittle dependency trees where a single library can compromise the entire project (see left-pad incident). You can reduce the surface area of vulnerability by minimizing dependencies: writing your own function or using a standard library.\nDeno has been developing and maintaining the Standard Library for the past five years, which includes over 40 packages meant covering a wide variety of use cases, such as data manipulation, javascript functionalities, web-related logic, and general utilities.", "url": "https://wpnews.pro/news/how-deno-protects-against-npm-exploits", "canonical_source": "https://deno.com/blog/deno-protects-npm-exploits", "published_at": "2025-09-30 12:00:00+00:00", "updated_at": "2026-05-22 12:23:53.002391+00:00", "lang": "en", "topics": ["cybersecurity", "open-source", "developer-tools"], "entities": ["Deno", "npm", "Node", "@ctrl/tinycolor", "debug", "chalk"], "alternates": {"html": "https://wpnews.pro/news/how-deno-protects-against-npm-exploits", "markdown": "https://wpnews.pro/news/how-deno-protects-against-npm-exploits.md", "text": "https://wpnews.pro/news/how-deno-protects-against-npm-exploits.txt", "jsonld": "https://wpnews.pro/news/how-deno-protects-against-npm-exploits.jsonld"}}