---
id: "MAL-2026-18301"
kind: "package"
aliases: ["MAL-2026-18301"]
title: "Malicious code in dictmerge-lite (PyPI)"
severity: "critical"
cvss: null
epss: null
exploited: false
status: "open"
category: "package"
products: [{"name": "dictmerge-lite", "fixed": [], "affected": "= 1.0.0", "ecosystem": "pypi"}]
ecosystems: ["pypi"]
tags: ["malicious", "package"]
not_affected_if: []
published_at: "2026-10-26T00:00:52+00:00"
first_seen_at: "2026-10-26T20:52:03+00:00"
updated_at: "2026-10-26T21:05:48+00:00"
sources: [{"source": "osv-malicious", "url": "https://osv.dev/vulnerability/MAL-2026-18301", "first_seen_at": "2026-10-26T20:52:03+00:00"}]
---

# Malicious code in dictmerge-lite (PyPI)

## Affected

- pypi:dictmerge-lite affected = 1.0.0 fixed ?

## Timeline

- 2026-10-26T20:52:03+00:00 osv-malicious https://osv.dev/vulnerability/MAL-2026-18301

## From the sources

dictmerge-lite 1.0.0, uploaded to PyPI on 2026-10-25 at 23:52 UTC, poses as a small recursive dictionary merge helper and is a credential and crypto-wallet stealer. Importing the package runs the payload: `dictmerge_lite/__init__.py` imports `_telemetry` and starts `_telemetry.run_async()`, a non-daemon thread so the upload completes even when the importing process exits at once. `setup.py` also overrides setuptools' `build_py` and `install` commands to call `_telemetry.run()`, so builds from the source distribution can trigger it too. All errors are swallowed.

`dictmerge_lite/_telemetry.py`, which calls itself a "dependency telemetry collector", collects SSH keys and config, AWS, Google Cloud and Azure credentials, .npmrc, .pypirc, .git-credentials, .gitconfig, .netrc, .pgpass, .my.cnf, Kubernetes and Docker configs, the GitHub CLI token, bash/zsh/Python/Node/psql/mysql histories, Chrome/Chromium/Brave/Edge/Opera `Login Data` and `Web Data`, Firefox `logins.json`/`key4.db`/`cert9.db`, the extension storage of eight crypto wallets (MetaMask, Phantom, Rabby, Keplr, TronLink, Coinbase Wallet, Trust Wallet, Solflare), and any .env, secrets.*, credentials.json, service-account*.json, *.pem, *.key, *.p12, *.pfx or private key file up to three directories below the working directory and the home directory. It gzips the bundle with host details, encrypts it with AES-GCM when `cryptography` is installed, signs it with HMAC-SHA256 and POSTs it to https://svbonlinebanking.com/v1/beacon with `x-dw-campaign`, `x-dw-ts`, `x-dw-sig` and `x-dw-enc` headers. It runs on Linux, macOS and Windows, writes a /tmp/.dw-<fingerprint> marker that suppresses a rerun for 15 minutes, and does nothing when DW_OFF=1 is set or ~/.dw_off exists.

Bitbison caught the release stealing credentials at 23:55:36 UTC, 3 minutes 20 seconds after publication: on import the payload read credential files and uploaded them to svbonlinebanking.com (209.99.190.173) within 0.45 seconds. Any environment that imported or built 1.0.0 should be treated as compromised: rotate its credentials, change saved browser passwords and move funds out of any wallet whose extension data was present.

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

## Source: kam193 (86ffa17e6ebc93b9c0509a6f6ec0f11a17bc79eec75d4fecf0f0b9520c3b93c5)
During installation or import, the package executes infostealer code and exfiltrates cryptocurrency wallet, browsers' data, SSH keys and development credential files.


---

Category: MALICIOUS - The campaign has clearly malicious intent, like infostealers.


Campaign: 2026-10-dictmerge-lite


Reasons (based on the campaign):


 - infostealer


 - exfiltration-crypto


 - exfiltration-browser-data


 - The package overrides the install command in setup.py to execute malicious code during installation.


 - exfiltration-ssh-keys


 - exfiltration-credentials

---

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