Skip to content

Back to the catalog

Socket: Popular Go Decimal Library Targeted by Long-Running Typosquat with DNS Backdoor
socket.devwriteup

Socket: Popular Go Decimal Library Targeted by Long-Running Typosquat with DNS Backdoor

Socket's Threat Research Team uncovered github.com/shopsprint/decimal, a six-year-old typosquat of the widely used github.com/shopspring/decimal Go library, which was weaponized in version v1.3.3 (2023-08-19) with an init() function that beacons via DNS TXT lookups to dnslog-cdn-images.freemyip.com every five minutes and executes whatever program name the C2 returns via os/exec.Command. Despite the GitHub repo and owner account being deleted, proxy.golang.org's permanent caching kept the malicious release fetchable for roughly 33 months until Socket's disclosure prompted the Go security team to withdraw it with a 403 SECURITY ERROR. The piece includes a full source diff of the payload, the "trust-then-poison" release pattern (a benign bugfix release seven minutes before the malicious one), IOCs, and detection/remediation guidance for developers and security teams.

TL;DR A six-year-old Go typosquat of shopspring/decimal was weaponized with a DNS TXT-record C2 backdoor, and Go Module Proxy caching kept it fetchable for 33 months after the source repo was deleted.
Document

What it is

github.com/shopsprint/decimal — a single-character typosquat of github.com/shopspring/decimal (the widely-used Go fixed-point decimal library, 38,634 importers on pkg.go.dev). The typosquat swaps the final g for a t. Version v1.3.3 (published 2023-08-19 09:27:21 UTC) is trojanized; all earlier tags are clean copies of upstream.

How it works

Between v1.3.2 and v1.3.3 the attacker spliced three edits into decimal.go: added imports net, os/exec, time; a malicious init(); and an empty main() inside the package. Because it lives in init(), it runs at process start with no opt-in. A background goroutine calls net.LookupTXT("dnslog-cdn-images.freemyip.com") every 5 minutes and passes each returned TXT string straight to exec.Command(txt).CombinedOutput(). The full public API and arithmetic behavior are preserved, so the module compiles, passes tests, and produces correct results — the C2 loop never touches the arithmetic paths and emits no visible output.

Preconditions / Affected

Any Go project that fetches the shopsprint/decimal path — via a typo in go.mod, an import line, go get, or IDE autocomplete — and builds a binary. Financial, billing, crypto, and analytics codebases are the intended targets. The C2 requires outbound DNS resolution of the attacker subdomain to receive commands.

What to do

  • Grep your modules and lockfiles for the typosquat path, not just the legit one:
grep -R "shopsprint/decimal" go.mod go.sum
  • Compare against the legitimate package's import set — the real shopspring/decimal imports only database/sql/driver, encoding/binary, fmt, math, math/big, regexp, strconv, strings, and has no net, os/exec, or init(). Presence of those is the tell.
  • Block/alert on DNS resolution of dnslog-cdn-images[.]freemyip[.]com.
  • Note that removal at source does not remediate: the GitHub repo and shopsprint owner account are deleted, but proxy.golang.org permanently caches and serves v1.3.3 on demand. Fixing this requires purging the dependency, not waiting for takedown.

Caveats

  • The page states public adoption signals for the typosquat itself are limited — impact depends on whether anyone actually pulled it, which the report does not quantify.
  • The "trust-then-poison" timing (benign v1.3.2 and malicious v1.3.3 seven minutes apart) is behavioral inference; only v1.3.3 is confirmed weaponized.
  • Roughly six years benign then ~33 months weaponized in the open ecosystem before disclosure.

Organisations named here

  • boltdb-go/bolt
  • dnslog-cdn-images.freemyip.com
  • freemyip.com
  • shopsprint/decimal
  • T1059
  • T1071.004
  • T1195.002
  • T1568
  • T1572
  • T1583.001

Technologies named here

  • github.com/shopsprint/decimal
  • Socket GitHub App
  • Socket CLI
  • github.com/shopspring/decimal
  • Socket Firewall
  • Socket browser extension
  • Socket MCP
  • VirusTotal / VirusTotal Intelligence
  • Go Module Proxy
  • pkg.go.dev
  • Go
  • Socket
  • VirusTotal
  • GitHub

Techniques named here

  • Compromise Software Supply Chain
  • Application Layer Protocol
  • Command and Scripting Interpreter
  • Acquire Infrastructure
  • Protocol Tunneling
  • Dynamic Resolution
  • Trust-then-poison pattern

Threat actors named here

  • Unnamed threat actor behind shopsprint/decimal typosquat