Open-source project
toxic-repos/toxic-repos avatar
toxic-repos/toxic-repos

toxic-repos: a dataset of packages that shipped protest code

We are against discrediting open source software

634 stars37 forksPythonCC0-1.0

At a glance

What is it?
toxic-repos is a public registry of open source repositories that added code of varying danger to popular projects, published as CSV, JSON and SQLite and updated by community reports. It suits security engineers who want a blocklist source or a CI check for suspicious additions, and it is community maintained data rather than an authoritative feed.
Who is it for?
Use toxic-repos as a source of indicators for a supply chain check, a seed list for keyword and file-diff scanning, or a research dataset, and treat every record as a community report rather than a verified verdict. Do not wire it into a blocking policy without reviewing the records yourself, because the registry is assembled from public reports and a Telegram bot, and the project itself warns that it exists to argue against discrediting open source software.
Can I use it commercially?
Yes. CC0-1.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 81 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A registry of packages that added protest code

The toxic-repos project is a public dataset of open source repositories that added code of varying degrees of danger to popular projects. The premise stated in its documentation is that such cases have become more frequent, that they can pose a threat to people, and that they undermine the credibility of the open source community and of open source as a whole.

The project states its position plainly in its title line: it is against discrediting open source software. That framing matters for how the data should be read. This is a list of repositories that shipped unwanted or dangerous code, gathered so that maintainers and engineers can find them, not a list of projects judged as bad in themselves.

The registry covers both GitHub and npm, which are the two ecosystems where a published package or a popular repository can reach a very large number of machines in a very short time. The primary language of the repository is Python, which is what the scripts/ directory at the root is for, and the data itself is stored in a data/ directory.

The scale is stated in one number: records in the database, more than 800. The website at toxic-repos.ru, a Telegram channel, a Telegram chat and a Telegram bot for submissions make up the surrounding infrastructure, and the CHANGELOG.md tracks changes to the data set.

Three export formats for the same records

The data is published in three formats under the data/ directory, and the choice between them is a practical one for whoever wants to consume it:

- CSV at data/csv/toxic-repos.csv - JSON at data/json/toxic-repos.json - SQLite at data/sqlite/toxic-repos.sqlite3

The SQLite file is the interesting one for automation, because a single file is trivial to ship inside a CI container and trivial to query, with no parser to write. The JSON export suits tools that already read JSON, and the CSV export is the one to reach for when you want to eyeball the data in a spreadsheet or diff two versions of it.

A separate file at the repository root, protestware_IoC.txt, holds indicators of compromise in a plain text form. The release list confirms the intent, since the v.2.1 tag is titled indicators of compromise of protestware. A flat text file of indicators is the easiest thing to grep against and the easiest to diff in a review, and it is the natural input for the keyword scanning the project recommends.

The repository also carries a CHANGELOG.md, which matters for anyone treating the data as a feed. A blocklist is only useful if you know how fresh it is, and the changelog is the place where that is recorded.

Three ways to get a record added

The submission routes are documented, and they are unusual for a repository of this kind.

First, there is a Telegram bot for sending information to be added to the list, and the documentation notes that information about toxic repositories appears even faster in the Telegram chat. Second, there is the GitHub route, since the project asks for pull requests and lists writing to the chat or to the info address as alternatives. Third, there is the HOW-TO-ADD.md file in the repository root, which is the written procedure for adding an entry.

The presence of HOW-TO-REPORT.md alongside HOW-TO-ADD.md separates two different audiences. One document is aimed at maintainers who have found something and need to report it correctly, the other at contributors who want to add an entry to the dataset. That distinction is sensible, because a report about a repository and a curated record in a database are not the same artefact.

A Telegram bot as the primary intake channel is a design decision with consequences. It means the fastest path to a record does not run through the repository's own review process, so a consumer of the data should assume that entries can appear that no maintainer has reviewed in a pull request. The database is closer to a community wire feed than to a curated, reviewed catalogue.

For context, the release history shows a small number of substantive data releases over a long period: v.1.2 with data files on 2023-10-16, v.2.0 in October 2024, and v.2.1 in July 2025.

The recommended defences are CI checks, not a blocklist

The recommendations section is where the project turns from a list into something usable, and it is worth reading closely because it describes detection rather than punishment.

The first recommendation is code isolation in containers, including isolation of intermediate code on developer machines. The second is to fork all libraries, where possible, and the containers themselves, so that your build depends on code you control rather than on an upstream that may change. The third is mirroring package repositories, so that a compromised release never reaches your build.

The fourth is the most concrete and the most directly implementable: include in CI at least a search by keywords, a search for UTF characters together with the image of the Ukrainian flag, and a comparison of the list of files with a whitelist. The third of those is the interesting one, because it is not a keyword list at all. It is a file-level check, and the project is essentially telling you that the protestware pattern of this era is characterised by unexpected new files and by specific non-ASCII content rather than by a suspicious function name.

The fifth recommendation is research on code analysis tools, which is an admission that static analysis is not solved here. The last is to send a report following the instructions in HOW-TO-REPORT.md.

A keyword search alone is weak, and the project knows it, which is why the whitelist comparison and the container isolation come first. The whitelist approach is the one that generalises: knowing exactly which files your dependency should contain means any extra file is a signal, whatever it contains.

What the registry cannot tell you

The limits of this data are worth stating clearly, because a registry of bad incidents is easy to over-read.

First, it is an incident list, not a judgement on projects. The repository's own framing is against discrediting open source software, and a project appearing in the list is a project that shipped something unwanted at some point, which is a different statement from a project being unsafe to depend on. Many entries will have been fixed, and a fixed entry stays in the list because the record of the incident is what matters for scanning historical builds.

Second, coverage is inherently partial. The intake channels are a Telegram bot, a chat, an email address and pull requests, so the registry sees what people notice and report. Popular projects get reported; obscure ones with the same behaviour may not be. Nothing in the documentation claims completeness, and no count of affected installations is given.

Third, the data is only useful for the versions it describes. A package that was clean at 1.2.0 and added code at 1.3.0 produces a signal only if you match the version. Using the registry as a flat list of repository names, without version awareness, produces false positives against every legitimate release of the same project.

Fourth, this is a static snapshot in a git repository. There is no API, no feed mechanism and no schema version documented in the project notes, so consuming it means either vendoring the file or polling the repository, and both put the burden of freshness on you.

CC0 licence, a small release history and a dated last push

The licence is CC0-1.0, a public domain dedication with no attribution requirement and no restrictions on reuse. For a dataset that other tools are expected to embed, that is the correct choice, and it removes any question about licensing a derived blocklist.

On maintenance, the repository is not archived and the last push was on 2026-08-03. The releases are v.1.2 with data files on 2023-10-16, v.2.0 with a database based on 1 October 2024, and v.2.1 as indicators of compromise of protestware on 2025-07-29. So the data set has been refreshed several times, most recently in July 2025, while commits have continued since.

The version numbering is worth noting for anyone automating against it. The tags use a v.2.1 form with a period rather than the usual v2.1.0, and the release titles carry a payload, the database date or the purpose, rather than a conventional changelog summary. That suggests the tags mark data drops rather than software releases, which is consistent with the nature of the project.

The repository also carries a CODE_OF_CONDUCT.md, a .github/ directory and the scripts/ directory that holds the Python tooling for producing the exports. With more than 800 records and a stated purpose of protecting maintainers and their users from surprise code in dependencies, the value of this project is in how quickly you can turn the exports into a check, and in how little you have to trust any single entry to act as a signal rather than a verdict.

Editorial conclusion

Use toxic-repos as a source of indicators for a supply chain check, a seed list for keyword and file-diff scanning, or a research dataset, and treat every record as a community report rather than a verified verdict. Do not wire it into a blocking policy without reviewing the records yourself, because the registry is assembled from public reports and a Telegram bot, and the project itself warns that it exists to argue against discrediting open source software. Before you rely on it, read HOW-TO-REPORT.md and HOW-TO-ADD.md to understand how entries are accepted, check the CHANGELOG.md for the last data update, and confirm that the format of the CSV or JSON export matches what your tooling expects.

Frequently asked questions

What is the toxic-repos project?

It is a public registry of open source repositories that added code of varying degrees of danger to popular projects, covering GitHub and npm. The project states its aim as being against discrediting open source software, and it publishes the records as CSV, JSON and SQLite.

Where can I download the toxic-repos data?

The exports live under the data directory: a CSV at data/csv/toxic-repos.csv, JSON at data/json/toxic-repos.json and a SQLite database at data/sqlite/toxic-repos.sqlite3. Indicators of compromise are additionally provided in a plain text file at the repository root.

How do I report a repository that shipped protest code?

The project provides a HOW-TO-REPORT.md document with the reporting instructions, and it also accepts submissions through a Telegram bot, a Telegram chat and an email address. Adding an entry to the database is a separate process described in HOW-TO-ADD.md.

How can I use toxic-repos in CI?

The recommendations suggest adding at least a keyword search, a search for UTF characters together with the image of the Ukrainian flag, and a comparison of the list of files with a whitelist to your CI. The project also recommends isolating code in containers, forking libraries and containers where possible, and mirroring package repositories.

Official sources

  1. License: CC0-1.0
  2. Project website
  3. README
  4. Releases
  5. toxic-repos/toxic-repos on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/toxic-repos-toxic-repos.svg)](https://hysenlabs.com/projects/toxic-repos-toxic-repos)

Was this useful?