🛡️ Sentinel: [HIGH] Fix Web UI CLI Command Execution Vulnerability#93
🛡️ Sentinel: [HIGH] Fix Web UI CLI Command Execution Vulnerability#93SlasshyOverhere wants to merge 1 commit into
Conversation
🚨 Severity: HIGH 💡 Vulnerability: The Web UI's `/api/cli/run` endpoint allowed execution of interactive, non-web, or destructive CLI commands (like `vault2fa`, `sync`, `totp`, etc.). This could lead to a severe security risk as the interactive shell prompts are bypassed or data could be overwritten without intended constraints. 🎯 Impact: Attackers or malicious scripts (via XSRF/CSRF, or a compromised browser) could trigger arbitrary internal commands that alter critical vault state, overwrite configs, or start interactive tasks that cause hangs or unwanted behavior. 🔧 Fix: Added all interactive and dangerous commands (`vault2fa`, `totp`, `sync`, `duress`, `autolock`, `settings`, `theme`, `update`, `desktop`) to the `BLOCKED_WEB_CLI_COMMANDS` Set in `src/webui/server.ts` to explicitly block them from execution over HTTP endpoints. ✅ Verification: Ran `pnpm test` and `pnpm lint` to ensure everything works properly and the change hasn't broken existing functionality.
|
👋 Jules, reporting for duty! I'm here to lend a hand with this pull request. When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down. I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job! For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with New to Jules? Learn more at jules.google/docs. For security, I will only act on instructions from the user who triggered this task. |
📝 WalkthroughWalkthroughThe PR expands the Changes
Estimated code review effort🎯 1 (Trivial) | ⏱️ ~2 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 inconclusive)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/webui/server.ts`:
- Line 50: The blocklist currently defined in BLOCKED_WEB_CLI_COMMANDS is
bypassable via CLI aliases because /api/cli/run only exact-matches the first
token; update the enforcement to canonicalize the incoming command token(s)
before checking (normalize hyphens/underscores and common alias mappings such as
2fa-setup → vault2fa, vault-2fa → vault2fa, 2fa → totp, panic → duress) or
alternatively expand BLOCKED_WEB_CLI_COMMANDS to include those alias variants,
and ensure the check in the /api/cli/run handler uses the normalized token (not
raw string) when deciding to block execution.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 61f9bcc0-7b5a-439b-9c2f-02ca9f4fda95
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (1)
src/webui/server.ts
| const CLI_RUN_TIMEOUT_MS = 120_000; | ||
| const CLI_RUN_MAX_BUFFER_BYTES = 10 * 1024 * 1024; | ||
| const BLOCKED_WEB_CLI_COMMANDS = new Set(['web', 'ui', 'destruct', 'init', 'auth', 'delete']); | ||
| const BLOCKED_WEB_CLI_COMMANDS = new Set(['web', 'ui', 'destruct', 'init', 'auth', 'delete', 'vault2fa', 'totp', 'sync', 'duress', 'autolock', 'settings', 'theme', 'update', 'desktop']); |
There was a problem hiding this comment.
Blocklist is still bypassable via CLI aliases.
At Line 50, the new blocked commands omit known aliases; at Lines 533-536, enforcement is exact-match on the first token.
2fa-setup, vault-2fa, 2fa, and panic can still reach blocked handlers (vault2fa/totp/duress) through /api/cli/run.
🔒 Proposed fix
-const BLOCKED_WEB_CLI_COMMANDS = new Set(['web', 'ui', 'destruct', 'init', 'auth', 'delete', 'vault2fa', 'totp', 'sync', 'duress', 'autolock', 'settings', 'theme', 'update', 'desktop']);
+const BLOCKED_WEB_CLI_COMMANDS = new Set([
+ 'web', 'ui', 'destruct', 'init', 'auth', 'delete',
+ 'vault2fa', 'vault-2fa', '2fa-setup', '2fa', 'totp',
+ 'sync', 'duress', 'panic', 'autolock', 'settings', 'theme', 'update', 'desktop',
+]);If you want a more robust fix, canonicalize aliases before checking (or switch /api/cli/run to an explicit allowlist of safe non-interactive commands).
Also applies to: 533-536
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/webui/server.ts` at line 50, The blocklist currently defined in
BLOCKED_WEB_CLI_COMMANDS is bypassable via CLI aliases because /api/cli/run only
exact-matches the first token; update the enforcement to canonicalize the
incoming command token(s) before checking (normalize hyphens/underscores and
common alias mappings such as 2fa-setup → vault2fa, vault-2fa → vault2fa, 2fa →
totp, panic → duress) or alternatively expand BLOCKED_WEB_CLI_COMMANDS to
include those alias variants, and ensure the check in the /api/cli/run handler
uses the normalized token (not raw string) when deciding to block execution.
There was a problem hiding this comment.
Pull request overview
This PR aims to harden the Web UI’s /api/cli/run endpoint by preventing execution of high-risk CLI commands when invoked over HTTP.
Changes:
- Expanded
BLOCKED_WEB_CLI_COMMANDSin the Web UI server to deny more commands via/api/cli/run. - Added a
pnpm-lock.yamllockfile to the repository.
Reviewed changes
Copilot reviewed 1 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/webui/server.ts | Expands the Web UI CLI denylist used by /api/cli/run. |
| pnpm-lock.yaml | Introduces a pnpm lockfile (appears unrelated to the security fix and conflicts with existing npm-based workflow). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const CLI_RUN_TIMEOUT_MS = 120_000; | ||
| const CLI_RUN_MAX_BUFFER_BYTES = 10 * 1024 * 1024; | ||
| const BLOCKED_WEB_CLI_COMMANDS = new Set(['web', 'ui', 'destruct', 'init', 'auth', 'delete']); | ||
| const BLOCKED_WEB_CLI_COMMANDS = new Set(['web', 'ui', 'destruct', 'init', 'auth', 'delete', 'vault2fa', 'totp', 'sync', 'duress', 'autolock', 'settings', 'theme', 'update', 'desktop']); |
There was a problem hiding this comment.
runCliCommand blocks the delete command, but the CLI exposes delete with an alias rm (see src/index.ts). As a result, /api/cli/run can still delete entries by calling rm (e.g. rm --force ...), so the security fix is incomplete. Add rm (and any other destructive aliases) to BLOCKED_WEB_CLI_COMMANDS, or change the check to block based on Commander-resolved command name rather than the raw first token.
| const BLOCKED_WEB_CLI_COMMANDS = new Set(['web', 'ui', 'destruct', 'init', 'auth', 'delete', 'vault2fa', 'totp', 'sync', 'duress', 'autolock', 'settings', 'theme', 'update', 'desktop']); | |
| const BLOCKED_WEB_CLI_COMMANDS = new Set(['web', 'ui', 'destruct', 'init', 'auth', 'delete', 'rm', 'vault2fa', 'totp', 'sync', 'duress', 'autolock', 'settings', 'theme', 'update', 'desktop']); |
| lockfileVersion: '9.0' | ||
|
|
||
| settings: | ||
| autoInstallPeers: true | ||
| excludeLinksFromLockfile: false | ||
|
|
||
| importers: | ||
|
|
||
| .: | ||
| dependencies: | ||
| '@google-cloud/local-auth': | ||
| specifier: ^3.0.1 | ||
| version: 3.0.1 | ||
| argon2: | ||
| specifier: ^0.44.0 | ||
| version: 0.44.0 | ||
| chalk: | ||
| specifier: ^5.3.0 | ||
| version: 5.6.2 | ||
| cli-progress: |
There was a problem hiding this comment.
pnpm-lock.yaml is being added, but the repo’s CI and scripts use npm (npm ci, npm run build/lint/test) and the canonical lockfile in the repository is package-lock.json. Adding a pnpm lockfile without switching the toolchain will cause churn/confusion and can desync dependency resolution. Please remove pnpm-lock.yaml from this PR (or, if the intent is to migrate to pnpm, update CI/scripts/documentation and remove package-lock.json in a dedicated PR).
🛡️ Sentinel: [HIGH] Fix Web UI CLI Command Execution Vulnerability
🚨 Severity: HIGH
💡 Vulnerability: The Web UI's
/api/cli/runendpoint allowed execution of interactive, non-web, or destructive CLI commands (likevault2fa,sync,totp, etc.). This could lead to a severe security risk as the interactive shell prompts are bypassed or data could be overwritten without intended constraints.🎯 Impact: Attackers or malicious scripts (via XSRF/CSRF, or a compromised browser) could trigger arbitrary internal commands that alter critical vault state, overwrite configs, or start interactive tasks that cause hangs or unwanted behavior.
🔧 Fix: Added all interactive and dangerous commands (
vault2fa,totp,sync,duress,autolock,settings,theme,update,desktop) to theBLOCKED_WEB_CLI_COMMANDSSet insrc/webui/server.tsto explicitly block them from execution over HTTP endpoints.✅ Verification: Ran
pnpm testandpnpm lintto ensure everything works properly and the change hasn't broken existing functionality.PR created automatically by Jules for task 8894548285912197306 started by @SlasshyOverhere
Summary by CodeRabbit