Skip to content

Resolve template injection on comment command#7546

Merged
youknowone merged 1 commit intoRustPython:mainfrom
ShaharNaveh:comment-commands-inject
Mar 30, 2026
Merged

Resolve template injection on comment command#7546
youknowone merged 1 commit intoRustPython:mainfrom
ShaharNaveh:comment-commands-inject

Conversation

@ShaharNaveh
Copy link
Copy Markdown
Contributor

@ShaharNaveh ShaharNaveh commented Mar 30, 2026

Validated that this version still works by pushing this branch to my main branch and triggering it at ShaharNaveh#53 (comment)

Summary by CodeRabbit

  • Chores
    • Improved GitHub Actions workflow configuration for handling issue assignments through enhanced environment variable management.

@ShaharNaveh ShaharNaveh added the skip:ci Skip running the ci label Mar 30, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 30, 2026

📝 Walkthrough

Walkthrough

A GitHub Actions workflow step that assigns issues now retrieves the assignee username via a step-level environment variable instead of direct template interpolation in the JSON payload. The env: block sets USER to the commenter's login, and the curl request references this variable.

Changes

Cohort / File(s) Summary
Workflow Configuration
.github/workflows/comment-commands.yml
Refactored issue assignment step to source assignee username through an env: block setting USER to the commenter's login, updating the curl request to reference ${{ env.USER }} instead of direct interpolation.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

Possibly related PRs

Suggested reviewers

  • youknowone

Poem

🐰 Hop, hop, variables bloom,
In workflows bright, no more gloom,
Env blocks neat, so clean and tight,
Assignees dance in perfect light!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Resolve template injection on comment command' accurately describes the main change: fixing a template injection vulnerability by moving the variable interpolation from inside the JSON payload to a step-level environment variable.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/comment-commands.yml:
- Around line 21-23: Replace the compile-time interpolation of ${{ env.USER }}
in the curl payload with a runtime-built, JSON-encoded payload using the shell
USER variable; specifically, stop using `${{ env.USER }}` inside the curl -d
string in the curl invocation and instead construct the JSON at runtime (e.g.,
use jq or another JSON encoder to create '{"assignees":["<user>"]}' from the
shell $USER) and pass that encoded payload to curl; change the step that sets
env: USER and the curl invocation in .github/workflows/comment-commands.yml so
the JSON is built and escaped by the runner (refer to the USER env variable and
the curl -d invocation in the file).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: c688521f-dae5-4a95-ab77-25e077a517b1

📥 Commits

Reviewing files that changed from the base of the PR and between 2703f94 and f81eebf.

📒 Files selected for processing (1)
  • .github/workflows/comment-commands.yml

Comment on lines +21 to +23
curl -H "Authorization: token ${{ github.token }}" -d '{"assignees": ["${{ env.USER }}"]}' https://api.github.com/repos/${{ github.repository }}/issues/${{ github.event.issue.number }}/assignees
env:
USER: ${{ github.event.comment.user.login }}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

`For GitHub Actions security hardening:

  1. Are expressions like ${{ env.USER }} inside run: interpolated before shell execution?
  2. What is GitHub’s documented guidance for handling untrusted input in workflows (especially script injections)?
  3. Is jq available by default on ubuntu-slim GitHub-hosted runners?`

💡 Result:

  1. Yes. In a run: step, expressions inside ${{ ... }} (including ${{ env.USER }}) are evaluated and substituted before the temporary shell script is executed, which is why this pattern can enable shell injection if the value is attacker-controlled. [1]

  2. GitHub’s guidance for untrusted input / script injection (documented):

    • Treat GitHub context fields that can be influenced by users (for example issue/PR title, body, branch names, etc.) as potentially untrusted and prevent them from flowing into places where they may be interpreted as code. [1]
    • Avoid embedding untrusted values directly via ${{ ... }} inside run: scripts. Prefer assigning the expression to an intermediate environment variable and then referencing it using the shell’s native variable syntax (for example "$TITLE" in bash). [2][3]
  3. Yes. jq is included by default on the GitHub-hosted runner label ubuntu-slim (the image’s installed software list includes jq, and it’s also present as an installed apt package). [4]

Sources
[1] GitHub Docs — “Script injections”
[2] GitHub Security Lab — “Keeping your GitHub Actions and workflows secure Part 2: Untrusted input”
[3] CodeQL query help — “Code injection” (GitHub Actions)
[4] actions/runner-images — ubuntu-slim-Readme.md (installed software list)


Use runtime JSON encoding instead of expression interpolation in payload.

At line 21, ${{ env.USER }} is still evaluated as a GitHub Actions expression before the shell script runs, which means untrusted input (github.event.comment.user.login) flows through expression interpolation into the JSON. GitHub's security guidance explicitly recommends against this pattern. Build the JSON payload at runtime with proper escaping instead.

Suggested hardening
-      - run: |
-          curl -H "Authorization: token ${{ github.token }}" -d '{"assignees": ["${{ env.USER }}"]}' https://api.github.com/repos/${{ github.repository }}/issues/${{ github.event.issue.number }}/assignees
+      - run: |
+          payload="$(jq -cn --arg user "$USER" '{assignees: [$user]}')"
+          curl -fsS \
+            -H "Authorization: token ${{ github.token }}" \
+            -H "Content-Type: application/json" \
+            -d "$payload" \
+            "https://api.github.com/repos/${{ github.repository }}/issues/${{ github.event.issue.number }}/assignees"
         env:
           USER:  ${{ github.event.comment.user.login }}

This uses shell variable substitution ($USER) instead of GitHub expression interpolation, and jq encodes the JSON safely. jq is available by default on ubuntu-slim runners.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
curl -H "Authorization: token ${{ github.token }}" -d '{"assignees": ["${{ env.USER }}"]}' https://api.github.com/repos/${{ github.repository }}/issues/${{ github.event.issue.number }}/assignees
env:
USER: ${{ github.event.comment.user.login }}
payload="$(jq -cn --arg user "$USER" '{assignees: [$user]}')"
curl -fsS \
-H "Authorization: token ${{ github.token }}" \
-H "Content-Type: application/json" \
-d "$payload" \
"https://api.github.com/repos/${{ github.repository }}/issues/${{ github.event.issue.number }}/assignees"
env:
USER: ${{ github.event.comment.user.login }}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/comment-commands.yml around lines 21 - 23, Replace the
compile-time interpolation of ${{ env.USER }} in the curl payload with a
runtime-built, JSON-encoded payload using the shell USER variable; specifically,
stop using `${{ env.USER }}` inside the curl -d string in the curl invocation
and instead construct the JSON at runtime (e.g., use jq or another JSON encoder
to create '{"assignees":["<user>"]}' from the shell $USER) and pass that encoded
payload to curl; change the step that sets env: USER and the curl invocation in
.github/workflows/comment-commands.yml so the JSON is built and escaped by the
runner (refer to the USER env variable and the curl -d invocation in the file).

# Using REST API and not `gh issue edit`. https://github.com/cli/cli/issues/6235#issuecomment-1243487651
- run: |
curl -H "Authorization: token ${{ github.token }}" -d '{"assignees": ["${{ github.event.comment.user.login }}"]}' https://api.github.com/repos/${{ github.repository }}/issues/${{ github.event.issue.number }}/assignees
curl -H "Authorization: token ${{ github.token }}" -d '{"assignees": ["${{ env.USER }}"]}' https://api.github.com/repos/${{ github.repository }}/issues/${{ github.event.issue.number }}/assignees

Check notice

Code scanning / zizmor

code injection via template expansion Note

code injection via template expansion
@youknowone youknowone merged commit 611b122 into RustPython:main Mar 30, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

skip:ci Skip running the ci

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants