TL;DR: A one-character Go module mismatch let a malicious decimal package keep the expected API while hiding import-time command execution, according to Corgea. Go dependency checks need path verification and cache hygiene, not just successful builds.
Editorial analysis by NHI Mgmt Group, based on content published by Corgea: “shopsprint/decimal Go typosquat hides DNS TXT command backdoor”.
Key questions
Q: Why do typosquatted Go modules create supply-chain risk even when builds succeed?
A: Because build success only proves the code compiled, not that the imported package is the one developers intended.
Q: What are the signs that a Go dependency is acting like a backdoor?
A: Look for unexpected init() logic, background goroutines, outbound DNS activity from packages that should be deterministic, and imports such as os/exec or net in libraries with no reason to use them.
Q: What breaks when a Go dependency keeps the right API but the wrong module path?
A: The control that breaks is provenance, not compilation.
Practitioner guidance
- Enforce exact module-path admission controls Block typosquat paths such as github.com/shopsprint/decimal in dependency policy so imports fail closed before they reach build or runtime environments.
- Rebuild from a clean module state Replace the malicious path with github.com/shopspring/decimal, run go mod tidy, and rebuild after clearing module caches, mirrors, and lock data that may still retain v1.3.3.
- Hunt for import-time backdoor indicators Search source, caches, logs, and binaries for unexpected init() functions, net.LookupTXT, os/exec.Command, and the dnslog-cdn-images.freemyip.com hostname.
Bottom line: A Go typosquat can preserve a familiar API and still behave as an execution backdoor the moment it is imported.
Glossary terms: Typosquatted Dependency, Import-time execution, Module Path Verification, DNS-Based Command Channel
Explore further
View Full Forum → | NHI Foundation Course → | Our Services → | Read the full analysis →
Supply-chain camouflage is now an identity problem, not only a code-review problem: when a dependency preserves its API while changing its runtime behaviour, trust shifts from function names to provenance and path control. That matters because build systems, module mirrors, and internal caches become the decision points that admit or reject execution. Practitioners should treat dependency identity as an enforced control boundary, not a naming convention.
A question worth separating out:
Q: Should teams trust module mirrors and caches after a malicious version is discovered?
A: No. Mirrors and caches can preserve a malicious version long after the original repository has changed or been removed, which means the compromise may survive as a reproducible build input. Teams should invalidate affected caches, deny the bad path, and verify that rebuilt artefacts no longer reference the poisoned module.
👉 Read our full editorial: Go module typosquats can turn safe-looking dependencies into backdoors