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

推荐订阅源

Stack Overflow Blog
Stack Overflow Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
P
Proofpoint News Feed
Apple Machine Learning Research
Apple Machine Learning Research
T
Tailwind CSS Blog
罗磊的独立博客
F
Future of Privacy Forum
The Register - Security
The Register - Security
MyScale Blog
MyScale Blog
P
Privacy & Cybersecurity Law Blog
V
Visual Studio Blog
T
Tenable Blog
F
Fortinet All Blogs
D
Docker
V
Vulnerabilities – Threatpost
Cyberwarzone
Cyberwarzone
A
Arctic Wolf
T
Threat Research - Cisco Blogs
I
Intezer
T
Tor Project blog
大猫的无限游戏
大猫的无限游戏
MongoDB | Blog
MongoDB | Blog
博客园 - 司徒正美
AWS News Blog
AWS News Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
G
GRAHAM CLULEY
T
Threatpost
美团技术团队
K
Kaspersky official blog
F
Fox-IT International blog
Hugging Face - Blog
Hugging Face - Blog
Vercel News
Vercel News
P
Palo Alto Networks Blog
Google DeepMind News
Google DeepMind News
T
The Blog of Author Tim Ferriss
S
Schneier on Security
腾讯CDC
Cisco Talos Blog
Cisco Talos Blog
C
Check Point Blog
博客园 - 叶小钗
I
InfoQ
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Blog — PlanetScale
Blog — PlanetScale
F
Full Disclosure
T
True Tiger Recordings
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
E
Exploit-DB.com RSS Feed
L
LINUX DO - 热门话题
J
Java Code Geeks
C
CERT Recently Published Vulnerability Notes

DEV Community

Looking for 4 people to build something weird with me Building a Local-Only RAG System with Ollama and TypeScript What's new in Data Preprocessor 1.5.x — R codegen, Robust Scaler, and a deadlock post-mortem How I self-hosted my Flask app on an old laptop for almost free I built a free DSA interview prep site because I was tired of the existing options I built an AI agent that migrates Next.js Pages Router to App Router Prisma Query Logging and PostgreSQL: Where the ORM Ends and the Database Begins Prisma query logging y PostgreSQL: dónde termina el ORM y empieza la base From Browser to Server : The Journey of an HTTP Request (Demystifying the Web’s Infrastructure) Santa Augmentcode Intent Ep.6 I Benchmarked 17 ESLint Security Plugins. Only One Found Every Vulnerability. How to Build a High-Performance Image Optimization Pipeline in 5 Minutes 50 Linux Commands Every DevOps Engineer Must Know Less Toil, More Flow - Automating the Path from Request to Implementation The Code Review Checklist I Actually Use How I run a small blog on Astro 5 + Content Collections Git: Best Practices for Professionals How IBM Bob Became My Everyday Coding Companion Solana Passkey Wallet: Replacing Seed Phrases with SIMD-0075 I built a small browser puzzle game about arrows I wrapped Claude Code in a zsh function. Here's every decision I almost got wrong. Mobile Game Optimization: A Unity Developer's Checklist Git: Best Practices for Beginners Three days I lost chasing a ghost that was already dead on disk Why Too Many Parts Hurt ClickHouse Performance Guardrails for Agent Output: Pluggable Validation Before and After LLM Calls Gemma Forge: Local AI Without the Setup Wall From Half‑dead Prototype to Local‑Only AI Medical Assistant: Rewiring MedClinic with GitHub Copilot Runninig a forkbomb in Jenkins What’s Actually Happening When You Use Git Preventing Recursive Tool Loops in LangChain Agents Building a Rock-Paper-Scissors CLI with TypeScript — Union Types, Conditionals, and Jest Your AI Coding Agent Wastes 80% of Its Context. Fixed That with Graph Theory. Why Flutter Has Become the Go-To Framework for Fintech App Development We built a scripting language just for AI agents. Here's why. Stop building AI inboxes. Build decision layers instead. Meme Monday Why I Built @editora/ui-react? Are AI tools the next level of abstraction in software development? Identity on Solana: Your Wallet Is Your Account One API Call Changed Everything The Internet Career Nobody Talks About Enough: What Is DevRel? Solar Panel Wiring Diagram: Series vs Parallel Hello everyone! Glad to join the dev.to community I Built an AI Agent That Tailors My Resume - Here's How Agents Actually Work I Built a WhatsApp OTP + AI Chatbot Platform for African Businesses MTP Explained — And Why It Matters for Android on Mac Most Beginners Learn Full-Stack Development Backwards GitHub Glow-Up: Open Source, READMEs, Badges, Streaks, Git and gh CLI System Design Cheat Sheet: Concepts Every Developer Should Know Are Junior Developer Roles Actually Dying? A Fresher's Honest Take Using DigitalOcean Droplets as Ephemeral Sandboxes for AI Agents I built a VSCode extension that visualises your code navigation as a call tree — made for legacy codebase pain Vite predev/prebuild: chaining scripts without losing your mind A website to save you from messy browser tabs Dear Web2 Developer... Solana is here calling Postgres JSONB indexes: GIN vs BTREE on the same column The $5 AI That Remembers Everything What are your goals for the week? #180 Zettelkasten for Developers: A Practical Method That Works OpenClaw vs Hermes Agent: Stars, Downloads & Usage 2026 `act` vs. `waitFor` Global Teams Don’t Struggle With Time Zones. They Struggle With Context Python as a JavaScript Dev $5.4 Billion in Damage. 8.5 Million Machines Down. Three YAML Controls Would Have Prevented It. Here's the Structural Analysis. 🚫 Stop Using PN532 V1 for Your NFC Projects (Real Debugging Experience) Probabilistic Graph Neural Inference for smart agriculture microgrid orchestration for extreme data sparsity scenarios Inference Is Becoming the New Steady-State Cost Center Why AI-Generated Code Is Always Good Enough — And Never Great I built a dark admin dashboard template in HTML — no React, no npm, just pure HTML What is the Difference Between Lattice-Based and Hash-Based Signatures? Next.js App Router caching: revalidate, dynamic, and no-store without the folklore Next.js App Router caching: revalidate, dynamic y no-store sin folklore I built Stashly — a full-stack content manager with a rich text editor published: false tags: react, node, mongodb, typescript Why I Started Building React Projects Instead of Just Watching Tutorials ? Every Tool Eventually Becomes Tuesday Nobody Warns You That Real Software Engineering Feels Chaotic Tích hợp VNPay, Stripe trong Odoo 19 BeautifulSoup and Requests for Web Scraping With Python: When Simple Still Works I Was Stuck Debugging React — Then Developer Tools Changed It Buck Converter Ripple: Sizing the Inductor and Capacitor With Confidence AWS Just Made Its MCP Server Generally Available. Here's What It Actually Gives AI Agents. RAMPART Tests Your AI Agents in Dev. What Catches Malicious Tool Calls in Production? Vibe Team Software Engineering: What a Real AI Human Dev Team Workflow Actually Looks Like An npm Package for AI Agent Orchestration Just Shipped With Its Front Door Unlocked. Here's What the CVE Actually Reveals. Microsoft Foundry Just Added CI/CD for AI Agents. Here's What That Actually Changes. The Best Career Insurance Is a Tech Event You Don't Want to Attend Your GitHub Profile Already Tells Recruiters More Than Your Resume. Most Devs Just Don't Surface It. How to Add Execution Budgets to OpenAI Agents SDK Binary Tree Interview Problems: 6 Traversal Patterns, 15 Problems We trained a personal voice DoRA on Qwen3-8B for $1.50 — beat stock model 100% in blind A/B Stop Leaking API Keys: Why I Built a Local-First Vault for Developers 🔐 RAG Explained: How Retrieval-Augmented Generation Actually Works I Built a Fast Async JioSaavn API Wrapper in Python 🎧 chown & chgrp Deploying Your First App on Kubernetes: A Beginner's Guide (Minikube & Kind) Logs in code It's called a PR "review" for a reason DePIN GPU Market: The Failed Job Receipt Developers Should Demand Why Your AI Agent Monitoring is Wrong (And How to Fix It)
The False Positive Tax: a 1:1 TP:FP analysis of eslint-plugin-security
Ofri Peretz · 2026-05-25 · via DEV Community

Skip to: Results Table | eslint-plugin-security | SonarJS | Microsoft SDL | Interlace | Methodology

This is the false-positive deep dive companion to I Benchmarked 17 ESLint Security Plugins. That overview ranks plugins by recall; this one drills into the FP code samples that drive alert fatigue.

TL;DR

I built a comprehensive benchmark with 40 vulnerable code patterns across 14 security categories and 38 safe patterns that should NOT trigger warnings. Then I ran six ESLint security plugins against them.

The Headline Numbers

Plugin download counts cited throughout this article are weekly figures snapshotted on 2026-02-08 from npm-stat.com.

Plugin Rules TP (Detections) FP (False Alarms) Precision Recall F1 Score ESLint 9
Interlace Ecosystem 201 40/40 0 100.0% 100.0% 100.0% ✅ Works
eslint-plugin-sonarjs 269 14/40 5 73.7% 35.0% 47.5% ✅ Works
eslint-plugin-security 13 11/40 11 50.0% 27.5% 34.4% ❌ Broken
eslint-plugin-security-node 22 7/40 4 63.6% 17.5% 27.4% ✅ Works
@microsoft/eslint-plugin-sdl 17 4/40 1 80.0% 10.0% 17.8% ✅ Works
eslint-plugin-no-unsanitized 2 2/40 1 66.7% 5.0% 9.3% ⚠️ Limited

eslint-plugin-security crashes on ESLint 9. Its results are from ESLint 8.57.0. All other plugins were tested on ESLint 9.39.2.

Key Findings:

  • eslint-plugin-security has a 1:1 true positive to false positive ratio — for every real issue it catches, it incorrectly flags a safe pattern
  • eslint-plugin-sonarjs has 269 rules but only detects 35% of vulnerabilities — most rules target code quality, not security
  • eslint-plugin-security-node (the "successor" to eslint-plugin-security) still misses 82.5% of vulnerabilities
  • The Interlace ecosystem achieved a perfect score: 40/40 detections with zero false positives

Why This Benchmark Matters

Security linters exist to catch vulnerabilities before they reach production. But two failure modes undermine this mission:

False Negatives (missed vulnerabilities) create a dangerous illusion of security. Your CI pipeline passes, your code looks "clean," but invisible vulnerabilities ship to production.

False Positives (incorrectly flagged safe code) create alert fatigue. Developers start ignoring warnings, disabling rules, or worse—bypassing security checks entirely.

