Supply-chain case study
Threat analysis · 28 Aug 2026
In May 2026, a NuGet package called Sicoob.Sdk posed as
an official integration library for Sicoob, one of Brazil's largest
cooperative banking systems. Developers who used it to automate Pix
payments and Boleto invoicing handed it exactly what a banking SDK
needs — an mTLS client certificate and its password — and the
package quietly shipped both to an attacker-controlled
Sentry endpoint. The
linked GitHub repository stayed clean the whole time. Here is how
it worked — and, honestly, which layer of defence actually stops it.
Sicoob.Sdk 2.0.0–2.0.4, act first, read second.
Treat the mTLS certificate (PFX), its password, and the client ID
used with that integration as fully compromised: revoke and reissue
the certificate with Sicoob, rotate the credentials, and audit
Pix and Boleto transactions processed since the package was
introduced. The exfiltration ran inside your application's normal
operation — there is no crash or error to look for.
What happened
This was not typosquatting. The package name, the
sicoob publisher profile, and the documentation all
impersonated an official SDK that Sicoob never published on
NuGet. The library genuinely worked: it authenticated against
Sicoob's APIs, generated Pix QR codes, produced Boleto
invoices. That is what made it dangerous — it earned its place
in production integrations at Brazilian firms doing automated
banking.
The theft was wired into initialisation. When an application
instantiated SicoobClient with its credentials,
the package read the PFX client-certificate file from disk,
Base64-encoded it, and sent the client ID, the PFX password and
the encoded certificate to a hardcoded third-party
Sentry endpoint —
abusing a legitimate error-tracking service as an exfiltration
channel that blends into normal outbound telemetry. A separate
Sentry path captured Boleto API responses, giving the attacker
ongoing visibility into payment data. With the certificate and
credentials, an attacker can impersonate the victim's banking
integration end to end.
The cover was a source-to-package mismatch: the GitHub repository the package linked to contained clean code, and stayed clean. The malicious logic existed only in the artifacts uploaded to NuGet — so a developer who "checked the source" before adopting the dependency saw nothing wrong. Socket's researchers found the malicious versions (2.0.0–2.0.4, roughly 500 downloads) and 11 more suspicious packages under the same profile with about 6,000 combined downloads; NuGet blocked them after responsible disclosure.
~500
downloads of the malicious Sicoob.Sdk versions 2.0.0–2.0.4
12
suspicious packages under the fake sicoob profile, ~6,000 downloads combined
0 diffs
the linked GitHub repo stayed clean — malice lived only in the NuGet upload
mTLS
stolen: client certificate (PFX), its password, client ID, Boleto API data
The OrbitalReg defence
This attack's entry ticket was an official-sounding name from an unknown publisher. Behind a curated OrbitalReg proxy, a new dependency from an unvetted NuGet profile doesn't resolve until someone approves it — and "is this SDK actually published by the bank?" is precisely the question an approval step forces. Sicoob has no official NuGet presence; that check fails in one search.
"The repo looks clean" proved worthless here, because the repo wasn't what shipped. Provenance-first policy — preferring packages with verifiable build provenance, and treating a linked repository that cannot reproduce the published artifact as a red flag — turns this attack's main camouflage into its main detection signal.
The moment the malicious versions land in the advisory feeds,
every pull of Sicoob.Sdk — or any of the 11 sibling
packages — through your registry gets a
403 instead of the
package: fleet-wide, from one policy change, without chasing
each project's lockfile or .csproj.
The append-only trail answers "which builds ever pulled
Sicoob.Sdk, and when" in one query — which is your
certificate-revocation and transaction-audit scope in the first
hour. In air-gap mode, an unknown banking SDK never resolves at
all until it is explicitly imported and approved.
dotnet add package away, and the audit
trail turns "are we affected?" from an investigation into a query.
Indicators of compromise
Indicators compiled from Socket's disclosure and public reporting of 29 May 2026. Treat these as a starting point, not a complete list, and cross-check the sources below.
Sources
Want unknown publishers blocked by default?
Rico, the founder, walks through a curation + pull-gate + audit layout for NuGet and your other formats — so a fake "official" SDK is an approval request, not a production incident.