Skip to content

Instantly share code, notes, and snippets.

@FranciscoG
Last active April 8, 2023 16:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save FranciscoG/55278045f95b66f11b6d1451af219ecd to your computer and use it in GitHub Desktop.
Save FranciscoG/55278045f95b66f11b6d1451af219ecd to your computer and use it in GitHub Desktop.
A small Deno script that enforces some stricter security in your project

Place this script at the very top of your entry file so that you can enfore that you are always using an allow-list for each of the permission flags deno provides.

it will exit with error code 1 if:

  • you use --allow-all
  • if you use any flag without providing a list: --allow-write instead of --allow-write=./tmp
  • you use --allow-hrtime

hrtime - This one does not use a list but I've included it because Deno's documentation states that "High-resolution time can be used in timing attacks and fingerprinting".

This script was written for Deno's permissions as of version v1.32.3.

I originally posted this as a discussion topic here: denoland/deno#18576

This is what the error message would look like when running with --allow-all

ERROR: No opened ended permissions allowed.
You must use an allow list for the following permissions:
	--allow-env
	--allow-run
	--allow-net
	--allow-write
	--allow-read
	--allow-sys
	--allow-ffi
Restricted use of 'hrtime'. Please remove --allow-hrtime
// as of Deno v1.32.2
type PermissionNames = Parameters<typeof Deno.permissions.query>[0]['name']
// "run" | "read" | "write" | "net" | "env" | "sys" | "ffi" | "hrtime"
/**
* Checks to see if you are providing a list to those permissions that can take a list
* @returns an error string if there were any premissions being improperly used, undefined if everthing is ok
*/
async function checkPermissionsWithLists(): Promise<string | void> {
const permissions: PermissionNames[] = [
"env",
"run",
"net",
"write",
"read",
"sys",
"ffi",
];
const granted = [];
for (const permission of permissions) {
const { state } = await Deno.permissions.query({ name: permission });
// if you use a flag without an allow-list, state will show as 'granted'
// but if you do use an allow-list, state will show as 'prompt'
if (state === "granted") {
granted.push(permission);
}
}
if (granted.length > 0) {
const formatted = granted.map((p) => `\t--allow-${p}`).join("\n");
return `ERROR: No opened ended permissions allowed.\nYou must use an allow list for the following permissions:\n${formatted}`;
}
}
/**
* Checks to see if you are using --allow-hrtime
* @returns an error string if permission is being used, undefined if everthing is ok
*/
async function checkHrtime(): Promise<string | void> {
const { state } = await Deno.permissions.query({ name: "hrtime" });
if (state === "granted") {
return `Restricted use of 'hrtime'. Please remove --allow-hrtime`;
}
}
const errorMessages = await Promise.all([
checkPermissionsWithLists(),
checkHrtime(),
]);
let hasError = false;
errorMessages.forEach((msg) => {
if (typeof msg === "string") {
hasError = true;
console.error(msg);
}
});
if (hasError) {
Deno.exit(1);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment