summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuca Casonato <hello@lcas.dev>2022-03-20 22:46:39 +0100
committerGitHub <noreply@github.com>2022-03-20 22:46:39 +0100
commitdaa7c6d32ab5a4029f8084e174d621f5562256be (patch)
tree27ed9921f4e6b1c2cb662bc7c1d51e73c9f9a50d
parentd0a7305676b1df0819d7f9ecd900110526da9109 (diff)
fix: actually don't inherit runtime permissions (#14024)
-rw-r--r--cli/tests/testdata/bench/allow_all.ts16
-rw-r--r--cli/tests/testdata/test/allow_all.ts16
-rw-r--r--cli/tests/testdata/workers/permission_echo.js19
-rw-r--r--cli/tests/testdata/workers/test.ts62
-rw-r--r--cli/tests/unit/http_test.ts20
-rw-r--r--cli/tests/unit/net_test.ts2
-rw-r--r--cli/tests/unit/timers_test.ts21
-rw-r--r--cli/tests/unit/tty_color_test.ts21
-rw-r--r--runtime/permissions.rs98
9 files changed, 192 insertions, 83 deletions
diff --git a/cli/tests/testdata/bench/allow_all.ts b/cli/tests/testdata/bench/allow_all.ts
index 110e4621f..d7dde3a85 100644
--- a/cli/tests/testdata/bench/allow_all.ts
+++ b/cli/tests/testdata/bench/allow_all.ts
@@ -17,8 +17,10 @@ for (const name of permissions) {
[name]: false,
},
async fn() {
- const status = await Deno.permissions.query({ name });
- assertEquals(status.state, "prompt");
+ for await (const n of permissions) {
+ const status = await Deno.permissions.query({ name: n });
+ assertEquals(status.state, "prompt");
+ }
},
});
@@ -28,8 +30,14 @@ for (const name of permissions) {
[name]: true,
},
async fn() {
- const status = await Deno.permissions.query({ name });
- assertEquals(status.state, "granted");
+ for await (const n of permissions) {
+ const status = await Deno.permissions.query({ name: n });
+ if (n === name) {
+ assertEquals(status.state, "granted");
+ } else {
+ assertEquals(status.state, "prompt");
+ }
+ }
},
});
}
diff --git a/cli/tests/testdata/test/allow_all.ts b/cli/tests/testdata/test/allow_all.ts
index e70ac46b0..c7a238130 100644
--- a/cli/tests/testdata/test/allow_all.ts
+++ b/cli/tests/testdata/test/allow_all.ts
@@ -17,8 +17,10 @@ for (const name of permissions) {
[name]: false,
},
async fn() {
- const status = await Deno.permissions.query({ name });
- assertEquals(status.state, "prompt");
+ for await (const n of permissions) {
+ const status = await Deno.permissions.query({ name: n });
+ assertEquals(status.state, "prompt");
+ }
},
});
@@ -28,8 +30,14 @@ for (const name of permissions) {
[name]: true,
},
async fn() {
- const status = await Deno.permissions.query({ name });
- assertEquals(status.state, "granted");
+ for await (const n of permissions) {
+ const status = await Deno.permissions.query({ name: n });
+ if (n === name) {
+ assertEquals(status.state, "granted");
+ } else {
+ assertEquals(status.state, "prompt");
+ }
+ }
},
});
}
diff --git a/cli/tests/testdata/workers/permission_echo.js b/cli/tests/testdata/workers/permission_echo.js
new file mode 100644
index 000000000..f492a25f2
--- /dev/null
+++ b/cli/tests/testdata/workers/permission_echo.js
@@ -0,0 +1,19 @@
+self.onmessage = async () => {
+ const env = await Deno.permissions.query({ name: "env" });
+ const ffi = await Deno.permissions.query({ name: "ffi" });
+ const hrtime = await Deno.permissions.query({ name: "hrtime" });
+ const net = await Deno.permissions.query({ name: "net" });
+ const read = await Deno.permissions.query({ name: "read" });
+ const run = await Deno.permissions.query({ name: "run" });
+ const write = await Deno.permissions.query({ name: "write" });
+ self.postMessage({
+ env: env.state,
+ ffi: ffi.state,
+ hrtime: hrtime.state,
+ net: net.state,
+ read: read.state,
+ run: run.state,
+ write: write.state,
+ });
+ self.close();
+};
diff --git a/cli/tests/testdata/workers/test.ts b/cli/tests/testdata/workers/test.ts
index b9204adee..d75ca499b 100644
--- a/cli/tests/testdata/workers/test.ts
+++ b/cli/tests/testdata/workers/test.ts
@@ -584,6 +584,68 @@ Deno.test("Worker with disabled permissions", async function () {
worker.terminate();
});
+Deno.test("Worker permissions are not inherited with empty permission object", async function () {
+ const worker = new Worker(
+ new URL("./permission_echo.js", import.meta.url).href,
+ {
+ type: "module",
+ deno: {
+ namespace: true,
+ permissions: {},
+ },
+ },
+ );
+
+ const promise = deferred();
+ worker.onmessage = (e) => {
+ promise.resolve(e.data);
+ };
+
+ worker.postMessage(null);
+ assertEquals(await promise, {
+ env: "prompt",
+ hrtime: "prompt",
+ net: "prompt",
+ ffi: "prompt",
+ read: "prompt",
+ run: "prompt",
+ write: "prompt",
+ });
+ worker.terminate();
+});
+
+Deno.test("Worker permissions are not inherited with single specified permission", async function () {
+ const worker = new Worker(
+ new URL("./permission_echo.js", import.meta.url).href,
+ {
+ type: "module",
+ deno: {
+ namespace: true,
+ permissions: {
+ net: true,
+ },
+ },
+ },
+ );
+
+ const promise = deferred();
+ worker.onmessage = (e) => {
+ promise.resolve(e.data);
+ };
+
+ worker.postMessage(null);
+ assertEquals(await promise, {
+ env: "prompt",
+ hrtime: "prompt",
+ net: "granted",
+ ffi: "prompt",
+ read: "prompt",
+ run: "prompt",
+ write: "prompt",
+ });
+ worker.terminate();
+});
+
Deno.test("Worker with invalid permission arg", function () {
assertThrows(
() =>
diff --git a/cli/tests/unit/http_test.ts b/cli/tests/unit/http_test.ts
index e8976c06d..83fa6116c 100644
--- a/cli/tests/unit/http_test.ts
+++ b/cli/tests/unit/http_test.ts
@@ -1180,7 +1180,7 @@ const decoder = new TextDecoder();
Deno.test({
name: "http server compresses body",
- permissions: { net: true },
+ permissions: { net: true, run: true },
async fn() {
const hostname = "localhost";
const port = 4501;
@@ -1231,7 +1231,7 @@ Deno.test({
Deno.test({
name: "http server doesn't compress small body",
- permissions: { net: true },
+ permissions: { net: true, run: true },
async fn() {
const hostname = "localhost";
const port = 4501;
@@ -1282,7 +1282,7 @@ Deno.test({
Deno.test({
name: "http server respects accept-encoding weights",
- permissions: { net: true },
+ permissions: { net: true, run: true },
async fn() {
const hostname = "localhost";
const port = 4501;
@@ -1336,7 +1336,7 @@ Deno.test({
Deno.test({
name: "http server augments vary header",
- permissions: { net: true },
+ permissions: { net: true, run: true },
async fn() {
const hostname = "localhost";
const port = 4501;
@@ -1387,7 +1387,7 @@ Deno.test({
Deno.test({
name: "http server weakens etag header",
- permissions: { net: true },
+ permissions: { net: true, run: true },
async fn() {
const hostname = "localhost";
const port = 4501;
@@ -1444,7 +1444,7 @@ Deno.test({
Deno.test({
name: "http server passes through weak etag header",
- permissions: { net: true },
+ permissions: { net: true, run: true },
async fn() {
const hostname = "localhost";
const port = 4501;
@@ -1501,7 +1501,7 @@ Deno.test({
Deno.test({
name: "http server doesn't compress body when no-transform is set",
- permissions: { net: true },
+ permissions: { net: true, run: true },
async fn() {
const hostname = "localhost";
const port = 4501;
@@ -1555,7 +1555,7 @@ Deno.test({
Deno.test({
name: "http server doesn't compress body when content-range is set",
- permissions: { net: true },
+ permissions: { net: true, run: true },
async fn() {
const hostname = "localhost";
const port = 4501;
@@ -1609,7 +1609,7 @@ Deno.test({
Deno.test({
name: "http server doesn't compress streamed bodies",
- permissions: { net: true },
+ permissions: { net: true, run: true },
async fn() {
const hostname = "localhost";
const port = 4501;
@@ -1675,7 +1675,7 @@ Deno.test({
Deno.test({
name: "http server updates content-length header if compression is applied",
- permissions: { net: true },
+ permissions: { net: true, run: true },
async fn() {
const hostname = "localhost";
const port = 4501;
diff --git a/cli/tests/unit/net_test.ts b/cli/tests/unit/net_test.ts
index 29e823b10..6769f6301 100644
--- a/cli/tests/unit/net_test.ts
+++ b/cli/tests/unit/net_test.ts
@@ -380,7 +380,7 @@ Deno.test(
);
Deno.test(
- { permissions: { net: true } },
+ { permissions: { net: true }, ignore: true },
async function netUdpSendReceiveBroadcast() {
// Must bind sender to an address that can send to the broadcast address on MacOS.
// Macos will give us error 49 when sending the broadcast packet if we omit hostname here.
diff --git a/cli/tests/unit/timers_test.ts b/cli/tests/unit/timers_test.ts
index 5b9e1fa48..ef7dc9eef 100644
--- a/cli/tests/unit/timers_test.ts
+++ b/cli/tests/unit/timers_test.ts
@@ -579,7 +579,7 @@ Deno.test(
Deno.test({
name: "unrefTimer",
- permissions: { run: true },
+ permissions: { run: true, read: true },
fn: async () => {
const [statusCode, output] = await execCode(`
const timer = setTimeout(() => console.log("1"));
@@ -592,7 +592,7 @@ Deno.test({
Deno.test({
name: "unrefTimer - mix ref and unref 1",
- permissions: { run: true },
+ permissions: { run: true, read: true },
fn: async () => {
const [statusCode, output] = await execCode(`
const timer1 = setTimeout(() => console.log("1"), 200);
@@ -607,7 +607,7 @@ Deno.test({
Deno.test({
name: "unrefTimer - mix ref and unref 2",
- permissions: { run: true },
+ permissions: { run: true, read: true },
fn: async () => {
const [statusCode, output] = await execCode(`
const timer1 = setTimeout(() => console.log("1"), 200);
@@ -623,7 +623,7 @@ Deno.test({
Deno.test({
name: "unrefTimer - unref interval",
- permissions: { run: true },
+ permissions: { run: true, read: true },
fn: async () => {
const [statusCode, output] = await execCode(`
let i = 0;
@@ -642,7 +642,7 @@ Deno.test({
Deno.test({
name: "unrefTimer - unref then ref 1",
- permissions: { run: true },
+ permissions: { run: true, read: true },
fn: async () => {
const [statusCode, output] = await execCode(`
const timer1 = setTimeout(() => console.log("1"), 10);
@@ -656,7 +656,7 @@ Deno.test({
Deno.test({
name: "unrefTimer - unref then ref",
- permissions: { run: true },
+ permissions: { run: true, read: true },
fn: async () => {
const [statusCode, output] = await execCode(`
const timer1 = setTimeout(() => {
@@ -673,7 +673,6 @@ Deno.test({
Deno.test({
name: "unrefTimer - invalid calls do nothing",
- permissions: { run: true },
fn: () => {
Deno.unrefTimer(NaN);
Deno.refTimer(NaN);
@@ -682,7 +681,7 @@ Deno.test({
Deno.test({
name: "AbortSignal.timeout() with no listeners",
- permissions: { run: true },
+ permissions: { run: true, read: true },
fn: async () => {
const [statusCode, output] = await execCode(`
const signal = AbortSignal.timeout(2000);
@@ -699,7 +698,7 @@ Deno.test({
Deno.test({
name: "AbortSignal.timeout() with listeners",
- permissions: { run: true },
+ permissions: { run: true, read: true },
fn: async () => {
const [statusCode, output] = await execCode(`
const signal = AbortSignal.timeout(1000);
@@ -712,7 +711,7 @@ Deno.test({
Deno.test({
name: "AbortSignal.timeout() with removed listeners",
- permissions: { run: true },
+ permissions: { run: true, read: true },
fn: async () => {
const [statusCode, output] = await execCode(`
const signal = AbortSignal.timeout(2000);
@@ -736,7 +735,7 @@ Deno.test({
Deno.test({
name: "AbortSignal.timeout() with listener for a non-abort event",
- permissions: { run: true },
+ permissions: { run: true, read: true },
fn: async () => {
const [statusCode, output] = await execCode(`
const signal = AbortSignal.timeout(2000);
diff --git a/cli/tests/unit/tty_color_test.ts b/cli/tests/unit/tty_color_test.ts
index d64c278bf..c10c9ff1e 100644
--- a/cli/tests/unit/tty_color_test.ts
+++ b/cli/tests/unit/tty_color_test.ts
@@ -3,12 +3,15 @@ import { assertEquals } from "./test_util.ts";
// Note tests for Deno.setRaw is in integration tests.
-Deno.test({ permissions: { run: true } }, async function noColorIfNotTty() {
- const p = Deno.run({
- cmd: [Deno.execPath(), "eval", "console.log(1)"],
- stdout: "piped",
- });
- const output = new TextDecoder().decode(await p.output());
- assertEquals(output, "1\n");
- p.close();
-});
+Deno.test(
+ { permissions: { run: true, read: true } },
+ async function noColorIfNotTty() {
+ const p = Deno.run({
+ cmd: [Deno.execPath(), "eval", "console.log(1)"],
+ stdout: "piped",
+ });
+ const output = new TextDecoder().decode(await p.output());
+ assertEquals(output, "1\n");
+ p.close();
+ },
+);
diff --git a/runtime/permissions.rs b/runtime/permissions.rs
index 707c9647e..095e67467 100644
--- a/runtime/permissions.rs
+++ b/runtime/permissions.rs
@@ -1432,12 +1432,6 @@ pub enum ChildUnitPermissionArg {
NotGranted,
}
-impl Default for ChildUnitPermissionArg {
- fn default() -> Self {
- ChildUnitPermissionArg::Inherit
- }
-}
-
impl<'de> Deserialize<'de> for ChildUnitPermissionArg {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
@@ -1491,12 +1485,6 @@ pub enum ChildUnaryPermissionArg {
GrantedList(Vec<String>),
}
-impl Default for ChildUnaryPermissionArg {
- fn default() -> Self {
- ChildUnaryPermissionArg::Inherit
- }
-}
-
impl<'de> Deserialize<'de> for ChildUnaryPermissionArg {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
@@ -1557,7 +1545,7 @@ impl<'de> Deserialize<'de> for ChildUnaryPermissionArg {
}
/// Directly deserializable from JS worker and test permission options.
-#[derive(Debug, Default, PartialEq)]
+#[derive(Debug, PartialEq)]
pub struct ChildPermissionsArg {
env: ChildUnaryPermissionArg,
hrtime: ChildUnitPermissionArg,
@@ -1568,6 +1556,32 @@ pub struct ChildPermissionsArg {
write: ChildUnaryPermissionArg,
}
+impl ChildPermissionsArg {
+ pub fn inherit() -> Self {
+ ChildPermissionsArg {
+ env: ChildUnaryPermissionArg::Inherit,
+ hrtime: ChildUnitPermissionArg::Inherit,
+ net: ChildUnaryPermissionArg::Inherit,
+ ffi: ChildUnaryPermissionArg::Inherit,
+ read: ChildUnaryPermissionArg::Inherit,
+ run: ChildUnaryPermissionArg::Inherit,
+ write: ChildUnaryPermissionArg::Inherit,
+ }
+ }
+
+ pub fn none() -> Self {
+ ChildPermissionsArg {
+ env: ChildUnaryPermissionArg::NotGranted,
+ hrtime: ChildUnitPermissionArg::NotGranted,
+ net: ChildUnaryPermissionArg::NotGranted,
+ ffi: ChildUnaryPermissionArg::NotGranted,
+ read: ChildUnaryPermissionArg::NotGranted,
+ run: ChildUnaryPermissionArg::NotGranted,
+ write: ChildUnaryPermissionArg::NotGranted,
+ }
+ }
+}
+
impl<'de> Deserialize<'de> for ChildPermissionsArg {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
@@ -1585,7 +1599,7 @@ impl<'de> Deserialize<'de> for ChildPermissionsArg {
where
E: de::Error,
{
- Ok(ChildPermissionsArg::default())
+ Ok(ChildPermissionsArg::inherit())
}
fn visit_str<E>(self, v: &str) -> Result<ChildPermissionsArg, E>
@@ -1593,17 +1607,9 @@ impl<'de> Deserialize<'de> for ChildPermissionsArg {
E: de::Error,
{
if v == "inherit" {
- Ok(ChildPermissionsArg::default())
+ Ok(ChildPermissionsArg::inherit())
} else if v == "none" {
- Ok(ChildPermissionsArg {
- env: ChildUnaryPermissionArg::NotGranted,
- hrtime: ChildUnitPermissionArg::NotGranted,
- net: ChildUnaryPermissionArg::NotGranted,
- ffi: ChildUnaryPermissionArg::NotGranted,
- read: ChildUnaryPermissionArg::NotGranted,
- run: ChildUnaryPermissionArg::NotGranted,
- write: ChildUnaryPermissionArg::NotGranted,
- })
+ Ok(ChildPermissionsArg::none())
} else {
Err(de::Error::invalid_value(de::Unexpected::Str(v), &self))
}
@@ -1613,7 +1619,7 @@ impl<'de> Deserialize<'de> for ChildPermissionsArg {
where
V: de::MapAccess<'de>,
{
- let mut child_permissions_arg = ChildPermissionsArg::default();
+ let mut child_permissions_arg = ChildPermissionsArg::none();
while let Some((key, value)) =
v.next_entry::<String, serde_json::Value>()?
{
@@ -2647,7 +2653,7 @@ mod tests {
#[test]
fn test_deserialize_child_permissions_arg() {
assert_eq!(
- ChildPermissionsArg::default(),
+ ChildPermissionsArg::inherit(),
ChildPermissionsArg {
env: ChildUnaryPermissionArg::Inherit,
hrtime: ChildUnitPermissionArg::Inherit,
@@ -2659,11 +2665,7 @@ mod tests {
}
);
assert_eq!(
- serde_json::from_value::<ChildPermissionsArg>(json!("inherit")).unwrap(),
- ChildPermissionsArg::default()
- );
- assert_eq!(
- serde_json::from_value::<ChildPermissionsArg>(json!("none")).unwrap(),
+ ChildPermissionsArg::none(),
ChildPermissionsArg {
env: ChildUnaryPermissionArg::NotGranted,
hrtime: ChildUnitPermissionArg::NotGranted,
@@ -2675,8 +2677,16 @@ mod tests {
}
);
assert_eq!(
+ serde_json::from_value::<ChildPermissionsArg>(json!("inherit")).unwrap(),
+ ChildPermissionsArg::inherit()
+ );
+ assert_eq!(
+ serde_json::from_value::<ChildPermissionsArg>(json!("none")).unwrap(),
+ ChildPermissionsArg::none()
+ );
+ assert_eq!(
serde_json::from_value::<ChildPermissionsArg>(json!({})).unwrap(),
- ChildPermissionsArg::default()
+ ChildPermissionsArg::none()
);
assert_eq!(
serde_json::from_value::<ChildPermissionsArg>(json!({
@@ -2685,7 +2695,7 @@ mod tests {
.unwrap(),
ChildPermissionsArg {
env: ChildUnaryPermissionArg::GrantedList(svec!["foo", "bar"]),
- ..Default::default()
+ ..ChildPermissionsArg::none()
}
);
assert_eq!(
@@ -2695,7 +2705,7 @@ mod tests {
.unwrap(),
ChildPermissionsArg {
hrtime: ChildUnitPermissionArg::Granted,
- ..Default::default()
+ ..ChildPermissionsArg::none()
}
);
assert_eq!(
@@ -2705,7 +2715,7 @@ mod tests {
.unwrap(),
ChildPermissionsArg {
hrtime: ChildUnitPermissionArg::NotGranted,
- ..Default::default()
+ ..ChildPermissionsArg::none()
}
);
assert_eq!(
@@ -2725,7 +2735,7 @@ mod tests {
read: ChildUnaryPermissionArg::Granted,
run: ChildUnaryPermissionArg::Granted,
write: ChildUnaryPermissionArg::Granted,
- ..Default::default()
+ ..ChildPermissionsArg::none()
}
);
assert_eq!(
@@ -2745,7 +2755,7 @@ mod tests {
read: ChildUnaryPermissionArg::NotGranted,
run: ChildUnaryPermissionArg::NotGranted,
write: ChildUnaryPermissionArg::NotGranted,
- ..Default::default()
+ ..ChildPermissionsArg::none()
}
);
assert_eq!(
@@ -2778,7 +2788,7 @@ mod tests {
"foo",
"file:///bar/baz"
]),
- ..Default::default()
+ ..ChildPermissionsArg::none()
}
);
}
@@ -2799,7 +2809,7 @@ mod tests {
hrtime: ChildUnitPermissionArg::NotGranted,
net: ChildUnaryPermissionArg::GrantedList(svec!["foo"]),
ffi: ChildUnaryPermissionArg::NotGranted,
- ..Default::default()
+ ..ChildPermissionsArg::none()
}
)
.unwrap(),
@@ -2813,7 +2823,7 @@ mod tests {
&mut main_perms.clone(),
ChildPermissionsArg {
net: ChildUnaryPermissionArg::Granted,
- ..Default::default()
+ ..ChildPermissionsArg::none()
}
)
.is_err());
@@ -2821,7 +2831,7 @@ mod tests {
&mut main_perms.clone(),
ChildPermissionsArg {
net: ChildUnaryPermissionArg::GrantedList(svec!["foo", "bar", "baz"]),
- ..Default::default()
+ ..ChildPermissionsArg::none()
}
)
.is_err());
@@ -2829,7 +2839,7 @@ mod tests {
&mut main_perms,
ChildPermissionsArg {
ffi: ChildUnaryPermissionArg::GrantedList(svec!["foo"]),
- ..Default::default()
+ ..ChildPermissionsArg::none()
}
)
.is_err());
@@ -2848,7 +2858,7 @@ mod tests {
ChildPermissionsArg {
read: ChildUnaryPermissionArg::Granted,
run: ChildUnaryPermissionArg::GrantedList(svec!["foo", "bar"]),
- ..Default::default()
+ ..ChildPermissionsArg::none()
},
)
.unwrap();
@@ -2866,7 +2876,7 @@ mod tests {
assert!(main_perms.write.check(&PathBuf::from("foo")).is_err());
let worker_perms = create_child_permissions(
&mut main_perms.clone(),
- ChildPermissionsArg::default(),
+ ChildPermissionsArg::none(),
)
.unwrap();
assert_eq!(worker_perms.write.denied_list, main_perms.write.denied_list);