惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

F
Fortinet All Blogs
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
有赞技术团队
有赞技术团队
www.infosecurity-magazine.com
www.infosecurity-magazine.com
大猫的无限游戏
大猫的无限游戏
爱范儿
爱范儿
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
T
Threatpost
V
Visual Studio Blog
Apple Machine Learning Research
Apple Machine Learning Research
博客园 - Franky
人人都是产品经理
人人都是产品经理
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
The Cloudflare Blog
N
News and Events Feed by Topic
L
Lohrmann on Cybersecurity
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
酷 壳 – CoolShell
酷 壳 – CoolShell
V
V2EX
AWS News Blog
AWS News Blog
S
SegmentFault 最新的问题
T
Tailwind CSS Blog
Hugging Face - Blog
Hugging Face - Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Spread Privacy
Spread Privacy
J
Java Code Geeks
博客园 - 聂微东
T
Tor Project blog
宝玉的分享
宝玉的分享
博客园 - 叶小钗
Webroot Blog
Webroot Blog
博客园 - 【当耐特】
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
H
Heimdal Security Blog
Y
Y Combinator Blog
T
The Blog of Author Tim Ferriss
MongoDB | Blog
MongoDB | Blog
I
InfoQ
Security Latest
Security Latest
Martin Fowler
Martin Fowler
Hacker News: Ask HN
Hacker News: Ask HN
P
Privacy International News Feed
C
CERT Recently Published Vulnerability Notes
Latest news
Latest news
雷峰网
雷峰网
D
Darknet – Hacking Tools, Hacker News & Cyber Security
C
Cisco Blogs
H
Help Net Security
L
LINUX DO - 最新话题
L
LINUX DO - 热门话题

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python) The Hidden Cost of AI Systems Nobody Talks About. undefined vs undeclared, and how typeof behaves Switching from file-based jobs to NATS/Kafka in Rust without changing code io_uring Adventures: Rust Servers That Love Syscalls Why Agentic AI is Killing the Traditional Database The POUR principles of web accessibility for developers and designers Quantum Neural Network 3D — A Deep Dive into Interactive WebGL Visualization How To Install Caveman In Codex On macOS And Windows Automation Pipeline Reliability: Why Your Workflow Breaks When Nobody Is Watching I Built an 'Open World' AI Coding Agent — It Works From ANY Folder From Freelancing to Product: A Tech Service Company's SaaS Transformation China's AI Giants: Adding Tencent Hunyuan & ByteDance Doubao to AI University (74 Providers) On the Vibe Coders and Their Lies clerk: Auto-Summarize Your Claude Code Sessions AI Weekly — 2026/04/10–04/17 | The Model Lockdown Is Here, but the Toolchain Is the Real Battleground AI 週報 — 2026/04/10–2026/04/17 模型封鎖潮來了,但工具鏈才是真戰場 Maybe this is how Open-Source apps are born... 🚀 Fine-Tune LLMs with LoRA and QLoRA: 2026 Guide tRPC v11 + Next.js App Router: End-to-End Type Safety Without the Boilerplate ShadCN UI in 2026: Why I Stopped Installing Component Libraries and Started Owning My Components SaaS Billing in React Server Components: Stripe + Supabase Without a Single `useEffect` Join our DEV Weekend Challenge — $1,000 in Prizes Across TEN winners! Submissions Due April 20 at 6:59 AM UTC. Implementing FSRS Spaced Repetition in Flutter + Supabase — Adding Memory Science to an AI Learning App "I Texted My Localhost From the Train — Claude Code Fixed the Bug Before I Got Home" I Built a Sales Prep AI and It Went Deeper Than Expected Design to Code #2: One JSON, Eleven Outputs Solving the 100M-Row Problem: A Summary Table Pattern for High-Volume Push Notification Logs Flutter Web With Wasm: What Actually Changes For Developers I Built 50 Royalty-Free Soundtracks for My Side Project in a Weekend Using AI Music Generation The Vibe Coding Security Checklist: 7 Things to Check Before You Ship Stop Letting Googlebot Guess Fix Your React App's SEO Right Desconstruindo o Streaming do LinkedIn: Como Criar um Engine de Extração de Vídeo de Alta Performance com HLS e FFmpeg (EDA Part-1) EDA (Exploratory Data Analysis) Explained With Real Life — Why Looking at Your Data Is the Most Important Step in Machine Learning Brand Relationship Management at Scale: Our 4-Touch Outreach System for 200+ Brands Why String.fromEnvironment() Might Return an Empty String in Dart JGuardrails 1.0.0 — Hardening Java LLM Apps Against Jailbreaks, Toxicity, and Prompt Injection Plan and Schedule a Full Week of Threads Content From One Claude Conversation Coding Cat Oran Ep3, Five Tables Changed Everything Updated: BFF Pattern I'm done watching freelancers get buried by 200 proposals. So I'm building the alternative. This is my first post BFS Algorithm in Java Step by Step Tutorial with Examples Tracking LLM Pricing Monthly: An Open Dataset for 22 AI Models How We Measure Content ROI on a Comparison Site: Revenue Attribution Without Perfect Data Introducing Nova AI Ops: The AI-Native Operating System for SRE Teams I built a free desktop video downloader for Windows — Grabbit How Talkie OCR Helps Vision-Impaired & Dyslexic Users Read the World Around Them VRCFaceTracking安装和iPhone面捕配置教程,有bug Even CrowdStrike Can't See Your Agents The Automation Gold Rush: What n8n Workflows and Claude Are Opening Up for Developers Right Now
Three npm Disasters That Were Predictable (And What the Signals Looked Like)
Pico · 2026-04-30 · via DEV Community

Supply chain attacks don't come from nowhere. They exploit structural conditions that existed long before the incident — single maintainers, token concentration, asymmetric blast radius. The conditions are visible. The question is whether anyone is looking.

We took three of the most consequential npm supply chain attacks in the last eight years and analyzed each one through proof-of-commitment — behavioral scoring that measures structural resilience, not CVE databases. For each incident, we ran the actual package through the API today, then reconstructed what the signals would have shown before the attack.

The results are honest. In some cases, the tool would have flagged the exact vulnerability exploited. In others, the signal was there but below the alarm threshold. We'll show both.


Case 1: event-stream (2018)

What happened

In November 2018, a developer named right9ctrl approached Dominic Tarr, the sole maintainer of event-stream, and offered to take over maintenance of the package. Tarr, who had moved on from the project, agreed. The new maintainer added a dependency called flatmap-stream, which contained an encrypted payload targeting Copay — a Bitcoin wallet — to steal cryptocurrency. The attack went undetected for two months. It targeted a specific downstream package while hiding in a generic utility with ~2 million weekly downloads at the time.

What proof-of-commitment sees today

Package Score Risk Maintainers Downloads/wk Age
event-stream 67 ⚠️ WARN 1 6.0M 14.7 yrs

Score: 67 — sitting in the "GOOD" band but well below the "HEALTHY" threshold of 75. The WARN flag fires because of single-maintainer risk. It misses CRITICAL only because downloads are under 10 million per week.

What signals existed before the attack

  • Single maintainer — Dominic Tarr was the only person with npm publish access. When he handed the keys over, there was no governance process, no second pair of eyes, no institutional memory.
  • Maintainer handoff pattern — A new, unknown contributor took ownership. This is the single strongest behavioral signal for social engineering attacks, and it's the one thing nobody was monitoring.
  • Sudden new dependency — The addition of flatmap-stream, a brand-new package with no download history, should have been a structural anomaly. An established package suddenly depending on an unknown package is a pattern, not just a diff.
  • Abandoned project, active downloads — Tarr had publicly stated he was no longer interested in maintaining the package. An abandoned but highly-downloaded package is the ideal target for social engineering.

Verdict: partially

Proof-of-commitment would have flagged the single-maintainer risk — that was the structural condition that made the social engineering attack possible. But it would not have specifically detected the maintainer handoff or the suspicious new dependency.

What it does prove: the structural condition that enabled the attack was observable. One maintainer. No governance. High download count relative to maintainer investment.


Case 2: ua-parser-js (2021)

What happened

In October 2021, the npm account of Faisal Salman — the sole maintainer of ua-parser-js — was compromised. The attacker published three malicious versions that contained a cryptominer and a credential-stealing trojan targeting Linux and Windows systems. The package had approximately 7 million weekly downloads at the time and was used by companies including Facebook, Microsoft, Amazon, and Google. The malicious versions were live for roughly four hours before removal.

What proof-of-commitment sees today

Package Score Risk Maintainers Downloads/wk Age
ua-parser-js 83 🔴 CRITICAL 1 25.4M 13.7 yrs

Today: score 83, single maintainer, 25.4 million weekly downloads. CRITICAL. The exact profile that was exploited.

What signals existed before the attack

  • Single maintainer with sole npm token — Faisal Salman was the only person who could publish. One compromised credential = full access to 7 million weekly installs.
  • High download-to-maintainer ratio — Even at 7M weekly downloads, the ratio of "people who depend on this" to "people who can publish" was approximately 7,000,000 : 1.
  • npm didn't require 2FA at the time — A single password could, and did, compromise the entire package.
  • Behavioral score looks fine — This is the uncomfortable part. The package was well-maintained, consistently released, widely adopted. Every quality metric was positive. The vulnerability was invisible to quality analysis.

Verdict: yes

Proof-of-commitment would have flagged this. In 2021, with ~7M weekly downloads, it would have been right at the CRITICAL boundary — WARN at minimum, with the single-maintainer flag clearly visible.

Three years after the attack, nothing has structurally changed. ua-parser-js today still has one maintainer. Downloads have grown from 7M to 25M per week. The blast radius is 3.6x larger than when it was compromised. The same attack would work again, with more damage.


Case 3: colors.js (January 2022)

What happened

In January 2022, Marak Squiress — the sole maintainer of colors.js and faker.js — intentionally published breaking versions of both packages. colors.js v1.4.44 and v1.4.45 introduced an infinite loop that caused any application importing the package to hang indefinitely. The package had approximately 35 million weekly downloads. Hundreds of open source projects and enterprise CI/CD pipelines broke immediately.

Marak had been publicly protesting the fact that large corporations were building commercial products on his unpaid open source work. The sabotage was intentional and announced. The entire incident was enabled by a single structural condition: he was the only person who could publish these packages.

What proof-of-commitment sees today

Package Score Risk Maintainers Downloads/wk Age
colors 65 🔴 CRITICAL 1 19.8M 15.1 yrs

Today: score 65, single maintainer, 19.8 million weekly downloads — and still CRITICAL. The download count has declined from ~35M since the incident damaged ecosystem trust, but the structural profile is unchanged. One person. One token. Millions of installs.

What signals existed before the incident

  • CRITICAL flag was present — At ~35M weekly downloads and sole maintainer, colors.js would have been flagged CRITICAL.
  • High score provided false comfort — colors.js was a well-maintained package with 15 years of history, consistent releases, and stable download trends. Every quality metric was positive. The risk wasn't about quality — it was about governance.
  • No governance structure — There was no second reviewer, no multi-maintainer quorum, no npm organizational account. The entire blast radius rested on one person's continued good will.
  • The signal is broader than external attacks — This case proves that CRITICAL flagging isn't only about token compromise. It's about any failure mode of the sole maintainer: burnout, grievance, instability, or compromise.

Verdict: yes, clearly

The CRITICAL flag is explicitly designed for this scenario. Not just external attacks — any failure of the single person at the helm.

npm audit showed nothing before the incident — there were no known vulnerabilities. CVE databases showed nothing. Every toolchain in the ecosystem reported green until the packages broke. The structural flag would have shown red for months.


Summary

Incident Attack vector npm audit CVE PoC flag Would PoC have helped?
event-stream (2018) Social engineering ⚠️ WARN Partially — flagged single maintainer, but wouldn't detect handoff
ua-parser-js (2021) Token compromise ⚠️ WARN* Yes — exact vulnerability flagged. *WARN at 2021 volume, CRITICAL today
colors.js (2022) Intentional sabotage 🔴 CRITICAL Yes — sole-maintainer flag visible for entire 15-year package history

The pattern across all three: zero pre-incident warnings from existing tools. npm audit looks at known CVEs — it can't flag structural risk. CVE databases are reactive by design — they catalog what already happened. Neither tool measures the conditions that make attacks viable.


What We Can't Catch (Yet)

  • Maintainer handoffs — The event-stream attack exploited a change in who controls the package. The current scoring is point-in-time; it doesn't track behavioral diffs over time. This is the most important gap.
  • New dependency injection — The addition of flatmap-stream was a structural anomaly. Detecting sudden new dependencies in established packages would catch this class of attack. Not implemented yet.
  • Code-level malice — The tool measures structural governance, not code content. If a trusted maintainer ships malicious code, the structural score won't reflect it. Deliberate scope boundary — structural governance and code analysis are different problems.

What it does catch: the structural conditions that make these attacks possible and high-impact. Single maintainer. Token concentration. Asymmetric blast radius. These conditions precede every attack in this analysis by months or years.


Try It

Run any package through proof-of-commitment in 10 seconds:

npx proof-of-commitment axios ua-parser-js event-stream
# Or your whole project:
npx proof-of-commitment --file package.json
# Or lock files — scans ALL transitive deps:
npx proof-of-commitment --file package-lock.json

Enter fullscreen mode Exit fullscreen mode

Web interface: getcommit.dev/audit

GitHub Action (posts risk table on PRs):

- uses: piiiico/proof-of-commitment@main
  with:
    fail-on-critical: false
    comment-on-pr: true

Enter fullscreen mode Exit fullscreen mode

MCP server for Claude Desktop, Cursor, or Windsurf:

{
  "mcpServers": {
    "proof-of-commitment": {
      "type": "streamable-http",
      "url": "https://poc-backend.amdal-dev.workers.dev/mcp"
    }
  }
}

Enter fullscreen mode Exit fullscreen mode

All data sourced from public npm registry and GitHub APIs. Open source: github.com/piiiico/proof-of-commitment. MIT licensed.


We're building Commit — trust infrastructure for the autonomous economy. Behavioral commitment data, not declarations.

Related: State of npm Trust: April 2026 · The axios signal