The ideal security linter has high recall (catches most vulnerabilities) and high precision (doesn't cry wolf).


The Benchmark Suite

Vulnerable Patterns (40 cases across 14 categories)

Category Test Cases CWEs
SQL Injection 4 CWE-89
Command Injection 4 CWE-78
Path Traversal 4 CWE-22
Hardcoded Credentials 4 CWE-798
JWT Vulnerabilities 3 CWE-757, CWE-347
XSS / Code Execution 4 CWE-79, CWE-94
Prototype Pollution 3 CWE-1321
Insecure Randomness 2 CWE-330
Weak Cryptography 3 CWE-328, CWE-327
Timing Attacks 2 CWE-208
NoSQL Injection 2 CWE-943
SSRF 2 CWE-918
Open Redirect 1 CWE-601
ReDoS 2 CWE-1333

Safe Patterns (38 cases)

Secure implementations that should NOT trigger any warnings:

  • Parameterized SQL queries (Prisma, TypeORM, pg)
  • execFile with validated arguments
  • path.resolve with startsWith validation
  • Environment variables for credentials
  • JWT with explicit algorithm restriction
  • DOMPurify sanitization
  • Allowlist validation before object access
  • crypto.randomBytes for tokens
  • crypto.timingSafeEqual for comparisons
  • URL allowlists for SSRF prevention

The Results

Detection Summary

Vulnerable Code Detections (out of 40 patterns):

Interlace Ecosystem:         ████████████████████████████████████████  40 (100%)
eslint-plugin-sonarjs:       ██████████████░░░░░░░░░░░░░░░░░░░░░░░░░░  14 (35%)
eslint-plugin-security:      ███████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░  11 (27.5%)
eslint-plugin-security-node: ███████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░   7 (17.5%)
@microsoft/eslint-plugin-sdl:████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░   4 (10%)
eslint-plugin-no-unsanitized:██░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░   2 (5%)

Enter fullscreen mode Exit fullscreen mode

The Leaderboard

Rank Plugin Version Rules TP FP FN Precision Recall F1
🥇 Interlace Ecosystem 3.0.2 201 40 0 0 100.0% 100.0% 100.0%
🥈 eslint-plugin-sonarjs 3.0.6 269 14 5 26 73.7% 35.0% 47.5%
🥉 eslint-plugin-security† 2.1.1 13 11 11 29 50.0% 27.5% 34.4%
4 eslint-plugin-security-node 1.1.4 22 7 4 33 63.6% 17.5% 27.4%
5 @microsoft/eslint-plugin-sdl 1.1.0 17 4 1 36 80.0% 10.0% 17.8%
6 eslint-plugin-no-unsanitized 4.1.4 2 2 1 38 66.7% 5.0% 9.3%

† Tested on ESLint 8.57.0 — crashes on ESLint 9 with TypeError: context.getScope is not a function


Plugin Deep Dives

eslint-plugin-security: The Incumbent

Weekly Downloads: 1.5M+ | Rules: 13 | Last Updated: 2024 | ESLint 9: ❌ Broken

What It Detected (11 violations)

Rule Count Lines
detect-non-literal-fs-filename 4 106, 115, 124, 134
detect-child-process 2 64, 73
detect-object-injection 2 264, 276
detect-eval-with-expression 1 243
detect-unsafe-regex 1 432
detect-non-literal-regexp 1 441

What It Missed (29 patterns = 72.5% False Negative Rate)

Category Detected Missed
SQL Injection 0/4 ❌ All
Hardcoded Credentials 0/4 ❌ All
JWT Vulnerabilities 0/3 ❌ All
Weak Cryptography 0/3 ❌ All
NoSQL Injection 0/2 ❌ All
SSRF 0/2 ❌ All
Open Redirect 0/1 ❌ All
Timing Attacks 0/2 ❌ All
Command Injection 2/4 ❌ Template literals
Path Traversal 4/4 ✅ Good
XSS / eval 1/4 ❌ innerHTML, document.write
Prototype Pollution 2/3 ⚠️ Partial
ReDoS 2/2 ✅ Good

The plugin has ZERO coverage for: SQL injection, hardcoded credentials, JWT attacks, weak crypto, NoSQL injection, SSRF, open redirects, and timing attacks.

The False Positive Problem (11 FPs = 100% of detections!)

For every vulnerability eslint-plugin-security catches, it also incorrectly flags a safe pattern:

FP #1-8: detect-object-injection (8 false positives)

// ✅ SAFE: Key validated against allowlist
const VALID_KEYS = ["name", "email", "age"];
if (VALID_KEYS.includes(key)) {
  return obj[key]; // ⚠️ Flagged as "Generic Object Injection Sink"
}

Enter fullscreen mode Exit fullscreen mode

The rule flags any bracket notation with a variable, regardless of validation. It cannot recognize allowlist checks, hasOwnProperty guards, or Object.hasOwn() checks.

FP #9-11: detect-non-literal-fs-filename (3 false positives)

// ✅ SAFE: Path validated with startsWith
const safePath = path.resolve(baseDir, path.basename(filename));
if (!safePath.startsWith(baseDir + path.sep)) {
  throw new Error("Path traversal detected");
}
fs.readFileSync(safePath); // ⚠️ Flagged anyway

Enter fullscreen mode Exit fullscreen mode

The rule cannot recognize path validation patterns.

ESLint 9 Compatibility: ❌ BROKEN

TypeError: context.getScope is not a function
Rule: "security/detect-child-process"

Enter fullscreen mode Exit fullscreen mode

This is a breaking API change in ESLint 9. The plugin hasn't been updated, making it unusable with modern ESLint flat config.


eslint-plugin-sonarjs: The 269-Rule Giant

Weekly Downloads: 3M+ | Rules: 269 | Last Updated: 2025 (active) | ESLint 9: ✅ Works

Detection Results: 14/40 (35% Recall)

Despite having the most rules of any plugin tested, SonarJS missed 65% of vulnerabilities. The majority of its 269 rules target code quality (complexity, duplication, cognitive load), not security.

Category SonarJS What It Missed
SQL Injection 2/4 Template literal patterns
Command Injection 2/4 execSync, spawn with shell
XSS 2/4 document.write, new Function
Hardcoded Credentials 2/4 AWS keys, JWT secrets
Prototype Pollution 2/3 Nested merge patterns
Weak Crypto 2/3 MD4, custom hash selection
ReDoS 1/2 Complex catastrophic patterns
Path Traversal 0/4 ❌ All
JWT 0/3 ❌ All
Timing Attacks 0/2 ❌ All
NoSQL Injection 0/2 ❌ All
SSRF 0/2 ❌ All
Open Redirect 0/1 ❌ All
Insecure Random 1/2 Token generation patterns

False Positives: 5

SonarJS had a 73.7% precision rate — better than eslint-plugin-security, but still means roughly 1 in 4 security warnings is noise.

📖 Deep dive: SonarJS vs Interlace: 269 Rules, 65% Missed


eslint-plugin-security-node: The Successor

Weekly Downloads: ~30K | Rules: 22 | Last Updated: 2023 | ESLint 9: ✅ Works

Created as a modern alternative to eslint-plugin-security, this plugin adds SQL injection and NoSQL injection detection rules that the original lacks. However, it still misses the majority of our test suite.

Detection Results: 7/40 (17.5% Recall)

Category security-node What It Caught
SQL Injection 2/4 Basic concatenation patterns
Command Injection 2/4 exec with string interpolation
XSS / eval 1/4 eval with expression
NoSQL Injection 1/2 Direct $where usage
Timing Attacks 1/2 Basic === comparison on secrets
Path Traversal 0/4 ❌ All
Hardcoded Credentials 0/4 ❌ All
JWT 0/3 ❌ All
Weak Crypto 0/3 ❌ All
SSRF 0/2 ❌ All

False Positives: 4

A 63.6% precision rate — better than eslint-plugin-security's 50%, but still noisy.


@microsoft/eslint-plugin-sdl: Enterprise Security

Weekly Downloads: ~100K | Rules: 17 | Last Updated: 2024 (active) | ESLint 9: ✅ Works

Microsoft's Security Development Lifecycle plugin has the highest precision of any non-Interlace plugin (80%), but its scope is extremely narrow — focused almost entirely on browser-side injection patterns.

Detection Results: 4/40 (10% Recall)

Category Microsoft SDL What It Caught
XSS 2/4 innerHTML, document.write
Code Execution 2/4 eval, setTimeout with exprs
Everything else 0/32 ❌ All

False Positives: 1 (Microsoft SDL)

High precision, but extremely limited coverage. Its 17 rules focus narrowly on XSS patterns — it has zero rules for SQL injection, command injection, path traversal, JWT attacks, or any server-side vulnerability.

📖 Deep dive: Microsoft SDL vs Interlace: Enterprise Security Benchmark


eslint-plugin-no-unsanitized (Mozilla)

Weekly Downloads: ~500K | Rules: 2 | Focus: XSS via DOM manipulation | ESLint 9: ⚠️ Limited

Detection Results: 2/40

Rule Count What It Caught
no-unsanitized/property 1 innerHTML = userContent
no-unsanitized/method 1 insertAdjacentHTML

False Positives: 1 (no-unsanitized)

// ✅ SAFE: Content sanitized with DOMPurify
const sanitized = DOMPurify.sanitize(userContent);
element.innerHTML = sanitized; // ⚠️ Flagged anyway

Enter fullscreen mode Exit fullscreen mode

Very narrow scope. Useful as a supplement for XSS, but covers only 2 of 14 categories.


Interlace Ecosystem

Weekly Downloads: ~5K | Rules: 201 (10 specialized plugins) | ESLint 9: ✅ Works

Detection Results: 40/40 (100% Recall, 0 False Positives)

The Interlace ecosystem achieved a perfect score — detecting every vulnerability with zero false positives across all 14 categories.

Sample detections:

🔒 CWE-798 OWASP:A04-Cryptographic CVSS:9.8 | Hard-coded API key detected | CRITICAL
   Fix: Use environment variable: process.env.API_KEY

🔒 CWE-347 | Including "none" in algorithms array allows unsigned tokens | CRITICAL
   Fix: Remove "none" from the algorithms array

🔒 CWE-95 OWASP:A05-Injection CVSS:9.8 | eval() can be refactored to safer alternative | HIGH
   Fix: Remove eval entirely

Enter fullscreen mode Exit fullscreen mode

The reason for 100% coverage is specialization. Instead of one monolithic plugin, the ecosystem uses purpose-built plugins for each domain: SQL (eslint-plugin-pg), JWT (eslint-plugin-jwt), browser XSS (eslint-plugin-browser-security), and weak crypto / randomness (consolidated into eslint-plugin-node-security on 2026-05-10), and more.


Category-by-Category Breakdown

Category security† security-node sonarjs MS SDL no-unsanitized Interlace
SQL Injection (4) ❌ 0/4 ⚠️ 2/4 ⚠️ 2/4 ❌ 0/4 ❌ 0/4 ✅ 4/4
Command Injection (4) ⚠️ 2/4 ⚠️ 2/4 ⚠️ 2/4 ❌ 0/4 ❌ 0/4 ✅ 4/4
Path Traversal (4) ✅ 4/4 ❌ 0/4 ❌ 0/4 ❌ 0/4 ❌ 0/4 ✅ 4/4
Hardcoded Creds (4) ❌ 0/4 ❌ 0/4 ⚠️ 2/4 ❌ 0/4 ❌ 0/4 ✅ 4/4
JWT (3) ❌ 0/3 ❌ 0/3 ❌ 0/3 ❌ 0/3 ❌ 0/3 ✅ 3/3
XSS / eval (4) ⚠️ 1/4 ⚠️ 1/4 ⚠️ 2/4 ⚠️ 2/4 ⚠️ 2/4 ✅ 4/4
Prototype Poll. (3) ⚠️ 2/3 ❌ 0/3 ⚠️ 2/3 ❌ 0/3 ❌ 0/3 ✅ 3/3
Insecure Random (2) ❌ 0/2 ❌ 0/2 ⚠️ 1/2 ❌ 0/2 ❌ 0/2 ✅ 2/2
Weak Crypto (3) ❌ 0/3 ❌ 0/3 ⚠️ 2/3 ❌ 0/3 ❌ 0/3 ✅ 3/3
Timing Attacks (2) ❌ 0/2 ⚠️ 1/2 ❌ 0/2 ❌ 0/2 ❌ 0/2 ✅ 2/2
NoSQL Injection (2) ❌ 0/2 ⚠️ 1/2 ❌ 0/2 ❌ 0/2 ❌ 0/2 ✅ 2/2
SSRF (2) ❌ 0/2 ❌ 0/2 ❌ 0/2 ❌ 0/2 ❌ 0/2 ✅ 2/2
Open Redirect (1) ❌ 0/1 ❌ 0/1 ❌ 0/1 ❌ 0/1 ❌ 0/1 ✅ 1/1
ReDoS (2) ✅ 2/2 ❌ 0/2 ⚠️ 1/2 ❌ 0/2 ❌ 0/2 ✅ 2/2
TOTAL 11/40 7/40 14/40 4/40 2/40 40/40

† ESLint 8 results (crashes on ESLint 9)


What This Means for Your Team

The Math of Missing Vulnerabilities

If your codebase has 100 potentially vulnerable patterns:

Plugin Detected Missed In Production
eslint-plugin-security 28 72 72 vulnerabilities
eslint-plugin-sonarjs 35 65 65 vulnerabilities
eslint-plugin-security-node 18 82 82 vulnerabilities
@microsoft/eslint-plugin-sdl 10 90 90 vulnerabilities
Interlace Ecosystem 100 0 0 vulnerabilities

The Alert Fatigue Cycle

When false positive rates are too high:

  1. Developer sees detect-object-injection on config[key] where key is validated
  2. Developer adds // eslint-disable-next-line
  3. Repeat 50 times across codebase
  4. Developer starts ignoring all security warnings
  5. Real vulnerability slips through disabled rule
  6. Breach
Plugin FP Rate Developer Impact
eslint-plugin-security 50.0% Every other warning is wrong
eslint-plugin-sonarjs 26.3% 1 in 4 is noise
eslint-plugin-security-node 36.4% 1 in 3 is noise
@microsoft/eslint-plugin-sdl 20.0% Tolerable, but very limited
Interlace 0.0% Every warning is actionable

Methodology

Test Environment

Component Version
Node.js v20.19.5
ESLint 9.39.2 (8.57.0†)
Platform macOS (darwin/arm64)
Date February 8, 2026

† ESLint 8.57.0 used for eslint-plugin-security only (crashes on ESLint 9)

Fixture Design

All fixtures are:

  • Realistic: Patterns from actual codebases, not contrived examples
  • Reproducible: Published to GitHub with exact versions
  • Comprehensive: All OWASP Top 10 with detectable patterns

Reproducibility

Full bench setup (fixtures, scripts, methodology) is documented in the companion article: I Benchmarked 17 ESLint Security Plugins. The FP samples in this article come from the same suite:

git clone https://github.com/ofri-peretz/eslint-benchmark-suite
cd eslint-benchmark-suite
npm install
npm run benchmark:fn-fp

# ESLint 8 benchmark (eslint-plugin-security only — required because it crashes on ESLint 9)
cd benchmarks/fn-fp-comparison/eslint8-compat
npm install
npm run benchmark

Enter fullscreen mode Exit fullscreen mode

Every claim in this article can be independently verified.


Conclusions

  1. eslint-plugin-security is hard to recommend for ESLint 9 codebases. A 72.5% false negative rate and a 1:1 TP:FP ratio on ESLint 8, plus a hard crash on ESLint 9. Teams on flat-config are left with no signal at all.

  2. eslint-plugin-sonarjs is a quality tool, not a security tool. Despite 269 rules and 3M+ downloads, it misses 65% of security vulnerabilities. Its strength is code quality enforcement.

  3. eslint-plugin-security-node is broader but still partial. It covers more categories than its predecessor, but still misses 82.5% of vulnerabilities.

  4. @microsoft/eslint-plugin-sdl is high precision, low coverage. Strong for browser XSS, but provides zero server-side security coverage.

  5. The Interlace ecosystem delivers comprehensive coverage. 100% detection rate with zero false positives. Domain-specific plugins ensure deep coverage across all vulnerability categories.

  6. Security tooling requires active maintenance. The OWASP landscape evolves. Plugins from 2020 don't cover JWT algorithm confusion, AI prompt injection, or modern SSRF patterns.


Migrating Off eslint-plugin-security

Full migration steps (uninstall + install + config) are in the companion article's 60-second migration block. The short version:

npm uninstall eslint-plugin-security
npm install -D eslint-plugin-secure-coding eslint-plugin-node-security \
  eslint-plugin-browser-security \
  eslint-plugin-pg eslint-plugin-jwt eslint-plugin-mongodb-security

Enter fullscreen mode Exit fullscreen mode

Note: weak-crypto and randomness rules were consolidated into eslint-plugin-node-security on 2026-05-10. The previously separate eslint-plugin-crypto package is deprecated.


Related deep dives


Explore the Full Ecosystem

201 security rules. 10 specialized plugins. 100% OWASP Top 10 coverage.

The Interlace ESLint Ecosystem provides comprehensive security static analysis for modern Node.js applications.

📖 Documentation | ⭐ GitHub | 📦 NPM


Build Securely.

I'm Ofri Peretz, a Security Engineering Leader and the architect of the Interlace Ecosystem. I build static analysis standards that automate security and performance for Node.js fleets at scale.

ofriperetz.dev | LinkedIn | GitHub