Deno run with --allow-read and --deny-read flags results in allowed
Description
Deno is a JavaScript, TypeScript, and WebAssembly runtime. Starting in version 1.41.3 and prior to versions 2.1.13, 2.2.13, and 2.3.2, deno run --allow-read --deny-read main.ts results in allowed, even though 'deny' should be stronger. The result is the same with all global unary permissions given as --allow-* --deny-*. This only affects a nonsensical combination of flags, so there shouldn't be a real impact on the userbase. Users may upgrade to version 2.1.13, 2.2.13, or 2.3.2 to receive a patch.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
denocrates.io | >= 1.41.3, < 2.1.13 | 2.1.13 |
denocrates.io | >= 2.2.0, < 2.2.13 | 2.2.13 |
denocrates.io | >= 2.3.0, < 2.3.2 | 2.3.2 |
deno_runtimecrates.io | >= 0.150.0, < 0.212.0 | 0.212.0 |
Affected products
1Patches
39d665572d3cdfix: handling of contradictory global permission flags (#29213)
1 file changed · +26 −0
runtime/permissions/lib.rs+26 −0 modified@@ -410,6 +410,8 @@ impl<TQuery: QueryDescriptor> UnaryPermission<TQuery> { pub fn is_allow_all(&self) -> bool { self.granted_global + && !self.flag_denied_global + && !self.prompt_denied_global && self.flag_denied_list.is_empty() && self.prompt_denied_list.is_empty() } @@ -4840,6 +4842,30 @@ mod tests { assert!(perms.write.check(&write_query, None).is_err()); } + #[test] + fn test_check_allow_global_deny_global() { + let parser = TestPermissionDescriptorParser; + let mut perms = Permissions::from_options( + &parser, + &PermissionsOptions { + allow_read: Some(vec![]), + deny_read: Some(vec![]), + allow_write: Some(vec![]), + deny_write: Some(vec![]), + ..Default::default() + }, + ) + .unwrap(); + + assert!(perms.read.check_all(None).is_err()); + let read_query = parser.parse_path_query("/foo").unwrap().into_read(); + assert!(perms.read.check(&read_query, None).is_err()); + + assert!(perms.write.check_all(None).is_err()); + let write_query = parser.parse_path_query("/foo").unwrap().into_write(); + assert!(perms.write.check(&write_query, None).is_err()); + } + #[test] fn test_net_fully_qualified_domain_name() { set_prompter(Box::new(TestPrompter));
ef315b56c26cfix: handling of contradictory global permission flags (#29213)
1 file changed · +26 −0
runtime/permissions/lib.rs+26 −0 modified@@ -410,6 +410,8 @@ impl<TQuery: QueryDescriptor> UnaryPermission<TQuery> { pub fn is_allow_all(&self) -> bool { self.granted_global + && !self.flag_denied_global + && !self.prompt_denied_global && self.flag_denied_list.is_empty() && self.prompt_denied_list.is_empty() } @@ -4844,6 +4846,30 @@ mod tests { assert!(perms.write.check(&write_query, None).is_err()); } + #[test] + fn test_check_allow_global_deny_global() { + let parser = TestPermissionDescriptorParser; + let mut perms = Permissions::from_options( + &parser, + &PermissionsOptions { + allow_read: Some(vec![]), + deny_read: Some(vec![]), + allow_write: Some(vec![]), + deny_write: Some(vec![]), + ..Default::default() + }, + ) + .unwrap(); + + assert!(perms.read.check_all(None).is_err()); + let read_query = parser.parse_path_query("/foo").unwrap().into_read(); + assert!(perms.read.check(&read_query, None).is_err()); + + assert!(perms.write.check_all(None).is_err()); + let write_query = parser.parse_path_query("/foo").unwrap().into_write(); + assert!(perms.write.check(&write_query, None).is_err()); + } + #[test] fn test_net_fully_qualified_domain_name() { set_prompter(Box::new(TestPrompter));
2f0fae9d9071fix: handling of contradictory global permission flags (#29213)
1 file changed · +26 −0
runtime/permissions/lib.rs+26 −0 modified@@ -410,6 +410,8 @@ impl<TQuery: QueryDescriptor> UnaryPermission<TQuery> { pub fn is_allow_all(&self) -> bool { self.granted_global + && !self.flag_denied_global + && !self.prompt_denied_global && self.flag_denied_list.is_empty() && self.prompt_denied_list.is_empty() } @@ -4792,6 +4794,30 @@ mod tests { assert!(perms.write.check(&write_query, None).is_err()); } + #[test] + fn test_check_allow_global_deny_global() { + let parser = TestPermissionDescriptorParser; + let mut perms = Permissions::from_options( + &parser, + &PermissionsOptions { + allow_read: Some(vec![]), + deny_read: Some(vec![]), + allow_write: Some(vec![]), + deny_write: Some(vec![]), + ..Default::default() + }, + ) + .unwrap(); + + assert!(perms.read.check_all(None).is_err()); + let read_query = parser.parse_path_query("/foo").unwrap().into_read(); + assert!(perms.read.check(&read_query, None).is_err()); + + assert!(perms.write.check_all(None).is_err()); + let write_query = parser.parse_path_query("/foo").unwrap().into_write(); + assert!(perms.write.check(&write_query, None).is_err()); + } + #[test] fn test_net_fully_qualified_domain_name() { set_prompter(Box::new(TestPrompter));
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
8- github.com/advisories/GHSA-xqxc-x6p3-w683ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2025-48888ghsaADVISORY
- github.com/denoland/deno/commit/2f0fae9d9071dcaf0a689bc7097584b1b9ebc8dbghsax_refsource_MISCWEB
- github.com/denoland/deno/commit/9d665572d3cd39f997e29e6daac7c1102fc5c04fghsax_refsource_MISCWEB
- github.com/denoland/deno/commit/ef315b56c26c9ef5f25284a5100d2ed525a148cfghsax_refsource_MISCWEB
- github.com/denoland/deno/pull/22894ghsax_refsource_MISCWEB
- github.com/denoland/deno/pull/29213ghsax_refsource_MISCWEB
- github.com/denoland/deno/security/advisories/GHSA-xqxc-x6p3-w683ghsax_refsource_CONFIRMWEB
News mentions
0No linked articles in our index yet.