Skip to content

bug(security): pr-merge-gitlab.ts shell-injection in repo interpolation (defence-in-depth) #408

@bakeb7j0

Description

@bakeb7j0

Summary

Pre-existing shell-injection surface in lib/adapters/pr-merge-gitlab.ts:86. The repo arg is interpolated raw into the shell command:

return repo !== undefined ? `${parts.join(' ')} -R ${repo}` : parts.join(' ');

This is the same injection class as PR #403/#407 (which fixed pr-merge-github.ts). The GitLab mirror was not flagged in the original code-reviewer pass and remains unpatched.

Active exploitability: Mitigated by repoOptionalSchema (regex blocks shell metacharacters at the handler boundary). This is a defence-in-depth fix — every other parts.push() in this function uses shellEscape() (line 84 escapes squashMessage).

Implementation Steps

  1. Update lib/adapters/pr-merge-gitlab.ts line 86:

    return repo !== undefined ? `${parts.join(' ')} -R ${shellEscape(repo)}` : parts.join(' ');
  2. The shellEscape helper is already defined locally at line 65 — no import needed.

  3. Add a regression test in lib/adapters/pr-merge-gitlab.test.ts injecting a hostile repo value (e.g. 'sec/repo'\\''; echo PWNED; #') and verifying the dangerous chars stay inside single-quoted argv tokens.

Test Procedures

  1. Run bun test lib/adapters/pr-merge-gitlab.test.ts — all should pass.
  2. Inject 'sec/repo'\\''; echo PWNED; #' as the repo arg and verify no breakout.
  3. Run full suite — confirm no regressions.

Acceptance Criteria

  • pr-merge-gitlab.ts:86 shell-escapes repo via shellEscape()
  • New test asserts shell-injection is contained within argv tokens
  • Full test suite passes (no regressions)
  • Existing tests updated if they assert on unquoted form

Dependencies

Metadata

Field Value
Repository Wave-Engineering/mcp-server-sdlc
Surfaced by code-reviewer trust-score gate (plan #390 audit byproduct)

Metadata

Metadata

Assignees

No one assigned

    Labels

    type::bugSomething is not working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions