Back to glossary

Threat Intelligence

Threat intelligence is evidence about attackers, their infrastructure, and techniques, processed into decisions to block, detect, or respond.

Also known as CTI, Cyber Threat Intelligence, TI

Threat intelligence is evidence-based knowledge about attackers, their infrastructure, and their techniques, processed so a defender can make a decision with it. Also called cyber threat intelligence (CTI), it turns raw observations such as file hashes, domains, and malicious package versions into block, detect, and respond actions. It loses value quickly, so delivery speed matters as much as accuracy.

NIST defines threat intelligence as threat information "that has been aggregated, transformed, analyzed, interpreted, or enriched to provide the necessary context for decision-making processes" (NIST SP 800-150). The operative word is decision. A list of bad IP addresses is data. Intelligence is knowing which of them should block traffic on your network today, and being right about it.

For open source software, we think most threat intelligence is aimed at the wrong layer. Classic feeds describe attacker infrastructure: IP addresses, domains, and file hashes, pushed into a SIEM to find a compromise after it happens. Malicious packages execute during install, often talk only to legitimate services, and are pulled from the registry within hours. The indicator that works is the package name and version, derived from analyzing what is actually inside the package, and enforced before the install runs.

The most important fact in this article comes from the keyv and cacheable compromise of August 4, 2026. Every network indicator in our write-up pointed at legitimate infrastructure: cloud metadata addresses, github.com, and registry.npmjs.org. An IP or domain blocklist had nothing to block.

What is cyber threat intelligence?

#

Cyber threat intelligence is the same discipline as threat intelligence. The "cyber" prefix separates it from the military and law enforcement intelligence work it borrows its methods from. Practitioners split it by audience:

  • Strategic intelligence is for leadership: which adversaries target your sector, and why. A state-backed group that steals developer credentials changes budget, hiring, and risk decisions.
  • Operational intelligence describes campaigns and adversary behavior, usually in the vocabulary of MITRE ATT&CK. Malicious packages map to technique T1195.002, Compromise Software Supply Chain.
  • Tactical intelligence is machine-readable: indicators of compromise such as hashes, IP addresses, domains, and, for software, package versions.

Threat intelligence comes from four kinds of source. The first is your own telemetry: logs, alerts, and incident findings. The second is commercial vendors. The third is government agencies and sector sharing groups. The fourth is open source intelligence (OSINT), meaning public material such as registry metadata, code repositories, paste sites, and published research. Large vendors run dedicated research teams. Microsoft's team, long branded the Microsoft Threat Intelligence Center (MSTIC), moved to a weather-based naming taxonomy for threat actors in April 2023.

A threat intelligence platform (TIP) is the system that ingests these feeds, deduplicates and scores them, and pushes the result to enforcement points: firewalls, endpoint agents, a SIEM, or a package firewall. The platform is plumbing. A TIP is only as good as the analysis behind each record it carries.

How is threat intelligence shared between organizations?

#

Threat intelligence is shared through three standards: STIX for the data, TAXII for transport, and TLP for handling rules. STIX 2.1 and TAXII 2.1 became OASIS Standards on June 10, 2021 (OASIS).

STIX (Structured Threat Information Expression) models intelligence as JSON objects: indicators, malware, threat actors, campaigns, and the relationships between them. An indicator carries a detection pattern. We generated and validated this STIX 2.1 indicator for the trojanized keyv release with the OASIS stix2 Python library, version 3.0.2:

JSON
{
  "type": "indicator",
  "spec_version": "2.1",
  "id": "indicator--c62e4521-056b-430a-b90c-eab38c51ecf8",
  "created": "2026-11-05T21:47:22.950986Z",
  "modified": "2026-11-05T21:47:22.950986Z",
  "name": "keyv@6.0.0 (npm) trojanized release",
  "indicator_types": ["malicious-activity"],
  "pattern": "[software:name = 'keyv' AND software:version = '6.0.0']",
  "pattern_type": "stix",
  "pattern_version": "2.1",
  "valid_from": "2026-08-04T09:35:00Z"
}

The pattern has a gap. The STIX 2.1 Software object has name, cpe, swid, languages, vendor, and version, and no field for the package ecosystem (stix2 docs). The pattern above matches anything called keyv, whether it came from npm, PyPI, or a vendor installer. STIX was designed around hosts and networks. Package identity gets bolted on through custom properties or a package URL in free text.

TAXII (Trusted Automated Exchange of Intelligence Information) is the HTTPS API that moves STIX objects. A client polls a collection and asks only for objects it has not seen:

HTTP
GET /api1/collections/91a7b528-80eb-42ed-a74d-c6fbd5a26116/objects/?added_after=2026-08-04T09:35:00Z HTTP/1.1
Host: taxii.example.com
Accept: application/taxii+json;version=2.1

The added_after filter keys on when the server added an object, not on any timestamp inside it. That distinction matters later in this article. TAXII 2.1 reserves keywords for publish-subscribe Channels but does not specify them, so in practice consumers poll.

TLP (Traffic Light Protocol) tells recipients how far they may pass a report along. FIRST's TLP 2.0, authoritative since August 2022, defines five labels (FIRST):

LabelWho may receive it
TLP:REDOnly the named individual recipients
TLP:AMBER+STRICTThe recipient's own organization
TLP:AMBERThe recipient's organization and its clients, on a need-to-know basis
TLP:GREENPeers and partners in the community, not public channels
TLP:CLEARAnyone, including the public

TLP 2.0 renamed TLP:WHITE to TLP:CLEAR, but the predefined markings in STIX 2.1 still use the 1.0 names. The reference stix2 library ships TLP_WHITE and has no TLP_CLEAR. FIRST is explicit that "TLP is not a formal classification scheme." Nothing enforces a TLP label except the recipient's discipline.

Why do IP and domain indicators fail against malicious packages?

#

IP and domain indicators fail against malicious packages because package malware rarely needs attacker-owned infrastructure that a defender could block. David Bianco's Pyramid of Pain, published in March 2013, ranks indicator types by "how much pain it will cause them when you are able to deny those indicators to them" (Bianco). Hash values sit at the bottom, because a tiny change "results in a completely different and unrelated hash value." IP addresses, domains, host artifacts, tools, and tactics, techniques, and procedures (TTPs) sit above them, in rising order of attacker cost.

Apply the pyramid to the keyv and cacheable compromise. A compromised maintainer account published keyv@6.0.0 with a preinstall hook that downloaded a standalone Bun runtime, ran an obfuscated credential stealer, and republished trojanized versions of other packages the stolen npm token could reach (Socket). The tradecraft closely matched Shai-Hulud, the self-propagating npm worm first seen in September 2025. These are the network indicators from our write-up:

Plain text
169[.]254[.]169[.]254
169[.]254[.]170[.]2
github[.]com/oven-sh/bun/releases/download/bun-v1.3.13/
registry[.]npmjs[.]org/-/whoami
registry[.]npmjs[.]org/-/npm/v1/tokens
registry[.]npmjs[.]org/-/npm/v1/oidc/token/exchange/package/

Every indicator on that list is legitimate infrastructure. The first two are the AWS instance metadata endpoint and the ECS credential endpoint. The rest are GitHub release downloads and the npm registry's own API. Exfiltration went to attacker-created GitHub repositories and to destinations resolved over DNS, so no fixed command-and-control host existed. A firewall rule against any of these breaks your own CI long before it inconveniences the attacker.

Indicatorkeyv campaign exampleUsefulness to a defender
Tarball hashsha512 of keyv-6.0.0.tgzExact but brittle. The payload recomputes integrity fields for every package it republishes, so each tarball hash is new.
File hashSHA-256 of setup.mjs and Math_Symbol.jsGood for hunting on disk after the fact. One edit to the loader defeats it.
IP address169.254.169.254 (cloud metadata)None. It is the victim's own cloud service.
Domaingithub.com, registry.npmjs.orgNone. Blocking them blocks development.
Package versionkeyv@6.0.0, file-entry-cache@11.1.6High. Every trojanized version is a public registry event that can be analyzed before anyone installs it.
Behavior (TTP)Install hook fetches a second runtime, reads cloud credentials, republishes packagesHighest. The attack cannot work without it.

The Pyramid of Pain has no row for package versions, so we added one. For open source, the package version is the tactical indicator that maps one-to-one onto what a package manager resolves. The durable signal is behavior, found by analyzing what the package does at install time rather than trusting its metadata.

What threat intelligence for open source packages looks like

#

