Skip to content

Security: Backstage identity JWT may leak to external GitHub host in CI activity proxy #218

@coderabbitai

Description

@coderabbitai

Summary

In plugins/catalog-backend-module-rhaap/src/router.ts, the handleGitHubCIActivity function currently falls back to forwarding the incoming Authorization header to the upstream GitHub API when no integration token is configured:

const tokenFromRequest = request.headers.authorization?.replace(/^Bearer\s+/i, '');
const { token: tokenFromConfig } = getGitHubIntegrationForHost(config, host);
const token = tokenFromConfig || tokenFromRequest;

Backstage's fetchApi automatically injects the Backstage identity JWT (not a GitHub PAT) into Authorization: Bearer <backstage-jwt> on every outbound request. When tokenFromConfig is absent, this code strips the Bearer prefix and forwards that internal Backstage JWT to api.github.com (or any configured GitHub Enterprise host). GitHub will reject it, but the internal token is still sent to an external host — constituting an internal token leak.

Recommended Fix

  1. Verify the caller via the existing httpAuth service (already available in createRouter options).
  2. Use a dedicated upstream header (e.g., X-GitHub-Token) for the GitHub PAT instead of repurposing Authorization.
// Verify caller is a legitimate Backstage user/service
await httpAuth.credentials(request as unknown as HttpAuthRequest, {
  allow: ['user', 'service'],
});

// Use a dedicated header for the upstream GitHub token
const tokenFromRequest = request.headers['x-github-token'] as string | undefined;
const { token: tokenFromConfig, apiBaseUrl: apiBaseFromConfig } =
  getGitHubIntegrationForHost(config, host);
const token = tokenFromConfig || tokenFromRequest;

The frontend (RepositoriesCIActivityTab.tsx / useLatestCIActivity.ts) would need to be updated to send X-GitHub-Token instead of relying on the Backstage Authorization header for the GitHub PAT.

References

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions