Skip to content
PublishedMalware Analysis · v1.0 · 2 min

Older Malware Still Public on GitHub

Discord token stealers and redistributed errorHandler loaders, with published tools distinguished from victims.

Cristian Chiriac

Published:
2 November 2026
Version:
1.0
Last observed:
30 October 2026
Dataset frozen:
1 November 2026
Collection cut-off:
31 October 2026, 17:59 UTC
Tracked items rechecked:
1 November 2026, 18:23 UTC
Time zone
All dates UTC.
Contents

Two known malware families remain in public code: Discord token stealers and copied errorHandler loaders.

The research in 30 seconds

What I found
Two known malware families remain in public code: Discord token stealers and copied errorHandler loaders.
What this adds
The contribution is the pinned-commit count and the separation of published tools from affected project copies.
Verified scope
202 stealer repositories, 70 copied-loader repositories and one Fernet loader on 30–31 October.
What remains unknown
These are not all live campaigns or confirmed victim infections; functionality was not tested.

The numbers, with their boundaries

Current count

202

Discord stealer repositories

30–31 Oct 2026 · UTC

Counts:
Both a hard-coded webhook with token and code reading local Discord storage; 187 owners.

Current count

70

Copied-loader repositories

30 Oct 2026 · UTC

Counts:
Loader copies outside the operator template set; 68 owners. Do not interpret the stealer set as 202 victims.
Technical detail:Long tables, code and the evidence register are folded; nothing is left out.

Not everything found in this research is a live campaign. 273 repositories carry older, publicly documented malware. Most are Discord token stealers or copies of the errorHandler loader from the fake coding tests; one is a Python loader with an encrypted stage.

  • 202 repositories (187 accounts) hold Discord token stealers. Each contains a hard-coded Discord webhook address with its token and code that reads Discord's local storage. Most are written in Python.
  • 70 repositories (68 accounts) hold an errorHandler-style loader in a controller or bootstrap file. It is the same loader family the Contagious Interview fake job tests use. It sits in copies of those test projects that are not part of the operators' own template set.
  • Both families are public. What this page adds is the count at a pinned commit, and the reasons these sets are kept apart.
  • On 30 October I removed three research datasets that had matched these rules: one of model outputs and two of collected malware samples. They are kept for study and are not infections.
  • On 31 October I added four stealers found by a wider read of lure and tool repositories: a game-cheat DLL source, two copies of one PowerShell grabber and a single-file injector. Later that day my daily searches added 39 more stealers, and a review of the broad-rule matches added one Python loader (see What is not counted).

Nothing was executed. Owners of the loader copies are treated as victims and are not named. Authors of the stealer repositories are not named either.

Where this stands (1 November 2026)

#

The proven set was closed on 1 November 2026 with what had been found up to 31 October 2026, 17:59 UTC; repositories found after that are tracked separately and are not in these figures. The full proof pass at pinned commits ran on 30–31 October. On 1 November 2026, 18:23 UTC a read-only GitHub API recheck covered the 162 repositories, 73 accounts and 12 issues that are tracked one by one (operator repositories, Shai-Hulud accounts, phishing issues), not the whole set.

  • Frozen: 273 repositories under 256 accounts: 202 Discord token stealers, 70 errorHandler copies and 1 Python loader.
  • Nature: published tools and copied loaders, not a campaign; the owners are not treated as victims or as operators.

Key findings

#

Discord token stealers

#
Discord token stealers by file type

202 repositories proven on 30 and 31 October 2026, by the extension of the matched file; 9 files without an extension and 6 other types not shown.

Table view
Discord token stealers by file type
ItemValueNote
Python (.py)148
Java (.java)12
PowerShell (.ps1)7
Batch (.bat)6
JavaScript (.js)5
C# (.cs)4
File name Repositories
main.py 20
token_grabber.py, main.ps1 4 each
token.py, nuker.py, Main.java 3 each
stealer.py, setup.py, Setup.bat and others 2 each or fewer
  • 148 of the 202 files are Python. The rest are Java, PowerShell, batch, JavaScript, C#, .pyw, C++, Rust, one .ets file, one executable and files without an extension.
  • Many file names call them stealers, grabbers or nukers. That suggests malware published as tools, not infections of someone else's project, although I did not check each repository's history. They are counted, but not as compromised accounts.
  • 59 of the first 163 have stars, so people do find and copy them.

Copied errorHandler loaders

#
File name Repositories
userController.js 25
bootstrap.js 11
productController.js, product.js 9 each
errorHandler.js 6
runtimeConfig.js 5

These are back-end files of the Node.js projects used as fake coding tests. The loader evaluates a response from a remote address. Contagious Interview describes the family and the operators' own template repositories. The 70 here are separate copies, none of them forks. Where each copy came from was not traced.

What is not counted

#

A broader first pass also matched these rules:

Rule Repositories
Python remote execution 92
PowerShell dropper 71
BeaverTail-like 11
Python Fernet-encrypted execution 6

The same patterns occur in tests, scanners and legitimate installers. On 31 October I reviewed all 180 with stricter rules fixed before reading. One counts: a Python loader that decrypts a Fernet-encrypted stage. Decrypted statically with the key in the file, the stage downloads and runs code from easylogs[.]fun. It is in the total. The other 179 are tests, scanners, research samples and legitimate installers, and stay out.

Evidence register

#
Expand technical detail · complete record
E-OF-PROOFPinned-commit proof rows

Repository id, owner id, commit, path, git object id and matched rule for 202 stealer, 70 loader and 1 Fernet loader repositories.

Source: GitHub GraphQL, read from an isolated virtual machine · Collected 30 October 2026

Data notes and reconciliation

#
Expand technical detail · complete record
Measure Figures Why they differ
Discord token stealers 159 → 163 → 202 30 Oct proof pass → +4 from a wider read of lure and tool repositories → +39 from re-run searches (31 Oct)
errorHandler copies 70 Unchanged since 30 Oct
Python Fernet loader 0 → 1 Added 31 Oct after static decryption of its stage
Family total / owners 229 / 216 → 233 / 219 → 273 / 256 Sum of the rows above

Defensive checks

#
  1. Never run a "grabber", "nuker" or "token checker" from GitHub. These tools steal from whoever runs them.
  2. In Node.js back ends, look for Function.constructor, new Function( or eval( applied to an HTTP response, in controllers, bootstrap files and error handlers.
  3. If you received a coding test as a repository, read Contagious Interview before running it.

Limitations

#
  • The stealer rule is a code pattern. It does not tell an educational repository from a working one, so some of the 202 may never have worked.
  • The loader copies were not traced back to the test they came from.
  • The 180 broad-rule repositories were reviewed on 31 October from the matched files; only one was counted.

Investigation context

#

This article is part of the GitHub threat investigation. Counts are a snapshot, not evidence that the code ran on a victim's machine. The shared methodology and proof rules explain inclusion, exclusions and the independent re-check.

Claims, evidence and limits

ClaimAssessmentEvidenceLimit
202 Discord token stealers in public repositoriesConfidence: Confirmed malicious
E-OF-PROOFNot stated in the finding
70 copies of the errorHandler loader outside the operators' templatesConfidence: Confirmed malicious
E-OF-PROOFNot stated in the finding

Terms used on this page

pinned commit
A specific commit, identified by its hash, at which a repository was read. Every counted repository was proven at the default-branch commit recorded in the proof pass, so a later change to the repository does not change what was proven.
proof pass
The 30–31 October 2026 re-read of every candidate at a pinned commit under fixed inclusion rules, followed by an independent re-read of a random sample of 555 repositories through a different API.

All terms: glossary.

Corrections & discussion

Found an error, or have evidence that supports or contradicts a finding? Send a correction. Name the section and what you observed.

← All research