Skip to content

fix(external-plugins): authenticate plugin proxy routes - #78

Closed
bherila wants to merge 6 commits into
mainfrom
codex/fix-unauthenticated-access-in-external-plugin-proxy
Closed

bherila wants to merge 6 commits into
mainfrom
codex/fix-unauthenticated-access-in-external-plugin-proxy

Conversation

@bherila

@bherila bherila commented Aug 15, 2026

Copy link
Copy Markdown
Owner

Motivation

  • Close a critical auth/impersonation vulnerability where external plugin proxy routes under /x/{plugin} were reachable without authentication and forwarded client-controlled x-temps-* headers that plugin SDKs trusted.
  • Ensure plugin requests carry a trusted, server-derived user identity and tamper-proof signature instead of accepting attacker-supplied headers.

Description

  • Require authenticated callers for the plugin listing route by adding the RequireAuth extractor to list_external_plugins and require SystemAdmin permission for reload_plugins using check_permission and Permission::SystemAdmin in crates/temps-external-plugins/src/handler.rs.
  • Add a guard to the dynamic proxy fallback so the /x/{plugin} proxy rejects unauthenticated requests early in crates/temps-external-plugins/src/plugin.rs.
  • Harden the proxy in crates/temps-external-plugins/src/proxy.rs to remove any caller-controlled x-temps-* headers, synthesize x-temps-user-id, x-temps-user-email, x-temps-user-role, x-temps-request-id from AuthContext, and HMAC-sign the proxied request with the plugin auth_secret into x-temps-auth-signature.
  • Add necessary dependencies (temps-auth, hmac, sha2, hex) and update CHANGELOG.md documenting the security fix.

Testing

  • Ran cargo check -p temps-external-plugins --lib which completed successfully.
  • Ran cargo test -p temps-external-plugins --lib and all unit tests passed (39 passed, 0 failed).
  • Built the crate during the change verification and the package compiled without warnings under the workspace build.

Codex Task

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for security reviews. Please try again later.

bherila and others added 6 commits August 15, 2026 07:43
Runs cargo check + lib tests on the tempsdev1 self-hosted runner for
pushes to main/feature/**/fix/** and manual dispatch. Scoped to push
and workflow_dispatch only (never pull_request/pull_request_target) so
fork PRs can never execute on the self-hosted host. Uses a persistent,
isolated CARGO_TARGET_DIR outside the runner work dir so the build
cache survives checkout cleans and is reused across runs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
A warm CARGO_TARGET_DIR caches the example plugins' build-script fingerprint,
so after actions/checkout git-cleans the source tree the script is skipped and
include_dir!(".../web/dist") panics on the missing dir. Recreate the debug
placeholder assets up front so the check is independent of build-script cache.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
temps-cli embeds crates/temps-cli/dist via include_dir!; like the example
plugins its build.rs placeholder is skipped on a warm cache, so generalize the
prep step to cover every include_dir! dist target, not just the plugins.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…vy crates

cargo test --lib --workspace pulled in temps-domains' real-Pebble ACME tests,
which need a challenge-responder network this box can't provide. Match the
unit-a/unit-b crate list from rust-tests.yml instead (Docker+networking-heavy
crates run in hosted's dedicated integration jobs, not here).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Its local_provider tests launch a real bundled Chromium against live
example.com/github.com. The hosted ubuntu-latest image ships
google-chrome system-wide so headless_chrome reuses it; this self-hosted
box has no system browser, so headless_chrome auto-downloads one and the
parallel tests race on the binary (Text file busy) and debug ports (no
available ports between 8000 and 9000). It is a live-network browser
integration test, not a unit test, and hosted CI already covers it.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@bherila
bherila force-pushed the codex/fix-unauthenticated-access-in-external-plugin-proxy branch from 84baf04 to 6ff8735 Compare August 15, 2026 07:43
@github-actions

Copy link
Copy Markdown

📓 Changelog preview

This is what your commits will add to the generated CHANGELOG.md at release time (via git-cliff). Do not edit CHANGELOG.md by hand — it is generated from your Conventional Commit messages.

## [Unreleased]

### CI

- **self-hosted:** Add build/test workflow on push to bherila fork
- **self-hosted:** Recreate example-plugin web/dist before cargo check
- **self-hosted:** Also recreate temps-cli/dist placeholder
- **self-hosted:** Run hosted unit-test crate set, skip integration-heavy crates
- **self-hosted:** Exclude temps-screenshots live-browser tests

### Fixed

- **external-plugins:** Authenticate plugin proxy routes

@bherila

bherila commented Oct 11, 2026

Copy link
Copy Markdown
Owner Author

Upstream gotempsh#676 records that current main already had a stronger equivalent of this proposal; its replacement gotempsh#677 was subsequently merged.

Fork main has now been fast-forwarded to upstream main at 7250ab59b38d3138014ade7f5d6391c856eaa4f7. Closing this obsolete fork PR as part of the upstream synchronization; its branch history is retained.

@bherila bherila closed this Oct 11, 2026
@bherila
bherila deleted the codex/fix-unauthenticated-access-in-external-plugin-proxy branch October 11, 2026 19:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant