Skip to content

Security review of plugin + scripts — 2 critical, 1 high, 2 lower (NLPM auto-scan) #1694

@xiaolai

Description

@xiaolai

Hi — while running an automated NL-quality audit on this repository (NLPM), the security pre-scan flagged two patterns I think are worth surfacing privately rather than as PRs. Friendly notice; both may be intentional.

Findings

# Severity File Line Pattern
1 Critical scripts/modules/prompt-manager.js 280 new Function(...) evaluating template-config conditions
2 Critical packages/claude-code-plugin/commands/install-taskmaster.md 95 curl … | bash inside a Claude command file
3 High packages/claude-code-plugin/commands/install-taskmaster.md 79 sudo npm install -g in the same command file
4 Medium .mcp.json 5 npx -y task-master-ai — no version pin, auto-confirm
5 Low package.json 63–125 ^ semver range on security-sensitive deps (jsonwebtoken, undici, express)

Finding #1 — hidden eval in template-config

new Function(...Object.keys(context), `return ${condition}`)

new Function() is functionally equivalent to eval(). The condition argument flows from template configuration. If any code path lets user-controllable data reach condition (a custom prompt pack, an editable template file, a config reload from disk), this is RCE shaped exactly like a classic eval injection.

Safer shape: a small expression evaluator (e.g., expr-eval or a custom AST walker) that only permits the operators your conditions actually need. Even a hardcoded allowlist of condition strings would close the gap.

Finding #2 — curl-pipe-sh inside a Claude command

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash

Embedding curl … | bash inside a Claude command file means Claude will run it as part of /taskmaster:install-taskmaster without the user seeing what the remote URL serves at fetch time. Two problems compound:

  • The pinned tag (v0.39.0) doesn't pin the content — a tag can be moved.
  • A user invoking /taskmaster:install-taskmaster doesn't get the standard "you're about to pipe curl into bash" cognitive friction.

Safer shape: download the script, show its checksum to the user, then execute with explicit consent. Or detect nvm presence and instruct the user to install it themselves before running the rest of the workflow.

Finding #3 — sudo in a Claude command

sudo npm install -g task-master-ai

Same file as #2. Claude executing sudo inside an automated workflow asks the user to type their root password as a side effect of running a slash command — surprising, and in CI contexts won't work at all. The npm install itself should probably be done at user scope (npm install -g without sudo on a user-owned npm prefix, or pnpm/yarn with their own paths).

Findings #4 and #5

Lower priority but worth a glance: npx -y skips the prompt that would normally let a user catch a swapped package, and ^-range semver on jsonwebtoken/undici/express means a future minor version with a vulnerability flows in without a review.

About this report

Findings come from NLPM's security pattern matcher applied to executable artifacts. The matcher surfaces patterns; intent is on the maintainer to confirm. If any are intentional, please close this issue. If you'd like fix PRs for any of them, let me know which and I'll send them — keeping security issues off the public PR queue while you triage.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:cliCLI functionalityarea:vscode-extensionVS Code extension relatedbugSomething isn't workinghigh-priorityUrgent issue requiring immediate attention

    Projects

    Status

    Triage

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions