Skip to content

fix(security): detect GitHub stateless token format (~520 chars)#530

Merged
Dumbris merged 1 commit into
mainfrom
fix/github-stateless-token-detection
May 27, 2026
Merged

fix(security): detect GitHub stateless token format (~520 chars)#530
Dumbris merged 1 commit into
mainfrom
fix/github-stateless-token-detection

Conversation

@Dumbris

@Dumbris Dumbris commented May 26, 2026

Copy link
Copy Markdown
Member

Why

GitHub notified that GitHub App installation tokens are moving to a new stateless format (ghs_…) that is much longer (~520 chars) than today's 40-char tokens, warning that "apps with hardcoded length assumptions may break."

Two of mcpproxy's secret-handling layers hardcoded the old length and silently break on the new format:

Layer Old Failure mode
Sensitive-data detector (internal/security/patterns/tokens.go) ghp_/gho_/ghs_/ghr_ pinned to {36} FindAllString substring-matched a longer token but truncated the capture to 40 chars — the recorded detection dropped the ~480-char tail, so the token tail could be stored in plaintext in the activity log
Log sanitizer (internal/logs/sanitizer.go) \b(gh[poushr]_[A-Za-z0-9]{36,255})\b A ~520-char alphanumeric run has no \b word boundary within {36,255}, so the regex matched nothing and the token leaked into logs unmasked

What

  • Widened both to open-ended {36,}.
  • Short-token rejection (ghp_12345) and existing 40-char behavior unchanged.

Tests (TDD)

  • TestGitHubTokenPatterns_LongStatelessFormat — asserts the full 520-char token is captured for all four prefixes (failed showing 40-of-520 truncation before the fix).
  • TestSanitizer_GitHubTokens + TestSanitizer_LongStatelessGitHubToken (new internal/logs/sanitizer_test.go) — long token leaked unmasked before, masked after; 40-char tokens still masked.

Verification: internal/security/patterns, internal/logs, internal/security all pass; gofmt clean, go vet clean. E2E suite shows the same 10 pre-existing failures with and without this change (unrelated upstream_servers env/args/headers flow), so no regression introduced. The tool-approval-hash stability canary is unaffected — this only touches detection/redaction regexes.

GitHub App installation tokens (ghs_) are moving to a stateless format
that is much longer (~520 chars) than today's 40-char tokens. Two
detection layers hardcoded the old length and silently break on it:

- internal/security/patterns/tokens.go: ghp_/gho_/ghs_/ghr_ patterns
  pinned to exactly {36} chars. FindAllString still substring-matched a
  longer token but truncated the capture to 40 chars, so the recorded
  detection dropped the ~480-char tail. Widened to {36,}.

- internal/logs/sanitizer.go: github_token mask regex bounded at
  {36,255} with \b anchors. A ~520-char alphanumeric run has no word
  boundary within range, so the regex matched nothing and the token
  leaked into logs unmasked. Widened to {36,}.

Short-token rejection (ghp_12345) and 40-char tokens still behave as
before. Added tests asserting full capture / masking of a 520-char token.
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying mcpproxy-docs with  Cloudflare Pages  Cloudflare Pages

Latest commit: 89ea1d0
Status: ✅  Deploy successful!
Preview URL: https://0b49110a.mcpproxy-docs.pages.dev
Branch Preview URL: https://fix-github-stateless-token-d.mcpproxy-docs.pages.dev

View logs

@codecov-commenter

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@github-actions

Copy link
Copy Markdown

📦 Build Artifacts

Workflow Run: View Run
Branch: fix/github-stateless-token-detection

Available Artifacts

  • archive-darwin-amd64 (27 MB)
  • archive-darwin-arm64 (25 MB)
  • archive-linux-amd64 (16 MB)
  • archive-linux-arm64 (14 MB)
  • archive-windows-amd64 (27 MB)
  • archive-windows-arm64 (24 MB)
  • frontend-dist-pr (0 MB)
  • installer-dmg-darwin-amd64 (21 MB)
  • installer-dmg-darwin-arm64 (18 MB)

How to Download

Option 1: GitHub Web UI (easiest)

  1. Go to the workflow run page linked above
  2. Scroll to the bottom "Artifacts" section
  3. Click on the artifact you want to download

Option 2: GitHub CLI

gh run download 26437210697 --repo smart-mcp-proxy/mcpproxy-go

Note: Artifacts expire in 14 days.

@Dumbris Dumbris merged commit 93d2153 into main May 27, 2026
28 checks passed
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