Skip to content

chore: update DocGuard extension to v0.21.1#2707

Open
raccioly wants to merge 1 commit into
github:mainfrom
raccioly:update-docguard
Open

chore: update DocGuard extension to v0.21.1#2707
raccioly wants to merge 1 commit into
github:mainfrom
raccioly:update-docguard

Conversation

@raccioly
Copy link
Copy Markdown
Contributor

DocGuard Community Extension Update

Updates the DocGuard community extension catalog entry.

Changes

Release Notes

Security patch — closes issue #190. Command injection vulnerability in
docguard init via the ai field of .specify/init-options.json is fixed.

Security

  • Issue What command should we execute in the VS Code terminal after navigating to the project directory using cd <project_name> if we want to use Git Copilot? #190: command injection in cli/commands/init.mjs and
    cli/ensure-skills.mjs.
    The detectAIAgent() helper returned the
    ai field from .specify/init-options.json without validation, and
    that value was then shell-interpolated into an execSync invocation:

    const aiFlag = `--ai ${detectedAgent}`;
    execSync(`specify init ... ${aiFlag} ...`);

    A local attacker with file-system write access to a victim's repo
    could plant {"ai": "claude; touch /tmp/pwned;"} and trigger
    arbitrary command execution on the victim's next docguard init.

    Severity: Medium (requires local file-system access; pre-fix
    detectAIAgent consumed configs from any project DocGuard ran in).

    Discovered: 23 duplicate auto-generated draft PRs from the
    "Sentinel" AI agent flagged this during the v0.19 cleanup sweep.
    The drafts were closed as noise but the underlying finding was
    tracked in What command should we execute in the VS Code terminal after navigating to the project directory using cd <project_name> if we want to use Git Copilot? #190 — fixed properly here.

    Fix (two layers, defense in depth):

    1. getDetectedAgent() now allowlist-validates the ai field against
      /^[a-zA-Z0-9_-]{1,32}$/. Anything else (shell metacharacters,
      non-strings, oversized values) returns null.
    2. New safeSpawnSpecify(args, opts) helper uses execFileSync with
      args passed as an array — no shell interpolation possible. Both
      unsafe call sites (init.mjs and ensure-skills.mjs) now use
      this helper. Cross-platform (POSIX direct exec / Windows
      cmd.exe /c specify.cmd).

Tests

  • 596 → 610 (+14): tests/security-init-injection.test.mjs pins
    both defense layers. Tests every shell metacharacter (;, backtick,
    $(), |, &&, newline), oversized values, non-string types,
    malformed JSON, missing config files. Asserts the legitimate
    allowlist (claude, cursor-agent, gemini, agy, copilot, windsurf,
    codex, roo, amp, kiro-cli, tabnine, underscore-bearing future names).

Audit

grep -rn execSync cli/ was re-run; remaining call sites are all
hardcoded literals (no attacker-influenced interpolation): freshness
git probes, score's git probe, setup/doc-quality which-style
detection. Documented in commit message.


This PR was automatically generated by the DocGuard release pipeline.

Copilot AI review requested due to automatic review settings May 26, 2026 16:15
@raccioly raccioly requested a review from mnriem as a code owner May 26, 2026 16:15
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Updates the community extensions catalog metadata to reflect a new docguard release and refreshes the catalog timestamps.

Changes:

  • Bumped docguard extension version and updated its release download URL.
  • Updated updated_at timestamps for the catalog and the docguard entry.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

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.

2 participants