# Malicious Package Supply Chain Tracker Scraper (`jungle_synthesizer/malicious-package-supply-chain-tracker-scraper`) Actor

Cross-ecosystem feed of confirmed malicious/typosquatted packages across npm, PyPI, crates.io, Go, Maven, NuGet, Packagist and RubyGems, sourced from the OSSF malicious-packages dataset (also feeds OSV.dev). Category taxonomy plus typosquat-target linkage for CI gating. Passive read only.

- **URL**: https://apify.com/jungle\_synthesizer/malicious-package-supply-chain-tracker-scraper.md
- **Developed by:** [BowTiedRaccoon](https://apify.com/jungle_synthesizer) (community)
- **Categories:** Developer tools, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Malicious Package Supply Chain Tracker Scraper

Track confirmed malicious and typosquatted packages from the [OSSF malicious-packages dataset](https://github.com/ossf/malicious-packages), the canonical upstream that also feeds OSV.dev's MAL-\* advisories. Returns normalized records across npm, PyPI, crates.io, Go, Maven, NuGet, Packagist, and RubyGems — over 230,000 confirmed-malicious advisories, growing daily.

***

### Malicious Package Supply Chain Tracker Scraper Features

- Unions confirmed malicious/typosquatted package advisories across 8 ecosystems into one schema
- Classifies each record into a category taxonomy — malware, typosquat, dependency confusion, protestware, compromised — instead of leaving you to parse free-text summaries
- Extracts the legitimate package name a malicious one imitates, when the advisory text states it
- Pure HTTP data read — no browser, no proxy, no anti-bot dance
- Round-robins across whichever ecosystems you select, so a small `maxItems` still samples every ecosystem you asked for instead of exhausting npm alone (npm outnumbers every other ecosystem combined)
- Ships a delta mode that returns only advisories new since your last run, for continuous CI-gating feeds
- Never downloads, installs, or executes any package artifact — reads published advisory metadata only

***

### Who Uses Malicious Package Data?

- **AppSec engineers** — gate CI pipelines against confirmed-malicious packages before they land in a lockfile
- **SCA tool builders** — enrich existing vulnerability feeds with a cross-ecosystem malicious-package layer most single-ecosystem tools skip
- **Security researchers** — track typosquat campaigns and dependency-confusion waves across npm and PyPI without stitching together five different feeds
- **Platform teams** — feed a denylist into an internal package proxy or registry mirror
- **Threat intel analysts** — monitor the daily delta for new campaign activity, or at least know when someone starts squatting on your package name

***

### How It Works

1. Pick the ecosystems you care about (npm and PyPI by default) and a `maxItems` cap.
2. The scraper reads the OSSF malicious-packages dataset and normalizes each advisory — package name, category, affected versions, references — into one consistent schema.
3. Records come back round-robin across your selected ecosystems, so a 20-item run with `["npm", "pypi", "rubygems"]` gives you a mix of all three, not 20 npm rows.
4. Switch to `mode: "delta"` on a scheduled run and get only the advisories added since the last delta run — the actor remembers what it already sent you.

***

### Input

```json
{
  "ecosystems": ["npm", "pypi"],
  "mode": "full",
  "maxItems": 100
}
```

| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `ecosystems` | array | `["npm", "pypi"]` | Ecosystems to include: `npm`, `pypi`, `crates.io`, `go`, `maven`, `nuget`, `packagist`, `rubygems` |
| `mode` | string | `full` | `full` returns the matching corpus each run. `delta` returns only advisories new since your last delta run on this actor |
| `maxItems` | integer | `100` | Maximum number of records to return |

#### Delta mode example

```json
{
  "ecosystems": ["npm", "pypi", "rubygems"],
  "mode": "delta",
  "maxItems": 500
}
```

Run this on a schedule and each run only returns advisories the actor hasn't handed you before. First run behaves like `full` mode since nothing has been seen yet.

***

### Malicious Package Supply Chain Tracker Scraper Output Fields

```json
{
  "package_name": "acloud-client",
  "ecosystem": "PyPI",
  "malicious_id": "MAL-2025-2929",
  "category": "malware",
  "typosquat_of": null,
  "affected_versions": ["1.0.0", "1.0.1"],
  "summary": "Malicious code in acloud-client (PyPI)",
  "details": "Clones of the legit aliyun-python-sdk-core package that exfiltrate cloud credentials...",
  "published": "2025-02-25T18:18:21Z",
  "modified": "2026-03-19T12:23:25Z",
  "source_dataset": "ossf",
  "references": ["https://security.snyk.io/vuln/SNYK-PYTHON-ACLOUDCLIENT-12201342"],
  "severity": null,
  "withdrawn": false,
  "scraped_at": "2026-07-13T09:49:11.135Z"
}
```

| Field | Type | Description |
|-------|------|--------------|
| `package_name` | string | Name of the affected package as published to the ecosystem registry |
| `ecosystem` | string | `npm`, `PyPI`, `crates.io`, `Go`, `Maven`, `NuGet`, `Packagist`, or `RubyGems` |
| `malicious_id` | string | OSV/OSSF advisory id (e.g. `MAL-2024-1677`) |
| `category` | string | `malware`, `typosquat`, `dependency_confusion`, `protestware`, `compromised`, or `pentest` |
| `typosquat_of` | string | null | Legitimate package name this one appears to imitate, when the advisory text says so — never guessed |
| `affected_versions` | array | Affected version strings |
| `summary` | string | One-line advisory summary |
| `details` | string | Full advisory details / analyst notes |
| `published` | string | ISO 8601 timestamp the advisory was first published |
| `modified` | string | ISO 8601 timestamp the advisory was last modified |
| `source_dataset` | string | Origin dataset tag — currently always `ossf` |
| `references` | array | Reference URLs and finder credit links |
| `severity` | string | null | Severity if present in the source advisory — most malicious-package records don't carry a CVSS score, so this is usually null |
| `withdrawn` | boolean | `true` if the advisory carries a withdrawn timestamp (retracted) |
| `scraped_at` | string | ISO 8601 timestamp this actor run captured the record |

***

### FAQ

#### How do I scrape confirmed malicious npm and PyPI packages?

Malicious Package Supply Chain Tracker Scraper does it in one input field. Set `ecosystems: ["npm", "pypi"]`, pick a `maxItems`, and run — you get normalized records with category classification and typosquat linkage, not raw advisory JSON you have to parse yourself.

#### How much does Malicious Package Supply Chain Tracker Scraper cost to run?

Standard per-record PPE pricing — you pay for records returned, not for the dataset download underneath. There's no proxy or browser cost baked in, since this is a plain HTTP read.

#### What data can I get on malicious packages?

Package name, ecosystem, advisory id, category (malware, typosquat, dependency confusion, protestware, compromised), affected versions, references, and — when the advisory text states it — the legitimate package a malicious one is impersonating.

#### Can I filter by ecosystem?

Yes. The `ecosystems` array accepts any combination of npm, PyPI, crates.io, Go, Maven, NuGet, Packagist, and RubyGems. Results round-robin across whatever you select.

#### Does Malicious Package Supply Chain Tracker Scraper need proxies?

No. It reads a publicly published dataset over plain HTTPS. No proxy, no browser, no anti-bot handling required.

#### Will this actor download or run any malicious package?

No. It reads advisory metadata only — package names, versions, summaries, references. It never fetches, installs, or executes a package artifact from any registry.

***

### Need More Features?

Need additional ecosystems, a different category taxonomy, or campaign-level grouping? [File an issue](https://console.apify.com/actors/issues) or get in touch.

### Why Use Malicious Package Supply Chain Tracker Scraper?

- **Cross-ecosystem** — one schema across 8 package registries, where most competitors cover a single ecosystem or generic advisories
- **Classified, not raw** — category taxonomy and typosquat-target linkage extracted for you, so you're not regex-ing advisory text at 2am
- **Built for CI** — delta mode returns only what's new since your last run, which is the shape a gating pipeline actually wants

# Actor input Schema

## `sp_intended_usage` (type: `string`):

Please describe how you plan to use the data extracted by this crawler.

## `sp_improvement_suggestions` (type: `string`):

Provide any feedback or suggestions for improvements.

## `sp_contact` (type: `string`):

Provide your email address so we can get in touch with you.

## `ecosystems` (type: `array`):

Package ecosystems to include. Defaults to npm + PyPI. Values correspond to the OSSF malicious-packages dataset's ecosystem directories.

## `mode` (type: `string`):

"full" returns the full matching corpus each run (bounded by Max Items). "delta" returns only records new since the last successful "delta" run on this actor (KV-persisted cursor of seen malicious IDs) — use for continuous CI-gating feeds.

## `maxItems` (type: `integer`):

Maximum number of malicious-package records to return.

## Actor input object example

```json
{
  "sp_intended_usage": "Describe your intended use...",
  "sp_improvement_suggestions": "Share your suggestions here...",
  "sp_contact": "Share your email here...",
  "ecosystems": [
    "npm",
    "pypi"
  ],
  "mode": "full",
  "maxItems": 100
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "sp_intended_usage": "Describe your intended use...",
    "sp_improvement_suggestions": "Share your suggestions here...",
    "sp_contact": "Share your email here...",
    "ecosystems": [
        "npm",
        "pypi"
    ],
    "mode": "full",
    "maxItems": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("jungle_synthesizer/malicious-package-supply-chain-tracker-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "sp_intended_usage": "Describe your intended use...",
    "sp_improvement_suggestions": "Share your suggestions here...",
    "sp_contact": "Share your email here...",
    "ecosystems": [
        "npm",
        "pypi",
    ],
    "mode": "full",
    "maxItems": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("jungle_synthesizer/malicious-package-supply-chain-tracker-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "sp_intended_usage": "Describe your intended use...",
  "sp_improvement_suggestions": "Share your suggestions here...",
  "sp_contact": "Share your email here...",
  "ecosystems": [
    "npm",
    "pypi"
  ],
  "mode": "full",
  "maxItems": 100
}' |
apify call jungle_synthesizer/malicious-package-supply-chain-tracker-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=jungle_synthesizer/malicious-package-supply-chain-tracker-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/U8qAep5Q1VQOw2cZ5/builds/f91jaetPAcsQs7ypl/openapi.json
