Guide Shows How to Uncover Forged GitHub Histories Used to Hide Malware

Summary
A guide explains how to investigate Git history tampering linked to the PolinRider campaign by comparing commit metadata with server-side push records and registry timestamps. Its case study found the npm package remained clean.
Key points
- The guide describes malware manipulating local clocks and Git identity, then force-pushing forged commits to make malicious changes appear legitimate or disappear from history.
- Compare author and committer metadata with GitHub’s server-side activity and organization audit logs, which record who pushed and when.
- Check whether a force-push rewrote history, whether the same commit appeared across multiple branches, and what changed in the files.
- Cross-reference package registry or CI timestamps to determine whether tampered code reached users; the case study found the published npm package was not poisoned.
- Look for surviving original commits in collaborator clones, CI logs, pull request timelines, notifications, or webhooks.
- Investigate from a fresh, isolated environment. Do not install dependencies, build or run untrusted code, open the repository in an auto-executing editor, or fetch submodules automatically.
- The case study attributes the suspicious push to a likely victim’s compromised account, emphasizing that a pushing account should not automatically be treated as the attacker.
Article Details
- Defense Focus
- Reconstruct Git repository history using independent server-side and registry timestamps to detect tampering, establish its scope, and avoid executing malicious code during investigation.
- Detection Methods
- Inspect raw commit objects and compare author and committer timestamps, timezone offsets, identities, and chronological consistency.
- Compare GitHub push activity and, where accessible, organization audit-log events with commit metadata to identify the authenticated pusher and force-push time.
- Compare before-and-after commit SHAs and test whether the prior commit is an ancestor; look for identical trees pushed to multiple refs within a short period.
- Diff suspicious commits against the surviving original to identify injected files or changes, including auto-run editor tasks.
- Cross-check GitHub push times against package-registry publish timestamps and gitHead values, plus CI logs and other independent records.
- Check surviving commits in older clones, forks, pull-request timelines, notifications, and webhook records; compare signatures and verification status.
- Build a UTC timeline by actor, ref, and event, and treat account attribution as uncertain until distinguishing a compromised victim from an attacker.
- Data Sources
- Git commit objects, refs, and diffs
- GitHub repository activity feed and organization audit log
- npm package metadata, publish timestamps, dist-tags, and gitHead
- CI runner logs
- Pull-request timelines
- Older local clones, forks, notification emails, chat integrations, and webhook payloads
- Commit signature and verification data
- Platforms
- GitHub
- npm
- Defensive Actions
- Investigate from a fresh clone on a trusted, disposable VM or container with restricted outbound network access, not from the potentially compromised machine.
- Keep Git patched and avoid recursive cloning; inspect .gitmodules before fetching submodules.
- Do not install dependencies, build, run project code, follow repository setup instructions, or open the repository in an editor with auto-execution enabled.
- Use a restricted or untrusted-workspace editor mode, or read files in a plain-text viewer.
- Use a scoped, temporary credential only if access is required, and revoke it afterward.
- Preserve raw event data and verify any timeline or anomaly assessment against the underlying records.
- Treat the pushing account as a probable victim unless evidence clearly indicates otherwise; notify maintainers privately when appropriate.
MITRE ATT&CK
T1059.003 · Windows Command ShellThe article describes a Windows batch script, temp_auto_push.bat, that changes the local clock and Git identity before committing and force-pushing.T1059.007 · JavaScriptA VS Code folder-open task runs Node.js on the disguised fa-solid-500.woff2 file, which the article identifies as the injected payload.T1565.001 · Stored Data ManipulationThe described tampering script replaces existing repository commits by force-pushing forged history and injected files across refs.
CVE
People
michaelyaliThe GitHub account that force-pushed the tampered commits; the article identifies the account holder as a victim, not a threat actor.Shady KhalifaThe name and email on the surviving legitimate, GPG-signed commit; the article says this maintainer was uninvolved.shekohexThe account associated in the case study with the repository's earlier legitimate pushes.
Malware
Vendors
Products
GitHubThreat actors commonly manipulate git history to make a GitHub author or repo look more credible, or to hide malicious activity. This guide walks through how to get past that and reconstruct what actually happened,npmMake a package look safe (there’s a corresponding typosquat on npm, for example)
Tools
curlcurl: Needed for steps 2 and 4, to call GitHub’s API and the npm registry.GitThreat actors commonly manipulate git history to make a GitHub author or repo look more credible, or to hide malicious activity. This guide walks through how to get past that and reconstruct what actually happened,Insomniaor package, since these are just web addresses returning JSON, or into a free GUI tool like Postman or Insomnia.jqjq: optional. Formats the JSON responses from curl into something readable.Postmanrepository or package, since these are just web addresses returning JSON, or into a free GUI tool like Postman or Insomnia.