cd /news/ai-safety/i-caught-a-trojan-in-my-mcp-marketpl… Β· home β€Ί topics β€Ί ai-safety β€Ί article
[ARTICLE Β· art-64332] src=dev.to β†— pub= topic=ai-safety verified=true sentiment=↓ negative

I caught a trojan in my MCP marketplace. Here's the 8-layer defense I built.

A developer discovered a Windows trojan, Trojan:Win64/Lazy.PGPK!MTB, hidden in a typosquatting MCP server package on their marketplace. In response, they built an 8-layer defense pipeline that includes recursive zip scanning, YARA rules for 17 malware families, and HTTP request inspection to prevent future incidents.

read4 min views1 publishedJul 18, 2026

Two weeks ago, a Windows trojan slipped into my MCP (Model Context Protocol) marketplace. The malware was Trojan:Win64/Lazy.PGPK!MTB

, hidden inside a nested zip in a skill package.

This is the technical writeup of what happened, what I built to prevent it, and the architecture of the 8-layer defense pipeline now running in production.

Vector: Typosquatting GitHub repository

A legitimate MCP server prospector-mcp-email-finder

existed. An attacker created a typosquatting copy at JuanquiFortuny/prospector-mcp-email-finder

(now taken down) with an identical README β€” but with a "Download Latest Release" badge linking to a malicious zip on raw.githubusercontent.com

.

The payload:

Application.cmd  β†’  'start unit.exe package.txt'
package.txt      β†’  298 KB of obfuscated Lua bytecode
unit.exe         β†’  872 KB PE32+ Windows executable

Windows Defender flagged unit.exe

as Trojan:Win64/Lazy.PGPK!MTB

. The Application.cmd β†’ unit.exe + package.txt

pattern is a classic staged launcher β€” small CMD wrapper executes the binary with the bytecode payload as input.

How it got in: My import script (which fetches MCP servers from GitHub) downloaded the zip and committed it to dist/skills/

without scanning inside it. My existing audit pipeline (Sentinel L1.5 + L1.6) only checked skill metadata β€” name, description, system_prompt. It never looked inside the actual package.

Cheapest layer. Runs on every skill's metadata:

ignore previous instructions

)Access-Control-Allow-Origin: *

(warning)18 Semgrep-equivalent rules implemented as JS regex (no Semgrep binary needed):

18 secret detection patterns:

sk_live_*

, sk_test_*

)ghp_*

, gho_*

, ghs_*

)AKIA*

, aws_secret_access_key

)OSV API for known vulnerable dependencies.

Bug fix (from peer review): process.env.X

references were triggering MCP-SL-001 (hardcoded API key). Fixed by stripping process.env.*

patterns before running secret detection.

This is the layer I built after the trojan incident. It opens the package zip (recursively β€” zips inside zips) and scans for:

const BINARY_EXTENSIONS = ['.exe', '.dll', '.scr', '.msi'];
const LAUNCHER_EXTENSIONS = ['.bat', '.cmd', '.vbs', '.ps1'];

Plus 8 regex patterns for:

start X.exe Y.txt

(the exact prospector signature)function(o,R,F,U,b,p,E,M,Z,W,...)

(high-arity function signature)raw.githubusercontent.com/.../...zip

-encodedcommand

with long base64eval(atob(...))

obfuscationQuarantine flow: Any critical finding β†’ score 0, risk_level critical

, status quarantined

, removed from catalog, listed at /api/security?view=quarantine

.

YARA-equivalent rules for specific malware families, each with MITRE ATT&CK technique IDs:

Family MITRE What it does
Win64/Lazy.PGPK T1027.002 The trojan that hit us
Emotet T1027.011 Banking trojan, Office macro delivery
Cobalt Strike T1071.001 Post-exploitation beacon
Mimikatz T1003.001 LSASS credential dumper
QakBot T1027 Banking trojan
TrickBot T1027 Modular trojan, ransomware precursor
Agent Tesla T1056.001 Keylogger
RedLine Stealer T1555 Browser credential theft
Vidar Stealer T1555 Browser + crypto wallet theft
Raccoon Stealer T1555 MaaS stealer
LummaC2 Stealer T1555 Telegram-sold stealer
AsyncRAT T1071.001 Open-source RAT
njRAT T1071.001 .NET RAT
Remcos RAT T1071.001 Commercial RAT
SolarMarker T1027 SEO-poisoned backdoor
Lokibot T1555 Credential stealer
DoS tools T1499 hping3, slowloris, goldeneye

Any match β†’ instant quarantine.

Inspects every incoming HTTP request:

SQLi (7): UNION SELECT, OR 1=1, stacked, time-based, info_schema, hex
XSS (7): script, event handlers, javascript:, data:, vbscript:, img/svg
Path traversal (5): ../, encoded, /etc/passwd, /proc/self, Windows
SSRF (6): AWS/GCP/Azure metadata, file://, gopher://, dict://
Command injection (5): backticks, $(), chained, pipe, && ||
NoSQL (3): $where, $ne, $gt
Prototype pollution: __proto__, constructor.prototype
SSTI: Jinja2 {{ }}, Twig {% %}, JS ${ }
Log injection: \n \r header injection

Auto-ban after 5 WAF hits in 10 minutes (1-hour ban).

Fake vulnerable paths that auto-ban scanners for 24 hours:

/.env

β†’ serves fake env file with canary tokens/admin

β†’ fake admin login form/wp-admin

β†’ fake WordPress login/.git/config

β†’ fake git config/.aws/credentials

β†’ fake AWS credentials/.ssh/id_rsa

β†’ fake SSH key/phpmyadmin

, /backup.sql

, /server-status

, /.DS_Store

, etc.Each hit: IP banned 24h + logged publicly at /api/security?view=honeypot

.

Real-time IOC feeds from abuse.ch (free, no API key):

Used to check skill source URLs and file hashes.

If any layer flags a skill as critical/high:

_data/quarantine/

/api/security?view=quarantine

for transparencyRe-audited all 7,063 skills with the 8 layers. 0 in quarantine. The catalog was clean except for the one we already removed.

Request β†’ Honeypot check β†’ WAF (40 rules) β†’ Handler
                                          ↓
Skill import β†’ L1.5 (6) β†’ L1.6 (36) β†’ L1.7 (8) β†’ L1.8 (17) β†’ Quarantine?
                                                                ↓ no
                                                          Catalog (public)
                                                                ↓ yes
                                                          _data/quarantine/
                                                          (publicly listed)

Stack: Vercel Hobby ($0/mo), GitHub Actions (free), Docker + gVisor for L2 sandbox, abuse.ch feeds.

β€” Edison Flores, AliceLabs LLC

── more in #ai-safety 4 stories Β· sorted by recency
── more on @mcp marketplace 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain β€” perfect for shipping the agent you just read about.

$git push zahid main
β†’ Live at https://your-agent.zahid.host βœ“
Get free account β†’ Pricing
from €0/mo Β· no card required
LIVE [news/i-caught-a-trojan-in…] indexed:0 read:4min 2026-07-18 Β· β€”