Skip to content

fix(security): prevent SSRF via unvalidated GitHub Enterprise URL in Copilot plugin#22

Open
tejas0077 wants to merge 9308 commits intoCyberStrikeus:mainfrom
tejas0077:fix/security-oauth-credential-detection
Open

fix(security): prevent SSRF via unvalidated GitHub Enterprise URL in Copilot plugin#22
tejas0077 wants to merge 9308 commits intoCyberStrikeus:mainfrom
tejas0077:fix/security-oauth-credential-detection

Conversation

@tejas0077
Copy link
Copy Markdown

@tejas0077 tejas0077 commented Mar 19, 2026

Fixes #23
What does this PR do?
Fixes a Server-Side Request Forgery (SSRF) vulnerability in the GitHub Copilot plugin where the enterpriseUrl input was only validated for URL format but not checked against safe domain patterns.
An attacker could supply internal addresses (127.0.0.1, localhost, 192.168.x.x) or attacker-controlled domains, causing CyberStrike to make OAuth requests to unintended endpoints and forward Bearer tokens to those endpoints.
Related to CWE-918 (Server-Side Request Forgery).
Type of change

Bug fix
Security tool / MCP server / Bolt plugin

Security impact

This PR modifies authentication / authorization logic

How did you verify it works?
Manually tested with the following inputs:

localhost → rejected with "Internal or loopback addresses are not allowed"
127.0.0.1 → rejected with "Internal or loopback addresses are not allowed"
192.168.1.1 → rejected with "Internal or loopback addresses are not allowed"
company.ghe.com → accepted correctly
github.mycompany.com → accepted correctly

Reviewed the fetch call chain to confirm baseURL, DEVICE_CODE_URL, and ACCESS_TOKEN_URL are always constructed from validated domains only. Defense in depth applied at both the UI validate hook and inside authorize().
Checklist

PR is focused on a single change
No secrets, credentials, or API keys in the diff
bun turbo typecheck passes
Tested locally with at least one LLM provider
Breaking changes are documented (if any)

K-Mistele and others added 30 commits February 12, 2026 04:54
…de SDK (#8161)

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Dax Raad <d@ironbay.co>
Makes npm and api fields optional in the provider schema so model definitions

can be more flexible when provider package details aren't needed.
Co-authored-by: opencode-agent[bot] <opencode-agent[bot]@users.noreply.github.com>
Co-authored-by: Frank <frank@anoma.ly>
github-actions Bot and others added 26 commits March 17, 2026 20:38
These inherited from opencode require SSH keys (AUR) and cross-repo
push permissions (homebrew-tap) that aren't configured. npm publish
is the only distribution channel needed for now.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Removes push trigger from publish workflow to prevent unwanted
dev builds on every commit. Releases are now manual-only via
workflow_dispatch.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The npm bin script was still looking for opencode-* packages and
opencode binary name, causing "failed to install the right version"
error on install.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Anthropic added billing header verification on 2026-03-17, causing
HTTP 400 for Sonnet/Opus models with OAuth tokens. This generates
the required SHA256-based billing header and prepends it as a system
block, matching the claude-code client protocol.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add dedicated system prompts for cyberstrike (primary) and general agents with ReAct reasoning discipline
- Rewrite all 6 session prompt files from coding agent to offensive security identity
- Add safety guard in publish.ts to abort if no binary packages found in dist/

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Use scoped @cyberstrike-io/cyberstrike@latest for npm/bun install
- Fix cyberstrike.us → cyberstrike.io in install script

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ninstall

- install: add -B/--beta flag to fetch latest pre-release from GitHub
- install: update help text and example URLs to cyberstrike.io/install.sh
- uninstall.ts: fix executeUninstall to use @cyberstrike-io/cyberstrike (scoped)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Previously TUI would show a blank screen if port 4096 was already in
use. Now the server tries the requested port first, then falls back to a
random available port. Also adds error handling in the TUI thread so a
proper message is shown instead of a blank screen if all ports fail.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The v1.1.3 binary had a symbol mismatch between the bundled JS code
(expecting setCursorStyle) and the native library (exporting
setCursorStyleOptions), causing blank screen on TUI startup. Pinning
both packages to 0.1.88 ensures consistent types and native symbols.
Also fixes PasteEvent API change (text -> bytes).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Drizzle's migrator uses sqlite3_prepare_v2 which only compiles the first
SQL statement. Multi-statement migrations without "--> statement-breakpoint"
delimiters silently skipped all but the first statement while being recorded
as applied. This caused missing columns (request.response_headers, etc.)
and broken web_credential table (type/value not migrated to headers).

- Add generic schema reconciler that compares all Drizzle table definitions
  against actual SQLite schema on startup and adds any missing columns
- Add web_credential type/value → headers structural repair for existing DBs
- Fix migration SQL files with proper statement-breakpoint delimiters
- Export all web proxy tables from schema.ts

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Replace dual-license (MIT + PolyForm) with single AGPL-3.0-only
- Delete LICENSE-MIT and LICENSE-POLYFORM
- Update LICENSE with full AGPL-3.0 text
- Update all 17 package.json license fields from MIT to AGPL-3.0-only
- Fix Twitter link: x.com/cyberstrike → x.com/cyberstrikeio
- Fix domain: cyberstrike.us → cyberstrike.io in READMEs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Global domain rebrand across 81 files: source code, tests, configs,
i18n translations, theme schemas, infra, workflows, and fixtures.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…olt 1:N architecture

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
docs: README rewrite with intelligence layer and SEO
…Copilot plugin

The enterpriseUrl input was only checked for valid URL format but not
validated against safe domain patterns, allowing SSRF attacks by
supplying internal/loopback addresses or attacker-controlled domains.

Changes:
- Added validateEnterpriseDomain() with regex pattern and blocklist
  for loopback, private, and internal addresses (CWE-918)
- Applied validation in both the UI validate hook and authorize()
  for defense in depth
- Removed non-null assertion on enterpriseUrl with explicit check

Affected: packages/cyberstrike/src/plugin/copilot.ts
@github-actions
Copy link
Copy Markdown
Contributor

Thanks for your contribution!

This PR doesn't have a linked issue. All PRs must reference an existing issue.

Please:

  1. Open an issue describing the bug/feature (if one doesn't exist)
  2. Add Fixes #<number> or Closes #<number> to this PR description

See CONTRIBUTING.md for details.

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.