Skip to content

Security: GitHub OAuth tokens stored in plaintext in database #244

Description

@chonilius

Problem

The GithubAccount entity stores OAuth access tokens in plaintext in the database (src/common/entities/github-account.entity.ts:32):

/**
 * OAuth access token used for GitHub API calls made on the user's behalf.
 * TODO: encrypt at rest (e.g. KMS envelope encryption) before production use.
 * Never returned via API responses — excluded at the DTO/serialization layer.
 */
@Column({ type: 'varchar', nullable: true, select: false })
accessToken: string | null;

This is explicitly marked as a TODO but represents a critical security vulnerability.

Risk

If the database is compromised (SQL injection, backup leak, insider threat), attackers gain:

  • Full GitHub API access with user permissions
  • Ability to read private repositories
  • Ability to create/modify issues and PRs on behalf of users
  • Access to user's GitHub organizations and private data

Impact

  • Severity: Critical
  • Affected data: All user OAuth tokens
  • Compliance: Violates SOC2, PCI-DSS, and GitHub's OAuth security guidelines

Recommended Solution

Implement envelope encryption using AWS KMS, Google Cloud KMS, or HashiCorp Vault:

  1. Generate a data encryption key (DEK) per token
  2. Encrypt the DEK with a master key in KMS
  3. Store encrypted token + encrypted DEK in database
  4. Decrypt on-demand when making GitHub API calls

Alternative (simpler): Use application-level encryption with a master key from environment:

import { createCipheriv, createDecipheriv, randomBytes } from 'crypto';

// Encrypt before saving
const iv = randomBytes(16);
const cipher = createCipheriv('aes-256-gcm', masterKey, iv);
const encrypted = Buffer.concat([cipher.update(token), cipher.final()]);
const authTag = cipher.getAuthTag();
// Store: iv + authTag + encrypted

// Decrypt when loading
const decipher = createDecipheriv('aes-256-gcm', masterKey, iv);
decipher.setAuthTag(authTag);
const decrypted = Buffer.concat([decipher.update(encrypted), decipher.final()]);

References

Priority

🔴 Critical - Must be fixed before production deployment

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Stellar WaveIssues in the Stellar wave program

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions