---
id: "MAL-2026-17199"
kind: "package"
aliases: ["MAL-2026-17199"]
title: "Malicious code in scrapetools2 (PyPI)"
severity: "critical"
cvss: null
epss: null
exploited: false
status: "open"
category: "package"
products: [{"name": "scrapetools2", "fixed": [], "affected": "= 1.2.1; = 1.2.0; = 0.2.0; = 0.2.1", "ecosystem": "pypi"}]
ecosystems: ["pypi"]
tags: ["malicious", "package"]
not_affected_if: []
published_at: "2026-09-27T14:33:48+00:00"
first_seen_at: "2026-10-26T20:51:58+00:00"
updated_at: "2026-10-26T21:08:21+00:00"
sources: [{"source": "osv-malicious", "url": "https://osv.dev/vulnerability/MAL-2026-17199", "first_seen_at": "2026-10-26T20:51:58+00:00"}]
---

# Malicious code in scrapetools2 (PyPI)

## Affected

- pypi:scrapetools2 affected = 1.2.1; = 1.2.0; = 0.2.0; = 0.2.1 fixed ?

## Timeline

- 2026-10-26T20:51:58+00:00 osv-malicious https://osv.dev/vulnerability/MAL-2026-17199

## From the sources

---
_-= Per source details. Do not edit below this line.=-_

## Source: amazon-inspector (44124d389269a5e4dc8801d3af1afeb08aee57313fcc7082570c5890e7d89233)
scrapetools2 1.2.1 ships an auto-update mechanism in downloader.py that fetches tar.gz payloads from public IPFS gateways (eu.orbitor.dev, dget.top, ipfs.filebase.io) at the author-controlled IPNS name k51qzi5uqu5dmh5178x8jzdkz8u3k3qona4zrwlvdr6865it3901l1oe8emjwc, decrypts an 'updates' entry using a Fernet key bundled inside the package (scrapetools2/versions), writes each decrypted blob to scrapetools2/modules/N.py, and then compile()+exec()s them in-process. The updater is invoked via runtime.DBConsumer.startQueue -> updater() and loops on a 60-second interval, so any code path that reaches the advertised RuntimeSite/browser-pool flow triggers the fetch-and-execute cycle. The package additionally ships an encrypted 'updates' blob decrypted by packer.unpackdata into a JSON {"cmd":...} whose contents are written to modules/*.py and exec'd by run_modules(); the executed source is not visible in the sdist without the bundled key. Because IPNS is a mutable pointer under the holder's control and the only integrity check is a Fernet key shipped with the package, whoever controls the IPNS name can push arbitrary Python that will be executed on installer hosts.

---

_Free to read at a human pace. An API with keys and an MCP server are in preparation; early access: hello@infrastack.ai_
