Harden workflow output handling#263
Conversation
Pass attacker-controllable GitHub context and workflow values through environment variables before shell use. Co-authored-by: openhands <openhands@all-hands.dev>
Co-authored-by: openhands <openhands@all-hands.dev>
Co-authored-by: openhands <openhands@all-hands.dev>
Co-authored-by: openhands <openhands@all-hands.dev>
Co-authored-by: openhands <openhands@all-hands.dev>
all-hands-bot
left a comment
There was a problem hiding this comment.
🟢 QA Report: PASS
Security hardening successfully eliminates command injection attack surface by moving user-controlled GitHub context values through env: blocks.
Does this PR achieve its stated goal?
Yes. The PR successfully addresses OpenHands/software-agent-sdk#3371 by eliminating direct interpolation of attacker-controllable values (PR titles, workflow inputs, branch names) into shell scripts. All user-influenced data now flows safely through environment variables, preventing shell expansion attacks.
Verification:
✅ Security scan completed: No user-controlled values are directly interpolated in shell script blocks
✅ YAML validation: All 4 workflow/action files pass PyYAML validation
✅ CI status: All checks passing
✅ Pragmatic approach: GitHub-controlled values (repository name, event names, PR numbers) remain as direct interpolation, which is safe and keeps the code clean
Security Analysis
User-Controlled Values (Now Safe)
All attacker-controllable values are correctly passed through env: blocks:
- ✅
github.event.pull_request.title→$GITHUB_EVENT_PULL_REQUEST_TITLE - ✅
github.event.pull_request.body→$PR_BODY - ✅
github.event.pull_request.head.ref→$PR_HEAD_BRANCH - ✅
github.ref_name→$GITHUB_REF_NAME - ✅
github.event.inputs.*→ env vars - ✅
inputs.*→ env vars (e.g.,$INPUTS_LLM_MODEL,$INPUTS_TAG)
GitHub-Controlled Values (Safe to Keep)
These remain as direct interpolation, which is pragmatic and secure:
github.repository(repository name)github.event_name(event type)github.event.pull_request.number(integer PR number)
Step Outputs (Low Risk)
Some numeric step outputs (commit-count, contributor-count) remain directly interpolated. These are generated by trusted actions and are numeric values, so they represent minimal risk. The current approach is pragmatic.
Issues Found
None.
[RISK ASSESSMENT]
- [Overall PR]
⚠️ Risk Assessment: 🟢 LOW
This PR reduces security risk by eliminating command injection attack surface. The changes are defensive and introduce no new functionality that could break existing behavior. The pragmatic approach of only hardening user-influenced values while leaving GitHub-controlled values unchanged demonstrates good engineering judgment.
VERDICT:
✅ Worth merging: Solid security improvement with no regressions
KEY INSIGHT:
This PR demonstrates good taste in security engineering - it solves the real problem (user-controlled data injection) without over-engineering by also changing safe values. The attack surface is meaningfully reduced while maintaining code clarity.
Was this automated review useful? React with 👍 or 👎 to this review to help us measure review quality.
Workflow run: https://github.com/OpenHands/extensions/actions/runs/26371148524
Why
Part of the cross-repo fix for OpenHands/software-agent-sdk#3371. Workflow
run:blocks should not interpolate derived outputs directly into shell scripts when those values may be influenced by workflow execution.Summary
env:before shell use in the summary step.$SCAN_ONLYand$VULNERABILITIES_FOUNDinstead of direct${{ ... }}interpolation.Issue Number
Fixes OpenHands/software-agent-sdk#3371
How to Test
python+PyYAMLvalidation over all changed workflow/action YAML files across the audited repositories:validated changed yaml files: 33remaining suspicious run blocks: 0git diff --checkacross all audited repositoriesNotes
This PR was created by an AI agent (OpenHands) on behalf of the user.
@enyst can click here to continue refining the PR