docs(audit): exact-code exhibit for Copilot token laundering
This commit is contained in:
+46
-10
@@ -54,16 +54,52 @@ argument. Local-only exposure, but an exec-shaped footgun in a codebase that
|
||||
otherwise doesn't do this.
|
||||
**Status: REMOVED.** JSON-only now.
|
||||
|
||||
### 1.5 Copilot auth plugin: token handling + request sniffing (DELETED)
|
||||
Before removal, the GitHub Copilot integration:
|
||||
- used an OAuth *refresh token* directly as the API bearer token,
|
||||
- stripped inbound `authorization`/`x-api-key` headers and replaced them,
|
||||
- JSON-parsed every outgoing request body to guess "is this vision? is this an
|
||||
agent?" in order to set policy headers (`x-initiator`,
|
||||
`Copilot-Vision-Request`) that GitHub's gate required.
|
||||
This was reverse-engineered policy evasion, ~5,400 lines, self-described in
|
||||
its README as "temporary… avoid making edits."
|
||||
**Status: DELETED entirely**, including the vendored AI-SDK fork behind it.
|
||||
### 1.5 Copilot auth plugin: token laundering + request sniffing (DELETED)
|
||||
|
||||
The GitHub Copilot integration routed every inference request through a custom
|
||||
fetch override (retrieved here from git history, `copilot.ts` auth loader):
|
||||
|
||||
```ts
|
||||
const headers: Record<string, string> = {
|
||||
"x-initiator": isAgent ? "agent" : "user",
|
||||
...(init?.headers),
|
||||
"User-Agent": `opencode/${InstallationVersion}`,
|
||||
Authorization: `Bearer ${info.refresh}`, // GitHub OAuth refresh token
|
||||
"Openai-Intent": "conversation-edits",
|
||||
}
|
||||
if (isVision) headers["Copilot-Vision-Request"] = "true"
|
||||
delete headers["x-api-key"]
|
||||
delete headers["authorization"]
|
||||
return fetch(request, { ...init, headers })
|
||||
```
|
||||
|
||||
**Token laundering, precisely:** three operations on every request.
|
||||
|
||||
1. *Re-credentialing* — the long-lived GitHub **OAuth refresh token** from
|
||||
plaintext `auth.json` was presented as the Bearer session credential for
|
||||
Copilot's inference endpoints. Your GitHub identity became the API key.
|
||||
2. *Stripping prior credentials* — inbound `x-api-key` / lowercase
|
||||
`authorization` headers were deleted so only the laundered token rode the
|
||||
wire (case-sensitivity quirk spared the one they had just set).
|
||||
3. *Impersonation of sanctioned-client behavior* — `x-initiator`,
|
||||
`Openai-Intent`, and `Copilot-Vision-Request` are GitHub policy-gate
|
||||
headers. Unofficial clients are rejected without them; values were
|
||||
fabricated by JSON-parsing every request body across three API formats to
|
||||
guess "vision?" and "agent?".
|
||||
|
||||
**What it accomplished:** converted one OAuth device-flow consent into
|
||||
standing access to Copilot's paid model APIs from an unsanctioned client,
|
||||
with per-request header fabrication sufficient to pass GitHub's gate — while
|
||||
avoiding any implementation of short-lived token exchange/rotation.
|
||||
|
||||
**Why dangerous:** long-lived credential transmitted on every call (one
|
||||
logged/proxied request captures a token with a huge blast-radius window);
|
||||
plaintext storage at rest; blind stripping destroyed corporate proxy auth
|
||||
headers; ToS exposure borne unknowingly by users.
|
||||
|
||||
~5,400 lines total including the vendored AI-SDK fork behind it,
|
||||
self-described in its README as "temporary… avoid making edits."
|
||||
**Status: DELETED entirely.**
|
||||
|
||||
### 1.6 Hardcoded OAuth client IDs in source (LOW)
|
||||
Device-flow client IDs for xai, DigitalOcean, Snowflake, Codex (and formerly
|
||||
|
||||
Reference in New Issue
Block a user