Software supply chain forensics is different from traditional digital forensics. You are not examining a compromised server or a malware sample in isolation. You are tracing an attack path that potentially crosses organizational boundaries -- from an upstream package maintainer's compromised laptop to your CI/CD pipeline to your production deployment. The artifacts you need are scattered across registries, build logs, version control systems, and deployment records.
The discipline is young. Compared to disk forensics or network forensics, supply chain forensics lacks standardized tools and established procedures. But the methodology can be structured, and the evidence, when preserved, is often more conclusive than in other forensic domains because software supply chains produce detailed, timestamped records.
Initial Triage
When a supply chain compromise is suspected, the first question is scope: what is affected?
Identify the compromised component. Is it a direct dependency, a transitive dependency, a build tool, or a CI/CD plugin? The component type determines the investigation path. A compromised npm package requires different forensic techniques than a compromised GitHub Action.
Determine the exposure window. When was the malicious version published? When did your systems first install it? The window between first installation and detection defines the potential impact period. Lock files with timestamps, CI/CD build logs, and container image creation dates provide the evidence.
Map the blast radius. Which applications, services, or systems installed the compromised component? SBOM records are invaluable here. If you have SBOMs for every build, you can query them to find every artifact that includes the compromised dependency.
Without SBOMs, you must scan every repository's lock files for the compromised package and version. This is slower and may miss applications that installed the package and later removed it (the lock file shows current state, not historical state).
Evidence Collection
Supply chain forensic evidence exists in multiple locations. Collect it before it disappears.
Package registry records. Download the compromised package version. Many registries remove malicious packages quickly, so capture the tarball, the metadata, and the publication timestamp before it is deleted. Use npm pack package@version or download directly from the registry API.
Version control history. If the compromised package has a public repository, clone it and examine the commit history around the time of the malicious publication. Look for: new maintainers added, commits from unfamiliar accounts, changes to build scripts or CI configuration, and changes to the package metadata (especially the scripts section in package.json).
Build logs. Your CI/CD system's build logs show exactly when each dependency was installed and what happened during installation. Lifecycle script output, network requests made during the build, and any warnings or errors from the package manager are all relevant.
Container image layers. If your applications are containerized, the image layers record which packages were installed and when. Use docker history and layer inspection tools to identify which layer introduced the compromised package.
Network logs. If the compromised package exfiltrated data, network logs may show the exfiltration. Look for DNS queries to unusual domains, HTTP/HTTPS connections to unknown endpoints, and unusual data volumes from build systems.
Lock file history. Git history of your lock files shows when the compromised version first appeared in your dependency tree. Use git log -p -- package-lock.json (or equivalent) to trace the exact commit that introduced the vulnerable version.
Analysis Methodology
Dependency tree reconstruction. Reconstruct the dependency tree at the time of compromise. The current dependency tree may differ because patches have been applied. Use the lock file from the compromised build to generate the exact dependency tree. Tools like npm ls --all with the historic lock file show the complete resolution.
Malicious code analysis. Extract and analyze the malicious code from the compromised package version. Focus on: what data did it access (environment variables, files, network endpoints)? Where did it send data (domains, IP addresses)? What persistence mechanisms did it use? What conditions triggered activation?
The analysis should produce a list of indicators of compromise (IOCs): domains contacted, files accessed, environment variables read, data patterns exfiltrated. These IOCs drive the impact assessment.
Timeline construction. Build a timeline that maps: when the compromised package was published, when your systems first installed it, which builds included it, when it was deployed to production, and when it was detected. This timeline is essential for determining which systems were affected and for how long.
Lateral movement analysis. If the malicious code stole credentials (CI/CD tokens, cloud provider keys, registry tokens), assess what those credentials could access. A stolen NPM_TOKEN could have been used to publish malicious versions of your organization's packages. A stolen AWS_ACCESS_KEY_ID could have been used to access your infrastructure.
Common Attack Patterns
Understanding common supply chain attack patterns helps focus the investigation.
The credential harvester. The malicious code reads environment variables and sends them to an attacker-controlled server. Common targets: NPM_TOKEN, GITHUB_TOKEN, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, database connection strings, and API keys. Investigation focus: network logs for exfiltration, credential rotation scope.
The backdoor installer. The malicious code modifies the build output or deployment artifacts to include a backdoor. This is harder to detect because the compromised dependency functions normally -- the malicious behavior is in what it adds to the final artifact. Investigation focus: artifact comparison between clean and potentially compromised builds.
The build system compromiser. The malicious code modifies CI/CD configuration or installs persistent access mechanisms on the build system. This extends the compromise beyond a single dependency update. Investigation focus: CI/CD system integrity, build configuration changes, user account audit.
Evidence Preservation
Supply chain forensic evidence is ephemeral. Package registries delete malicious packages. Build logs rotate. Container images are replaced. Preserve evidence immediately upon discovering a potential compromise.
Create forensic copies. Download and hash compromised package versions. Export build logs. Snapshot container images. Copy lock files and dependency trees.
Document the chain of custody. Record who collected what evidence, when, and how. This matters for legal proceedings and for verifying that evidence has not been tampered with.
Preserve upstream evidence. If possible, archive the compromised package's repository state, registry metadata, and maintainer information. This data may be relevant for law enforcement or for coordinating with the package registry's security team.
Post-Investigation Actions
Forensic findings drive remediation:
Credential rotation. If the investigation determines that credentials were exposed, rotate them immediately. Do not wait for confirmation that credentials were used -- rotate on suspicion.
Artifact rebuilding. Rebuild all artifacts that included the compromised dependency from clean inputs. Do not patch -- rebuild. A patch assumes you understand all the malicious changes. A clean rebuild starts from known-good inputs.
Detection rule creation. Convert IOCs from the investigation into detection rules for your security monitoring systems. DNS queries to the exfiltration domain, HTTP requests to the command-and-control server, file access patterns matching the malware's behavior.
Supply chain hardening. Apply the lessons learned. If the compromise entered through a transitive dependency, implement deeper dependency monitoring. If it entered through a lifecycle script, implement script blocking or sandboxing.
How Safeguard.sh Helps
Safeguard.sh maintains a historical record of your dependency supply chain through continuous SBOM generation. When a compromise is discovered, you can query Safeguard.sh to determine exactly which applications, builds, and deployments included the compromised component and when. This blast radius mapping, which would otherwise require manually searching through build logs and lock files, is available immediately. Safeguard.sh's vulnerability intelligence also correlates your dependency history with emerging threat data, enabling faster triage when new supply chain compromises are disclosed.