Skip to content

security: Harden GitHub workflows against prompt injection cache pivots#2119

Closed
enyst wants to merge 2 commits intomainfrom
security/harden-workflows-clinejection
Closed

security: Harden GitHub workflows against prompt injection cache pivots#2119
enyst wants to merge 2 commits intomainfrom
security/harden-workflows-clinejection

Conversation

@enyst
Copy link
Copy Markdown
Collaborator

@enyst enyst commented Feb 18, 2026

Summary

Hardens GitHub Actions workflows against the attack pattern where LLM prompt injection leads to code execution in CI, which then enables cache poisoning pivots into more privileged workflows.

Attack Pattern Reference: https://adnanthekhan.com/posts/clinejection/

Security Changes

1. PR Review by OpenHands Workflow

  • Before: Triggered automatically on opened/ready_for_review/review_requested
  • After: Only runs when a maintainer applies the review-this label
  • Impact: Removes untrusted code execution path in pull_request_target workflow with secret access

2. PR Review Composite Action

  • Before: Checked out PR head repository/ref and executed PR code
  • After: Checks out trusted base repo commit and uses GitHub API for diff fetching
  • Before: Used GitHub Actions caching in setup-uv
  • After: Disables caching (enable-cache: false) to prevent cache poisoning
  • Impact: No PR code execution; no shared cache exposure

3. Auto-label Issues Workflow

  • Before: Used long-lived PAT
  • After: Uses ephemeral GITHUB_TOKEN
  • Impact: Reduced token exposure

4. Integration + Condenser Label Workflows

  • Removed unnecessary id-token: write permission
  • Gated setup-matrix job to only run for relevant labels/triggers
  • Impact: Principle of least privilege

Security Impact

Eliminates untrusted-code-execution path in pull_request_target workflow
Prevents cross-workflow cache poisoning attacks
Reduces secret exposure by using ephemeral tokens
Applies least privilege to workflow permissions

Testing

  • Workflows remain functional after changes
  • PR review workflow now requires manual review-this label application by maintainers
  • No breaking changes to legitimate use cases

Agent Server images for this PR

GHCR package: https://github.com/OpenHands/agent-sdk/pkgs/container/agent-server

Variants & Base Images

Variant Architectures Base Image Docs / Tags
java amd64, arm64 eclipse-temurin:17-jdk Link
python amd64, arm64 nikolaik/python-nodejs:python3.12-nodejs22 Link
golang amd64, arm64 golang:1.21-bookworm Link

Pull (multi-arch manifest)

# Each variant is a multi-arch manifest supporting both amd64 and arm64
docker pull ghcr.io/openhands/agent-server:14a89ae-python

Run

docker run -it --rm \
  -p 8000:8000 \
  --name agent-server-14a89ae-python \
  ghcr.io/openhands/agent-server:14a89ae-python

All tags pushed for this build

ghcr.io/openhands/agent-server:14a89ae-golang-amd64
ghcr.io/openhands/agent-server:14a89ae-golang_tag_1.21-bookworm-amd64
ghcr.io/openhands/agent-server:14a89ae-golang-arm64
ghcr.io/openhands/agent-server:14a89ae-golang_tag_1.21-bookworm-arm64
ghcr.io/openhands/agent-server:14a89ae-java-amd64
ghcr.io/openhands/agent-server:14a89ae-eclipse-temurin_tag_17-jdk-amd64
ghcr.io/openhands/agent-server:14a89ae-java-arm64
ghcr.io/openhands/agent-server:14a89ae-eclipse-temurin_tag_17-jdk-arm64
ghcr.io/openhands/agent-server:14a89ae-python-amd64
ghcr.io/openhands/agent-server:14a89ae-nikolaik_s_python-nodejs_tag_python3.12-nodejs22-amd64
ghcr.io/openhands/agent-server:14a89ae-python-arm64
ghcr.io/openhands/agent-server:14a89ae-nikolaik_s_python-nodejs_tag_python3.12-nodejs22-arm64
ghcr.io/openhands/agent-server:14a89ae-golang
ghcr.io/openhands/agent-server:14a89ae-java
ghcr.io/openhands/agent-server:14a89ae-python

About Multi-Architecture Support

  • Each variant tag (e.g., 14a89ae-python) is a multi-arch manifest supporting both amd64 and arm64
  • Docker automatically pulls the correct architecture for your platform
  • Individual architecture tags (e.g., 14a89ae-python-amd64) are also available if needed

Co-authored-by: openhands <openhands@all-hands.dev>
@enyst enyst mentioned this pull request Feb 18, 2026
Copy link
Copy Markdown
Collaborator

@all-hands-bot all-hands-bot left a comment

Choose a reason for hiding this comment

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

Taste Rating: 🟢 Good taste - Pragmatic security hardening

This PR addresses a real attack vector (LLM prompt injection → untrusted code execution in CI → cache poisoning) with a straightforward mitigation: remove automatic execution of untrusted PR code in privileged workflows.

Key Security Wins:

  • Gating PR review workflow behind explicit maintainer label removes the untrusted execution path
  • Checking out base repo instead of PR head prevents malicious code from running
  • Disabling uv cache prevents cross-workflow poisoning attacks
  • Switching from PAT to ephemeral github.token reduces credential exposure
  • Removing unnecessary id-token: write shrinks attack surface

Trade-offs (acceptable):

  • Reduced automation - maintainers must manually apply review-this label
  • PR review agent uses main SDK instead of PR changes (correct security posture)

Verdict: ✅ Worth merging - Solves real problem without over-engineering.

Key Insight: You correctly identified that convenience (auto-review on PR open) was creating a security hole, and fixed it with the principle of least privilege. This is exactly the right engineering judgment.

@juanmichelini juanmichelini changed the title Harden CI workflows against prompt injection + cache poisoning security: Harden GitHub workflows against prompt injection cache pivots Feb 18, 2026
@enyst
Copy link
Copy Markdown
Collaborator Author

enyst commented Feb 21, 2026

@OpenHands I think we may have already got part of this in main branch from other PRs, please merge main into this PR and fix the conflicts.

@openhands-ai
Copy link
Copy Markdown

openhands-ai bot commented Feb 21, 2026

I'm on it! enyst can track my progress at all-hands.dev

Co-authored-by: openhands <openhands@all-hands.dev>
@openhands-ai
Copy link
Copy Markdown

openhands-ai bot commented Feb 21, 2026

Work summary (new since the last update)

  • Verified that after merging main and pushing, the PR’s remaining diff vs main is still limited to the intended 5 files:
    • .github/actions/pr-review/action.yml
    • .github/workflows/auto-label-issues.yml
    • .github/workflows/condenser-runner.yml
    • .github/workflows/integration-runner.yml
    • .github/workflows/pr-review-by-openhands.yml

Completion checklist

  • Merged latest main into security/harden-workflows-clinejection
  • Resolved the only merge conflict (.github/workflows/pr-review-by-openhands.yml)
  • Ran pre-commit YAML formatting checks on the touched workflow/action files
  • Committed the merge with the required Co-authored-by: openhands <openhands@all-hands.dev> line
  • Pushed the updated branch to GitHub to update PR security: Harden GitHub workflows against prompt injection cache pivots #2119

Conciseness check

  • No extra PR-specific changes were introduced beyond the merge from main + the conflict resolution; the PR diff remains scoped to the security/workflow hardening files listed above.

@github-actions
Copy link
Copy Markdown
Contributor

API breakage checks (Griffe)

Result: Passed

Action log

@enyst enyst marked this pull request as draft February 25, 2026 16:39
@all-hands-bot
Copy link
Copy Markdown
Collaborator

[Automatic Post]: It has been a while since there was any activity on this PR. @enyst, are you still working on it? If so, please go ahead, if not then please request review, close it, or request that someone else follow up.

2 similar comments
@all-hands-bot
Copy link
Copy Markdown
Collaborator

[Automatic Post]: It has been a while since there was any activity on this PR. @enyst, are you still working on it? If so, please go ahead, if not then please request review, close it, or request that someone else follow up.

@all-hands-bot
Copy link
Copy Markdown
Collaborator

[Automatic Post]: It has been a while since there was any activity on this PR. @enyst, are you still working on it? If so, please go ahead, if not then please request review, close it, or request that someone else follow up.

@enyst
Copy link
Copy Markdown
Collaborator Author

enyst commented Apr 8, 2026

@OpenHands I think this was solved a while ago. If there is something necessary in it that wasn’t solved already, decide if you’d recommend it, and if yes open a new PR with it, and if not, just tell me so. Clone yourself the extensions repo too so you have the full picture.

Note that I close this PR. Don’t push to it.

@enyst enyst closed this Apr 8, 2026
@openhands-ai
Copy link
Copy Markdown

openhands-ai bot commented Apr 8, 2026

I'm on it! enyst can track my progress at all-hands.dev

Copy link
Copy Markdown
Collaborator Author

enyst commented Apr 8, 2026

I dug through both the current branch here and the migrated PR-review implementation in .

My recommendation: keep this PR closed. I would not revive it in .

What I found:

  • On , the original PR-review path has largely been superseded already: the repo now uses the extensions plugin and the workflow here no longer matches the old in-repo composite-action setup this PR was changing.
  • The part that still looked worth fixing lives in ****, where the migrated PR-review workflow/plugin still had the privileged path, automatic triggers, PR-head checkout, and cache enabled.

I opened the follow-up there instead:

That PR hardens the current home of the feature by:

  • requiring explicit maintainer-triggered review starts
  • reviewing from a trusted base checkout while sourcing the diff from the GitHub API
  • disabling cache in the privileged review path
  • defaulting the workflow template to

So my call is: don’t reopen/reuse this PR branch; the meaningful remaining fix belongs in the extensions repo, and I moved it there.

I did not push to this closed PR branch. This comment was created by an AI assistant (OpenHands) on behalf of the user.

Copy link
Copy Markdown
Collaborator Author

enyst commented Apr 8, 2026

Here’s the clean summary after checking both repositories:

My recommendation: keep this PR closed. I would not revive it in software-agent-sdk.

What I found:

  • On software-agent-sdk, the original PR-review path has largely been superseded already: this repo now uses the extensions plugin, and the workflow here no longer matches the old in-repo composite-action setup this PR was changing.
  • The part that still looked worth fixing lives in OpenHands/extensions, where the migrated PR-review workflow/plugin still had the privileged pull_request_target path, automatic triggers, PR-head checkout, and setup-uv cache enabled.

I opened the follow-up there instead:

That PR hardens the current home of the feature by:

  • requiring explicit maintainer-triggered review starts
  • reviewing from a trusted base checkout while sourcing the diff from the GitHub API
  • disabling setup-uv cache in the privileged review path
  • defaulting the workflow template to github.token

So my call is: don’t reopen or reuse this PR branch; the meaningful remaining fix belongs in the extensions repo, and I moved it there.

I did not push to this closed PR branch. This comment was created by an AI assistant (OpenHands) on behalf of the user.

@openhands-ai
Copy link
Copy Markdown

openhands-ai bot commented Apr 8, 2026

Since my last summary, there were no further code or workflow changes. The work remains as previously reported.

Completion status

Conciseness of changes

  • Changes were kept focused on the actual remaining issue in OpenHands/extensions
  • No unrelated files were intentionally kept
  • Temporary/extraneous changes were cleaned up (for example, transient artifacts were removed and a nonessential AGENTS.md edit in extensions was reverted)

Final answer

The request has been fully addressed: the old PR should remain closed, and the meaningful remaining hardening was moved into OpenHands/extensions#158 instead of reviving or pushing to the closed SDK PR branch.

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