Harden command execution in init wizard beyond string-based validation
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 5/5
- Tempo stimato
- Più di una settimana
- Idoneità per principianti
- 25/100
- Tipo di issue
- Funzionalità
- Chiarezza
- Da chiarire
- Stato di attività
- Ferma
- Stack tecnologico
- node.js, shell, typescript
- Ambito
- cli, operating-systems, security
Direzione di ricerca
Leggi cli/src/lib/init/local-ops.ts, iniziando da validateCommand() e runSingleCommand(), per comprendere la validazione esistente, l’uso della shell, il timeout e i limiti di output. Confronta le opzioni di sandboxing per Linux e macOS elencate nell’issue e determina quali percorsi dei comandi richiedono una gestione specifica del sistema operativo. Il lavoro è completato quando l’approccio di hardening scelto è implementato senza rimuovere i controlli esistenti e i relativi confini di sicurezza sono verificati.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Summary
cli/src/lib/init/local-ops.ts executes commands from the API server using shell: true. The current protections are string-based and could be bypassed by a sufficiently creative payload. Before sentry init exits experimental mode, we should add OS-level sandboxing.
Current protections
validateCommand() (line 140) — three layers of string validation:
- Shell metacharacter blocking — rejects commands containing
;,&&,||,|,`,$(,$, quotes, redirects (>,<), braces, globs, newlines, backslashes - Env var injection blocking — rejects commands where the first token contains
= - Dangerous executable blocklist — rejects 40+ executables (
rm,curl,sudo,ssh,bash,eval, etc.) but only checks the first token — e.g.npm exec -- rm -rf /would pass becausenpmis the primary executable
safePath() / path validation — prevents path traversal and symlink escapes outside the project root.
runSingleCommand() (line 426) — spawns via spawn(command, [], { shell: true, cwd, ... }) with a timeout and output truncation (64KB cap).
Gap
All protections are string-based pattern matching. The command still runs under shell: true with full user privileges. Potential bypasses:
- Package manager subcommands that execute arbitrary code (e.g.
npm exec, lifecycle scripts) - Unicode/encoding tricks that survive validation but are interpreted differently by the shell
- Future commands the server might send that don't match current patterns
Suggested hardening (Linux)
These are additive layers — the string validation remains as a fast first pass.
| Technique | How | Benefit |
|---|---|---|
Linux namespaces / unshare |
unshare --net --mount --pid wrapper |
Network isolation, mount isolation, PID isolation |
| Landlock LSM | Restrict filesystem access to project dir + node_modules + package manager cache | Prevents reads/writes outside expected paths even if shell escapes |
bubblewrap (bwrap) |
Lightweight sandbox with readonly / bind-mount, writable project dir only |
Strong filesystem + namespace isolation in one tool |
| Drop to restricted user | runuser / setuid to a no-login user for spawned commands |
Limits damage from any escape |
| Read-only filesystem mounts | Bind-mount / as read-only, whitelist project dir as writable |
Commands can't modify system files |
| Network namespace isolation | Empty network namespace for commands that don't need network (e.g. codemods) | Prevents data exfiltration |
--shell=false where possible |
For simple commands like npx @sentry/wizard, split into [executable, ...args] and avoid shell entirely |
Eliminates shell injection surface |
macOS considerations
macOS lacks namespaces/Landlock. Options are more limited:
sandbox-exec(deprecated but functional) with a restrictive profile- Avoid
shell: truewhere possible by splitting commands into argv arrays
Priority
Low — the current string validation is a reasonable defense for an experimental feature where commands originate from our own API server. This becomes more important if/when the command surface expands or the feature exits experimental.
- Lingua principale
- TypeScript
- Stelle
- 121
- Fork
- 14
- Merge medio
- 23h 54m
- PR unite (30g)
- 103
Guida per i contributori
Nessuna guida per i contributori indicizzata per questo repository
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di getsentry/cli
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
-
Difficoltà 3/5 1-2 giorni Idoneità per principianti 68/100
-
Difficoltà 3/5 1-2 giorni Idoneità per principianti 65/100
-
bug jared
-
jared
Difficoltà 4/5 3-5 giorni Idoneità per principianti 52/100
Tutte le issue di getsentry/cli
Issue simili
-
VerificationGate: ATTRIBUTION quote guard never matches a normal quotation (\b around the quote) Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
danielmiessler/LifeOS#2234 ·
-
T: Bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 65/100
-
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 85/100
-
Mend: dependency security vulnerability untriaged
Difficoltà 2/5 1-3 ore Idoneità per principianti 70/100