Open source threat intelligence centers on package records, not network indicators. Malware does not get a CVE, and the National Vulnerability Database does not track malicious packages. Our CEO argued on the Risky Business podcast that this missing database is a central gap in open source malware tracking. The closest shared substitute is the OpenSSF malicious-packages repository, which publishes reports in the OSV format under MAL- identifiers.

This is the record for keyv@6.0.0, trimmed to the fields a consumer acts on. The full file is MAL-2026-11524:

JSON
{
  "schema_version": "1.7.4",
  "id": "MAL-2026-11524",
  "published": "2026-08-04T11:19:14Z",
  "aliases": ["GHSA-3p9h-f68w-m6fx"],
  "summary": "Malicious code in keyv (npm)",
  "affected": [{
    "package": { "name": "keyv", "ecosystem": "npm" },
    "versions": ["6.0.0"],
    "database_specific": {
      "cwes": [{ "cweId": "CWE-506", "name": "Embedded Malicious Code" }],
      "indicators": {
        "evidence_files": [
          { "path": "setup.mjs", "sha256": "54dc7ea54a1317cca0e890a2770630cf7fa6c97813e0cb9d2caa93012b350668" },
          { "path": "Math_Symbol.js", "sha256": "9fc2570b7cef51c1b8df116d144d11ff4096357be7d2c4c6367cfc2509cf1bcc" }
        ],
        "package_integrity": [{
          "filename": "keyv-6.0.0.tgz",
          "hashes": { "sha512_sri": "sha512-N/n4R+nD5SC0fYOpAp4ZnbwwxqGVodgEZ9D7Gm/VBocorU0aQimVyleDWSY6/axdO0/temub760n3hnMppZpUg==" }
        }]
      }
    }
  }],
  "database_specific": {
    "malicious-packages-origins": [
      { "source": "amazon-inspector", "import_time": "2026-08-04T21:33:11.726128238Z" },
      { "source": "ghsa-malware", "import_time": "2026-08-05T00:10:17.860265883Z" }
    ]
  }
}

Three fields make this record more useful than the STIX indicator. The ecosystem, name, and versions triple is an exact key, the same one a package manager resolves. The sha512_sri value uses the same Subresource Integrity format npm writes into the integrity field of package-lock.json, so a lockfile can be matched against it with a string comparison. And the evidence is a pair of files inside the tarball, not an IP address.

PropertySTIX 2.1 indicatorOSV malicious-package record
Identity keySoftware name and version, no ecosystemEcosystem, name, and exact versions
Lockfile matchingNo native integrity fieldsha512_sri matches npm integrity values
ContextRich: actors, campaigns, ATT&CK techniques, relationshipsFree-text details and aliases only
TransportTAXII 2.1 collectionsA Git repository and the OSV API
Handling rulesTLP markings built inNone; records are public
Best forJoining a package compromise to a wider incident in a SIEM or TIPGating installs and scanning dependency trees

Our verdict: use OSV-format package records to gate installs and match lockfiles, because their identity key is the one your package manager uses. Use STIX when a package compromise has to join a broader investigation with actors, infrastructure, and host telemetry. Translate OSV records into STIX at that boundary, not the other way around.

How fast does threat intelligence reach defenders?

#

Threat intelligence about a malicious package reaches most defenders hours after the package can already run. We reconstructed the keyv@6.0.0 timeline from the npm registry's publish timestamps, our published detection timing, and the origin metadata inside the OSV record.

keyv@6.0.0: time after publish (09:35 UTC, Aug 4, 2026)1m10m1h6h24hSocket flags keyv@6.0.0 as malware~6 minAttacker publishes cacheable family~35 minGitHub advisory GHSA-3p9h-f68w-m6fx1 h 44 minFirst report imported into OpenSSF malicious-packages11 h 58 minGHSA report imported into OSV repo14 h 35 minLog scale. Hatched bar = attacker activity.Sources: npm registry, Socket, OSV MAL-2026-11524.
Time (UTC)ElapsedEventSource
Aug 4, 09:35:000keyv@6.0.0 published with the malicious preinstall hooknpm registry time field
Aug 4, ~09:41~6 minSocket flags the hook as malwareSocket write-up
Aug 4, 10:09 to 10:14~35 minAttacker publishes nine trojanized cacheable-family packagesSocket write-up
Aug 4, 11:191 h 44 minGitHub advisory GHSA-3p9h-f68w-m6fx timestampedOSV record origins
Aug 4, 21:3311 h 58 minFirst source report imported into OpenSSF malicious-packagesOSV record origins
Aug 5, 00:1014 h 35 minGitHub advisory report imported into the same repositoryOSV record origins

