You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Coordinated disclosure: github-safe.js helper interpolates argv into a shell string passed to execSync (AS-S001) #3411
We scanned the top 100 MCP-related npm packages by weekly downloads as part of a security study (full report + methodology). @claude-flow/mcp@3.0.0-alpha.9 (current npm latest) came up with one finding we would like to hand you before anything is published — public disclosure is held for 14 days from the date on this issue.
The shipped helper .claude/helpers/github-safe.js runs (lines 101 and 105):
args comes from the script’s own argv, so any caller — including a prompt-injected agent that composes this command line — gets its content executed through a shell. Wildcards, $(…), backticks, ; all expand. The gap is that a helper namedgithub-safe is exactly what agents (and humans) will trust without reading; the name promises sanitization the implementation does not do.
Suggested fix (drop the shell entirely):
execFileSync('gh',args,{stdio: 'inherit'});
If the intent is an allowlist of gh subcommands, validate args[0] against it before exec — either way no shell string is ever constructed.
npm pack @claude-flow/mcp && tar -xzf claude-flow-mcp-*.tgz
npx @yoshine2007/agent-scan@latest .
We are fans of the project — this is a one-line fix that turns a trust-checking finding into nothing. Happy to re-run and confirm clean before you ship.
Confirmed against the published @claude-flow/mcp@3.0.0-alpha.9 tarball without executing an exploit. Current main already contains the shell-free source fix from commit 0e1d26c11, but that repair has not reached the published artifact.
Draft PR #3412 adds package-copy parity and behavioral regression coverage across all three shipped helpers. Local checks pass 15/15 cases and the packed alpha.10 candidate contains the hardened helper. No release or merge was performed.
Because the affected package remains published, please coordinate the release and disclosure through a private security advisory; do not treat source-only repair as remediation.
2026-09-25 delivery verification (public-safe): the npm latest, alpha, and v3alpha dist-tags still resolve @claude-flow/mcp to 3.0.0-alpha.9; 3.0.0-alpha.10 is not published. The current Ruflo release/tag contains newer source, but its release path does not publish the standalone MCP package, so the affected registry artifact remains the user-visible version. Draft PR #3412 remains cleanly mergeable and its harmless regression passes 18/18 plus packed-candidate argv/body/bounds cases, but it does not change the package version, lockfile, or publishing workflow. Closure therefore requires a private advisory, an authorized standalone MCP release, retrieval of the exact published tarball, replay of all helper/error/bounds regressions against that tarball, and verification that the intended dist-tags moved. No release or merge was performed by this review.
This verifies package publication and bounded local behavior only. Adoption and production outcomes remain unverified. No production endpoint or credential was used.
Independent verification (2026-09-30), separate from the prior maintainer checks above:
@claude-flow/mcp@latest/alpha/v3alpha all resolve to 3.0.0 (confirmed via npm view @claude-flow/mcp dist-tags).
Packed and inspected @claude-flow/mcp@latest (3.0.0) directly: it does not ship .claude/helpers/github-safe.js or any execSync call — the affected helper surface is absent from this artifact.
Packed and inspected @claude-flow/mcp@3.0.0-alpha.10 directly: it does ship .claude/helpers/github-safe.js, and all three gh invocations use execFileSync('gh', argv, ...) — no shell-string execSync remains.
In the repo source, all three shipped copies of github-safe.js pass the regression smoke (scripts/smoke-github-safe-injection.mjs, 18/18 cases: backtick/$()/semicolon bodies, oversized-body rejection, argv whitespace preservation).
This confirms the fix (PR #3412) and the publish are both live on the registry as of this comment. No further code or release action is needed on our end for this report. Thanks again for the responsible disclosure and the clean repro steps — appreciated.
Activity
ruvnet commentedon Sep 24, 2026
Confirmed against the published
@claude-flow/mcp@3.0.0-alpha.9tarball without executing an exploit. Current main already contains the shell-free source fix from commit0e1d26c11, but that repair has not reached the published artifact.Draft PR #3412 adds package-copy parity and behavioral regression coverage across all three shipped helpers. Local checks pass 15/15 cases and the packed alpha.10 candidate contains the hardened helper. No release or merge was performed.
Because the affected package remains published, please coordinate the release and disclosure through a private security advisory; do not treat source-only repair as remediation.
ruvnet commentedon Sep 25, 2026
2026-09-25 delivery verification (public-safe): the npm
latest,alpha, andv3alphadist-tags still resolve@claude-flow/mcpto3.0.0-alpha.9;3.0.0-alpha.10is not published. The current Ruflo release/tag contains newer source, but its release path does not publish the standalone MCP package, so the affected registry artifact remains the user-visible version. Draft PR #3412 remains cleanly mergeable and its harmless regression passes 18/18 plus packed-candidate argv/body/bounds cases, but it does not change the package version, lockfile, or publishing workflow. Closure therefore requires a private advisory, an authorized standalone MCP release, retrieval of the exact published tarball, replay of all helper/error/bounds regressions against that tarball, and verification that the intended dist-tags moved. No release or merge was performed by this review.chore(release): move 18 internal leaf packages from alpha to stable s…
ruvnet commentedon Sep 29, 2026
Delivery verification update (2026-09-29)
The source/package gap tracked here is now closed in current official registry artifacts:
@claude-flow/mcp@3.0.0-alpha.10published 2026-09-27@claude-flow/mcp@3.0.0published 2026-09-28; currentlatest,v3alpha, andalphatags resolve to 3.0.0ghnpm auditreports zero findings for bothArtifact digests:
cb17b2537a05e7ce26759fcbf622df2e064bf5ef7a67239501fe43b42a97731c0c44e4e99634cd6e73d3fa64fb9bdb6a5516f9c5db0d1ac9fb56090db179a56dThis verifies package publication and bounded local behavior only. Adoption and production outcomes remain unverified. No production endpoint or credential was used.
nicholas-ruest commentedon Sep 30, 2026
Independent verification (2026-09-30), separate from the prior maintainer checks above:
@claude-flow/mcp@latest/alpha/v3alphaall resolve to3.0.0(confirmed vianpm view @claude-flow/mcp dist-tags).@claude-flow/mcp@latest(3.0.0) directly: it does not ship.claude/helpers/github-safe.jsor anyexecSynccall — the affected helper surface is absent from this artifact.@claude-flow/mcp@3.0.0-alpha.10directly: it does ship.claude/helpers/github-safe.js, and all threeghinvocations useexecFileSync('gh', argv, ...)— no shell-stringexecSyncremains.github-safe.jspass the regression smoke (scripts/smoke-github-safe-injection.mjs, 18/18 cases: backtick/$()/semicolon bodies, oversized-body rejection, argv whitespace preservation).This confirms the fix (PR #3412) and the publish are both live on the registry as of this comment. No further code or release action is needed on our end for this report. Thanks again for the responsible disclosure and the clean repro steps — appreciated.
ruvnet commentedon Oct 7, 2026
@/tmp/claude-0/-home-user-ruflo/99a198e7-2058-59ed-a922-018777f60b76/scratchpad/triage/i3411.md
Generated by Claude Code