Files
PowerToys/tools/mcp/github-artifacts/package.json
Gordon Lam 1ce0509fc7 Fix GITHUB_TOKEN leak in github-artifacts MCP helper (#48782)
## Summary

Hardens the local `github-artifacts` MCP helper
(`tools/mcp/github-artifacts/server.js`) so the `GITHUB_TOKEN` bearer
token is only ever sent to allowlisted GitHub API hosts. Previously the
same token was attached when downloading image and ZIP URLs extracted
from issue/PR Markdown, which could forward the token to any host
referenced in untrusted issue content.

This is repository MCP dev-tooling, not the shipped PowerToys runtime.

## What changed

- **New `auth.js`** centralizes token handling:
  - `AUTH_ALLOWED_HOSTS = { api.github.com }`
- `shouldSendGitHubToken(url)` — true only for HTTPS + allowlisted host
- `headersForUrl(url, token, extra)` — attaches `Authorization` only
when the host is allowlisted
- **`server.js`** routes all three request sites (`fetchJson`,
`downloadBytes`, `downloadZipBytes`) through `headersForUrl`. Image/ZIP
URLs from issue content are now fetched **without** `Authorization`.
Removed the ZIP dual-attempt auth retry that previously sent the token
to untrusted hosts.
- **New `test-token-allowlist.js`** regression test (wired into `npm
test` / `npm run test:unit`).

## Verification

- Unit test: 13/13 pass — token attached for `api.github.com`, withheld
from arbitrary hosts, loopback, look-alike hostnames
(`api.github.com.attacker.com`), non-HTTPS, and
`*.githubusercontent.com`.
- Cross-origin redirects: confirmed Node's `fetch` (undici) strips
`Authorization` when a redirect leaves the origin.
- Functionality preserved (real public issues, real token): issue #25595
images (5/5 downloaded) and issue #39476 `PowerToysReport_*.zip`
(downloaded + extracted) both succeed without the token — GitHub serves
this content via public/signed URLs.

## Note

For private-repo attachments that would require an `Authorization`
header on a non-API host, the token is intentionally not sent (the
recommended tradeoff). PowerToys is public, so the helper's normal use
is unaffected.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-22 16:37:03 +08:00

21 lines
508 B
JSON

{
"name": "github-artifacts",
"version": "1.0.0",
"description": "",
"main": "server.js",
"scripts": {
"test": "node test-token-allowlist.js && node test-github_issue_images.js && node test-github_issue_attachments.js",
"test:unit": "node test-token-allowlist.js",
"start": "node server.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"type": "module",
"dependencies": {
"@modelcontextprotocol/sdk": "^1.25.2",
"jszip": "^3.10.1",
"zod": "^3.25.76"
}
}