Across the campaign, Socket detected affected artifacts an average of 5 minutes and 18 seconds after publication (Socket). The attacker had spread to a second package family before the first public advisory existed.

The OSV record exposes a subtler problem. Its published field says 11:19 UTC, but its origin metadata shows the first source report reached the repository at 21:33 UTC. A consumer syncing that repository could not have seen the record for roughly ten hours after its own published timestamp. A feed timestamp records when something was true, not when you could have known it. Any retro-hunt that asks for "malware published since my last sync" will miss records that arrive backdated. TAXII's added_after avoids that trap by keying on server arrival time.

You can check what the registry still remembers. npm no longer serves keyv@6.0.0, but it kept the version's publish timestamp:

Shell Session
$ curl -s https://registry.npmjs.org/keyv \
    | jq '{published: .time["6.0.0"], still_served: (.versions | has("6.0.0"))}'
{
  "published": "2026-08-04T09:35:00.763Z",
  "still_served": false
}
$ curl -s https://registry.npmjs.org/keyv/6.0.0
"version not found: 6.0.0"

As of November 2026, the same check on file-entry-cache returns a publish time of 10:13:02 UTC for version 11.1.6 and still_served: false. Once a malicious version is gone, intelligence about it can only answer a retrospective question: were we hit?

Bad threat intelligence breaks builds

#

False positives in threat intelligence are outages when feeds drive enforcement. On May 26, 2026, OSV withdrew 157 malware reports after automated detections flagged legitimate npm and PyPI packages, including FastAPI 0.136.3. The FastAPI record called a new dependency "typosquat-shaped" but identified no payload, no install-time execution, and no exfiltration. Many of the withdrawn records traced to Amazon Inspector, which OpenSSF had added as an automated source in October 2025.

Malware verdicts carry more operational weight than vulnerability advisories. A vulnerability alert can be triaged by version range and reachability. A malware alert triggers blocked builds, emergency package removal, and credential rotation. When an enforcement point trusts a feed blindly, a wrong record becomes a self-inflicted incident for every consumer at once.

We draw two rules from this. Confidence has to travel with every record, and the evidence has to be inspectable. A record that says "malicious" without naming the file and the behavior should not gate a build on its own. Socket's Threat Feed API exposes this split directly: its is_human_reviewed filter returns only records that no longer need human validation (changelog). Human review costs time, so blocking on unreviewed machine verdicts and blocking on reviewed ones are separate policy decisions with different failure modes. Teams should make that choice explicitly rather than inherit a vendor default.

Where threat intelligence should be enforced

#

Package threat intelligence should be enforced at install, because the install is when the payload runs. The keyv@6.0.0 preinstall hook executed before any project code, and the package's library code was byte-identical by SHA-256 to the clean release candidate. Nothing downstream of the install would have looked wrong. A package firewall checks each package request against known malicious packages and blocks it before download. That only works if the verdict exists within minutes of publication, which is why we derive verdicts from analyzing package contents at publish time instead of waiting for downstream reports.

Retrospective hunting is the fallback, and it is weaker than it looks. Matching MAL records against lockfiles finds packages installed into tracked projects. It misses code fetched by npx, global installs, and ephemeral CI jobs, none of which leave a project lockfile behind. The axios compromise showed the limit. As our analysis of its blast radius put it, "The absence of evidence after the fact is not strong evidence of absence." A clean lockfile does not prove you were safe. Socket's Threat Intel campaigns view answers "were we hit?" from install-time evidence instead, showing whether each campaign package was blocked by Socket Firewall or detected in scans, with links to the specific events.

Package provenance does not substitute for threat intelligence. keyv@6.0.0 shipped with a valid, signed provenance attestation, because the legitimate release workflow built source the attacker had already trojanized. Provenance correctly answered "was this built by the expected pipeline?" It could not answer "is this code malicious?"

The open problem is a source of truth. Open source has no authoritative database for malicious packages that is both fast and careful. OSV is open and structured, but May 26 showed it is only as reliable as its automated sources, and its import times can trail an attack by half a day. Vendor feeds can be faster, but they are proprietary. Until that changes, every team consuming package threat intelligence is choosing between being late and being wrong, and its install policy should say which one it prefers.