Unmasking Persistent Git Compromises: Beyond Personal Tokens

Developer confused by unauthorized activity from a powered-off laptop
Developer confused by unauthorized activity from a powered-off laptop

The Alarming Case of the Powered-Off Compromise

Imagine this: you’ve secured your GitHub account—revoked all tokens, changed passwords, enabled 2FA, and even deleted potentially infected local repos. Yet, unauthorized force-pushes to your organization’s repository resume, all while your laptop is completely powered off. This perplexing scenario, recently highlighted in a GitHub Community discussion, reveals a critical blind spot in many security strategies: the compromise isn't just about stolen personal credentials; it's about persistent access mechanisms that operate beyond your immediate control.

The user, prashannaLeo, experienced this nightmare twice after running an npm install with a known malicious package loader. The key takeaway from the community's expert advice is that if unauthorized git actions persist after a full personal credential rotation, the attacker likely isn't replaying an old token. Instead, something is actively minting new credentials or leveraging an overlooked access vector.

Security team analyzing audit logs and git reports on a large screen
Security team analyzing audit logs and git reports on a large screen

Understanding the Persistence: Beyond Your Personal Account

When personal token revocations and password changes don't stop the attacks, the focus must shift to other potential points of compromise. The community identified several sophisticated persistence methods:

Organizational-Level Vulnerabilities

  • Git Author Spoofing & Lateral Compromise: Git authenticates the pusher, not the author. If a teammate's account is compromised, the attacker can push code while spoofing your email, making it appear as if you're the culprit. This highlights the need for a comprehensive view of git reports across the organization.
  • Malicious Deploy Keys: Attackers with admin access can add hidden Deploy Keys to a repository. These keys are tied to the repo, not a user account, rendering personal revocations ineffective.
  • CI/CD Pipeline Poisoning: Malware injected into build configuration files (like postcss.config.js) can execute within CI/CD runners (e.g., GitHub Actions). The attacker can then use the runner's GITHUB_TOKEN or other environment variables to force-push code.
  • OAuth Apps and GitHub Apps: These applications grant permissions independent of PATs or SSH keys. A malicious app, once authorized, can maintain access even after password changes and 2FA enrollment.

Local Machine Persistence

  • Credential Helpers and Cached Sessions: Your git config credential.helper might point to OS-level storage (e.g., Windows Credential Manager, macOS Keychain) that still holds a valid token, or a plaintext ~/.git-credentials file.
  • npm/yarn Config and Persistence Hooks: Malicious loaders can modify ~/.npmrc, ~/.yarnrc (for registry hijacks or auth tokens), shell startup files (.bashrc, .zshrc), or create scheduled tasks (cron jobs, LaunchAgents) to re-establish access.
  • Environment Variables: Info-stealers might dump GITHUB_TOKEN or NPM_TOKEN into shell profiles, allowing them to persist across reboots.

A Comprehensive Remediation Strategy

To break this cycle, a multi-pronged approach is essential, leveraging detailed git reports and audit logs:

  1. Audit Your GitHub Security Log: Go to github.com/settings/security-log and filter for oauth_authorization, personal_access_token, public_key, and ssh_certificate_authority events. Look for any new token/key creation post-revocation.
  2. Check Authorized OAuth Apps and GitHub Apps: Review github.com/settings/applications (Authorized OAuth Apps) and github.com/settings/installations (Installed GitHub Apps) and revoke anything you don't recognize.
  3. Perform a Deep Local Machine Audit:
    git config --global --get credential.helper
    cat ~/.git-credentials 2>/dev/null
    cat ~/.gitconfig
    cat ~/.npmrc
    cat ~/.yarnrc
    crontab -l
    env | grep -i -E "token|github|npm"
    Check shell startup files (~/.bashrc, ~/.zshrc, ~/.bash_profile) and system-level scheduled tasks.
  4. Leverage the Organization Audit Log (Critical): The organization owner or admin should go to github.com/organizations//settings/audit-log. Trace the exact unauthorized force-push events. This is the most definitive git report, showing who performed the action, the IP address, user agent, and crucially, whether it was associated with a PAT, OAuth App, deploy key, or SSH key.
  5. Audit Repo-Level Access: In the organization repository settings, meticulously check Deploy Keys, GitHub Apps, and Webhooks for anything suspicious.
  6. Consider an Org-Wide Reset: If lateral compromise is suspected, treat the entire engineering team as compromised. Every developer who interacted with the repository should revoke tokens and audit their environments.
  7. The Nuclear Option: Given recurring compromise, a full OS wipe and fresh install from a clean, different device is often the safest course of action. Rotate all credentials from this clean machine.

This situation underscores that developer productivity hinges on robust security practices that extend beyond individual accounts to encompass organizational infrastructure and continuous monitoring. By understanding these advanced attack vectors and diligently using available git reports and audit logs, teams can effectively unmask and prevent persistent compromises.

|

Dashboards, alerts, and review-ready summaries built on your GitHub activity.

 Install GitHub App to Start
Dashboard with engineering activity trends