Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(permissions): handle ipv6 addresses correctly #24397

Merged
merged 6 commits into from
Jul 5, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
fix(permissions): handle ipv6 addresses correctly
Also don't panic on invalid domain names and addresses.

Co-authored-by: Yazan AbdAl-Rahman <[email protected]>
  • Loading branch information
lucacasonato and yazan-abdalrahman committed Jul 3, 2024
commit ef760f54fb8451df9f588e5dc8c5d67ba8836205
8 changes: 4 additions & 4 deletions cli/args/flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8060,7 8060,7 @@ mod tests {
let r = flags_from_vec(svec![
"deno",
"run",
"--allow-net=deno.land,deno.land:80,::,127.0.0.1,[::1],1.2.3.4:5678,:5678,[::1]:8080",
"--allow-net=deno.land,deno.land:80,[::],127.0.0.1,[::1],1.2.3.4:5678,:5678,[::1]:8080",
"script.ts"
]);
assert_eq!(
Expand All @@ -8073,7 8073,7 @@ mod tests {
allow_net: Some(svec![
"deno.land",
"deno.land:80",
"::",
"[::]",
"127.0.0.1",
"[::1]",
"1.2.3.4:5678",
Expand All @@ -8095,7 8095,7 @@ mod tests {
let r = flags_from_vec(svec![
"deno",
"run",
"--deny-net=deno.land,deno.land:80,::,127.0.0.1,[::1],1.2.3.4:5678,:5678,[::1]:8080",
"--deny-net=deno.land,deno.land:80,[::],127.0.0.1,[::1],1.2.3.4:5678,:5678,[::1]:8080",
"script.ts"
]);
assert_eq!(
Expand All @@ -8108,7 8108,7 @@ mod tests {
deny_net: Some(svec![
"deno.land",
"deno.land:80",
"::",
"[::]",
"127.0.0.1",
"[::1]",
"1.2.3.4:5678",
Expand Down
49 changes: 34 additions & 15 deletions cli/args/flags_net.rs
Original file line number Diff line number Diff line change
@@ -1,6 1,7 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.

use deno_core::url::Url;
use deno_runtime::deno_permissions::NetDescriptor;
use std::net::IpAddr;
use std::str::FromStr;

Expand Down Expand Up @@ -42,21 43,17 @@ pub fn validator(host_and_port: &str) -> Result<String, String> {
/// `127.0.0.1:port` and `localhost:port`.
pub fn parse(paths: Vec<String>) -> clap::error::Result<Vec<String>> {
let mut out: Vec<String> = vec![];
for host_and_port in paths.iter() {
if Url::parse(&format!("internal://{host_and_port}")).is_ok()
|| host_and_port.parse::<IpAddr>().is_ok()
{
out.push(host_and_port.to_owned())
} else if let Ok(port) = host_and_port.parse::<BarePort>() {
for host_and_port in paths.into_iter() {
if let Ok(port) = host_and_port.parse::<BarePort>() {
// we got bare port, let's add default hosts
for host in ["0.0.0.0", "127.0.0.1", "localhost"].iter() {
out.push(format!("{}:{}", host, port.0));
}
} else {
return Err(clap::Error::raw(
clap::error::ErrorKind::InvalidValue,
format!("Bad host:port pair: {host_and_port}"),
));
host_and_port.parse::<NetDescriptor>().map_err(|e| {
clap::Error::raw(clap::error::ErrorKind::InvalidValue, format!("{e:?}"))
})?;
out.push(host_and_port)
}
}
Ok(out)
Expand Down Expand Up @@ -174,10 171,8 @@ mod tests {

#[test]
fn parse_net_args_ipv6() {
let entries =
svec!["::", "::1", "[::1]", "[::]:5678", "[::1]:5678", "::cafe"];
let expected =
svec!["::", "::1", "[::1]", "[::]:5678", "[::1]:5678", "::cafe"];
let entries = svec!["[::1]", "[::]:5678", "[::1]:5678"];
let expected = svec!["[::1]", "[::]:5678", "[::1]:5678"];
let actual = parse(entries).unwrap();
assert_eq!(actual, expected);
}
Expand All @@ -190,12 185,36 @@ mod tests {

#[test]
fn parse_net_args_ipv6_error2() {
let entries = svec!["0123:4567:890a:bcde:fg::"];
let entries = svec!["::1"];
assert!(parse(entries).is_err());
}

#[test]
fn parse_net_args_ipv6_error3() {
let entries = svec!["::"];
assert!(parse(entries).is_err());
}

#[test]
fn parse_net_args_ipv6_error4() {
let entries = svec!["::cafe"];
assert!(parse(entries).is_err());
}

#[test]
fn parse_net_args_ipv6_error5() {
let entries = svec!["1::1"];
assert!(parse(entries).is_err());
}

#[test]
fn parse_net_args_ipv6_error6() {
let entries = svec!["0123:4567:890a:bcde:fg::"];
assert!(parse(entries).is_err());
}

#[test]
fn parse_net_args_ipv6_error7() {
let entries = svec!["[::q]:8080"];
assert!(parse(entries).is_err());
}
Expand Down
18 changes: 3 additions & 15 deletions runtime/ops/permissions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 4,8 @@ use ::deno_permissions::parse_sys_kind;
use ::deno_permissions::PermissionState;
use ::deno_permissions::PermissionsContainer;
use deno_core::error::custom_error;
use deno_core::error::uri_error;
use deno_core::error::AnyError;
use deno_core::op2;
use deno_core::url;
use deno_core::OpState;
use serde::Deserialize;
use serde::Serialize;
Expand Down Expand Up @@ -65,7 63,7 @@ pub fn op_query_permission(
"net" => permissions.net.query(
match args.host.as_deref() {
None => None,
Some(h) => Some(parse_host(h)?),
Some(h) => Some(h.parse()?),
}
.as_ref(),
),
Expand Down Expand Up @@ -100,7 98,7 @@ pub fn op_revoke_permission(
"net" => permissions.net.revoke(
match args.host.as_deref() {
None => None,
Some(h) => Some(parse_host(h)?),
Some(h) => Some(h.parse()?),
}
.as_ref(),
),
Expand Down Expand Up @@ -135,7 133,7 @@ pub fn op_request_permission(
"net" => permissions.net.request(
match args.host.as_deref() {
None => None,
Some(h) => Some(parse_host(h)?),
Some(h) => Some(h.parse()?),
}
.as_ref(),
),
Expand All @@ -155,13 153,3 @@ pub fn op_request_permission(
};
Ok(PermissionStatus::from(perm))
}

fn parse_host(host_str: &str) -> Result<(String, Option<u16>), AnyError> {
let url = url::Url::parse(&format!("http://{host_str}/"))
.map_err(|_| uri_error("Invalid host"))?;
if url.path() != "/" {
return Err(uri_error("Invalid host"));
}
let hostname = url.host_str().unwrap();
Ok((hostname.to_string(), url.port()))
}
Loading
Loading