Skip to content

fix(auth): replace exec() with execFile/spawn to prevent shell injection (#79)#98

Open
draix wants to merge 1 commit intoMiniMax-AI:mainfrom
draix:fix/79-shell-injection-oauth
Open

fix(auth): replace exec() with execFile/spawn to prevent shell injection (#79)#98
draix wants to merge 1 commit intoMiniMax-AI:mainfrom
draix:fix/79-shell-injection-oauth

Conversation

@draix
Copy link
Copy Markdown

@draix draix commented Apr 14, 2026

Summary

Fixes the shell injection vulnerability in src/auth/oauth.ts reported in #79.

Root cause

exec() passes its argument to the system shell (/bin/sh on Unix, cmd.exe on Windows). The OAuth authorization URL was passed directly to exec():

exec(`${openCmd} "${authUrl}"`);

A crafted authUrl containing shell metacharacters (e.g. from a malicious or tampered authorization server) could execute arbitrary commands on the user's machine. Example attack vector:

https://evil.com/auth?redirect_uri=..."; rm -rf ~/; echo "

Fix

Replace exec() with execFile() / spawn(), which bypass the shell entirely and pass arguments as an array:

Platform Before After
macOS exec('open "' + url + '"') execFile('open', [url])
Linux exec('xdg-open "' + url + '"') execFile('xdg-open', [url])
Windows exec('start "' + url + '"') spawn('cmd.exe', ['/c', 'start', '', url], { shell: false })

Windows requires cmd.exe because start is a shell built-in, but the URL is passed as a separate argument — never interpolated into a shell string.

Part of #79

This PR addresses the Critical #1 item (shell injection). The other items (#2#6) require larger changes (keychain integration, file locking, etc.) and are best addressed in separate PRs.

…ion (MiniMax-AI#79)

src/auth/oauth.ts passed the OAuth authorization URL directly to exec():

  exec(`${openCmd} "${authUrl}"`)

exec() passes the string to a shell (/bin/sh on Unix, cmd.exe on Windows).
A crafted authorization URL containing shell metacharacters (e.g. from a
malicious or tampered authorization server redirect) could execute arbitrary
commands on the user's machine.

Fix: replace exec() with execFile() on macOS/Linux (which bypasses the shell
entirely) and spawn() on Windows (since 'start' is a shell built-in that
requires cmd.exe, spawned with shell:false and an explicit empty title arg
to prevent argument injection).

Closes part of MiniMax-AI#79
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants