Skip to content

🔒 [Security] Fix shell command injection in plugin runner - #225

Merged
undivisible merged 3 commits into
masterfrom
fix-plugin-command-injection-8922977327826257157
Jul 30, 2026
Merged

🔒 [Security] Fix shell command injection in plugin runner#225
undivisible merged 3 commits into
masterfrom
fix-plugin-command-injection-8922977327826257157

Conversation

@undivisible

@undivisible undivisible commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

🎯 What: The plugin runner in plugin run <name> <target> was vulnerable to shell command injection because arguments were passed to bash which could interpret shell metacharacters embedded in name or target.
⚠️ Risk: If a malicious user or automated system supplied crafted plugin names or targets containing metacharacters (like ;, $, etc.), arbitrary commands could be executed by the bash interpreter running the plugin script, potentially leading to system compromise.
🛡️ Solution: Added a strict validation function contains_shell_metacharacters to explicitly reject inputs containing dangerous shell characters during both plugin installation and execution, preventing injection. Added unit tests to ensure behavior is correct.


PR created automatically by Jules for task 8922977327826257157 started by @undivisible


Note

Medium Risk
Security-focused changes to the plugin runner; behavior tightens (invalid names/targets error) but scope is limited to the CLI plugin commands.

Overview
Hardens in plugin install and in plugin run by validating inputs before they reach bash or the filesystem.

Plugin names must be a single non-empty path segment (no /, \, ., .., or nested paths). Install and run both call plugin_name first so script paths under the registry/install dirs cannot be escaped via the name.

Run targets are resolved with workspace_target: relative paths only, no .. or absolute paths, the path must exist, canonicalization must stay under the workspace root, and symlink escapes outside the root are rejected on Unix. The runner now passes the canonical target path to the plugin script instead of root.join(target) without checks.

Adds unit tests for name rules, in-workspace targets, and symlink rejection.

Reviewed by Cursor Bugbot for commit d0652b2. Bugbot is set up for automated code reviews on this repo. Configure here.

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
@google-labs-jules

Copy link
Copy Markdown
Contributor

👋 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 @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

@cursor

cursor Bot commented Jul 29, 2026

Copy link
Copy Markdown

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@mergify

mergify Bot commented Jul 29, 2026

Copy link
Copy Markdown

Tick the box to add this pull request to the merge queue (same as @mergifyio queue).

  • Queue this pull request

undivisible and others added 2 commits July 29, 2026 21:30
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Validate plugin names as single path components and canonicalize targets within the workspace before invoking an installed script. Command arguments are passed directly to bash, so this replaces the misleading shell-token blacklist with an actual filesystem boundary.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit d0652b2. Configure here.

Comment thread in-cli/src/main/plugin.rs
return Err(InError::Message(
"plugin target must stay within the workspace".to_string(),
));
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rejects in-workspace dot-dot paths

Low Severity

workspace_target rejects any target whose parsed path includes a .. component before resolution, so values like nested/../sibling fail with “plugin target must stay within the workspace” even when they would canonicalize to a path still under root. The later canonicalize plus starts_with check already blocks escapes.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit d0652b2. Configure here.

@undivisible
undivisible merged commit 75d1ec0 into master Jul 30, 2026
7 checks passed
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.

1 participant