Skip to content

Harden launcher against argument injection#341

Merged
clcollins merged 2 commits into
mainfrom
srepd/launcher-arg-injection
Jul 9, 2026
Merged

Harden launcher against argument injection#341
clcollins merged 2 commits into
mainfrom
srepd/launcher-arg-injection

Conversation

@clcollins

Copy link
Copy Markdown
Owner

Summary

replaceVars joined args on spaces → ReplaceAll → split on spaces,
re-tokenizing any substituted value containing a space into extra argv
elements. Cluster/incident IDs come from PagerDuty alert data and the command
is passed to exec.Command, so an attacker-controlled cluster_id like
x --evil-flag y could inject extra arguments (not shell RCE — argv injection).

Two layers:

  1. replaceVars rewritten to substitute per-arg — a value with spaces stays
    one argv element.
  2. Added exported ocm.ValidClusterID; getUniqueClusters now drops any
    cluster_id failing ^[a-zA-Z0-9_-]+$ before it reaches the launcher.

Test plan

  • TDD: 3 test groups written first (red), then green
  • TestReplaceVars_PreservesArgBoundaries asserts on the []string slice,
    not a joined string — the existing TestLoginCommandBuild compares via
    strings.Join and is boundary-blind, so this closes that gap
  • TestValidClusterID + TestGetUniqueClusters_RejectsMalformedClusterID
  • Existing launcher/ocm/tui tests unchanged and green
  • make test-all green (fmt, vet, lint, test, race, test-fixtures)

skip-readme: internal security hardening, no user-facing config/flag/keybinding changes.

🤖 Generated with Claude Code

replaceVars joined args on spaces, substituted, then split back on spaces,
re-tokenizing any substituted value containing a space into extra argv
elements. Since cluster/incident IDs come from PagerDuty alert data and the
command is passed to exec.Command, an attacker-controlled cluster_id like
"x --evil-flag y" could inject extra arguments.

Two layers: (1) rewrite replaceVars to substitute per-arg so a value never
crosses argv boundaries; (2) add exported ocm.ValidClusterID and validate
cluster IDs in getUniqueClusters so malformed values never reach the launcher.

New replaceVars test asserts on the []string slice (the existing
TestLoginCommandBuild compares via strings.Join, which is boundary-blind).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@clcollins clcollins added the skip-readme Skip README update CI check label Jul 8, 2026
@codecov-commenter

codecov-commenter commented Jul 8, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 66.38%. Comparing base (b1d523c) to head (64ea57b).

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #341      +/-   ##
==========================================
+ Coverage   66.33%   66.38%   +0.04%     
==========================================
  Files          50       50              
  Lines        8154     8160       +6     
==========================================
+ Hits         5409     5417       +8     
+ Misses       2369     2368       -1     
+ Partials      376      375       -1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@clcollins clcollins merged commit bfb9516 into main Jul 9, 2026
10 checks passed
@clcollins clcollins deleted the srepd/launcher-arg-injection branch July 9, 2026 17:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

skip-readme Skip README update CI check

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants