Skip to content

Instantly share code, notes, and snippets.

@bozdoz
Last active December 26, 2024 07:09
Show Gist options
  • Save bozdoz/9b8562b7e0b4b820fb7cd8bcf615ea7c to your computer and use it in GitHub Desktop.
Save bozdoz/9b8562b7e0b4b820fb7cd8bcf615ea7c to your computer and use it in GitHub Desktop.
Simple Example of how Deno could be calling NPM scripts

Important

Run with deno run --allow-run=deno main.ts (this allows us to run deno instead of node in scripts, but prevents any other nefarious scripts)

With NPM

npm run start

> [email protected] start
> node evil.js
npm run postinstall

> [email protected] postinstall
> rm -rf ./delete-me

With Deno

Note

Ideally this would be deno task ... but that just executes any command. In main.ts I've created a command runner for a given npm script

deno run --allow-run=deno main.ts
node evil.js
┏ ⚠️  Deno requests net access to "api.github.com:443".
┠─ Requested by `fetch()` API.
┠─ To see a stack trace for this prompt, set the DENO_TRACE_PERMISSIONS environmental variable.
┠─ Learn more at: https://docs.deno.com/go/--allow-net
┠─ Run again with --allow-net to bypass this prompt.
┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all net permissions) > 

rm -rf ./delete-me
┏ ⚠️  Deno requests run access to "rm".
┠─ Requested by `Deno.Command().spawn()` API.
┠─ To see a stack trace for this prompt, set the DENO_TRACE_PERMISSIONS environmental variable.
┠─ Learn more at: https://docs.deno.com/go/--allow-run
┠─ Run again with --allow-run to bypass this prompt.
┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all run permissions) > 
const main = async () => {
// an unexpected fetch appeared!
const resp = await fetch('https://api.github.com/repos/bozdoz/bozdoz.com');
console.log(await resp.json());
}
main();
import pkg from './package.json' with { type: "json" };
const runScript = async (script: keyof typeof pkg.scripts) => {
let [cmd, ...args] = pkg.scripts[script].split(' ');
console.log(cmd, ...args);
if (cmd === 'node') {
// swap with deno
cmd = 'deno';
}
const run = new Deno.Command(cmd, {
args,
});
const child = run.spawn();
console.log(await child.status);
};
await runScript('start');
await runScript('postinstall');
{
"name": "deno",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"start": "node evil.js",
"postinstall": "rm -rf ./delete-me"
},
"keywords": [],
"author": "",
"license": "ISC",
"description": ""
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment