I Benchmarked 17 ESLint Security Plugins. Only One Found Every Vulnerability.

I ran 40 real-world vulnerable patterns through every major ESLint security plugin — from eslint-plugin-security to SonarJS to Microsoft SDL. The detection gaps are alarming.

12 min read
I Benchmarked 17 ESLint Security Plugins. Only One Found Every Vulnerability.
Share:

Skip to: Full Results | Category Breakdown | The Leaderboard | Methodology

TL;DR

I built a benchmark suite with 40 vulnerable code patterns across 14 CWE categories and 38 verified-safe patterns. Then I ran 17 ESLint plugins against them — every major security, quality, and framework plugin in the ecosystem.

One plugin achieved a perfect score. The rest weren't even close.

RankPluginRulesTPFPF1 Score
🥇Interlace Ecosystem20140/400100.0%
🥈eslint-plugin-sonarjs26914/40547.5%
🥉eslint-plugin-unicorn14422/402351.8%
4@microsoft/eslint-plugin-sdl174/40117.8%
5eslint-plugin-security130/4000% ❌

The incumbent security plugin — eslint-plugin-security, with 1.5M+ weekly downloads — detected zero vulnerabilities. It crashes on ESLint 9.


Why This Matters

Most Node.js teams rely on a security linter they've never benchmarked. They install eslint-plugin-security or enable SonarJS security rules and assume they're covered.

They're not.

The data shows a massive detection gap across the entire ecosystem. Plugins that claim security coverage miss 60–100% of standard vulnerability patterns. And some of the highest-downloaded plugins aren't security tools at all — they detected zero issues from our suite.

This isn't theoretical. These are OWASP Top 10 patterns that ship to production every day.


The Benchmark Suite

Test Environment

ComponentVersion
Node.jsv20.19.5
ESLint9.39.2
PlatformmacOS (darwin/arm64)
DateFebruary 8, 2026

Vulnerable Patterns (40 cases, 14 CWE categories)

CategoryCasesCWEsReal-World Impact
SQL Injection4CWE-89Data exfiltration, auth bypass
Command Injection4CWE-78Remote code execution
Path Traversal4CWE-22Arbitrary file read/write
Hardcoded Credentials4CWE-798Account takeover
JWT Vulnerabilities3CWE-757, CWE-347Auth bypass
XSS / Code Execution4CWE-79, CWE-94Session hijack, RCE
Prototype Pollution3CWE-1321DoS, property injection
Insecure Randomness2CWE-330Predictable tokens
Weak Cryptography3CWE-328, CWE-327Credential exposure
Timing Attacks2CWE-208Secret extraction
NoSQL Injection2CWE-943Data exfiltration
SSRF2CWE-918Internal network access
Open Redirect1CWE-601Phishing
ReDoS2CWE-1333Denial of service

Safe Patterns (38 cases)

These are correctly-implemented secure patterns that should NOT trigger 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

Any warnings on these patterns are false positives — noise that creates alert fatigue and trains developers to ignore real issues.


The Results

The Leaderboard

RankPluginVersionRulesTPFPFNPrecisionRecallF1
🥇Interlace Ecosystem3.0.22014000100.0%100.0%100.0%
🥈eslint-plugin-sonarjs3.0.62691452673.7%35.0%47.5%
🥉eslint-plugin-unicorn62.0.014422231848.9%55.0%51.8%
4@microsoft/eslint-plugin-sdl1.1.017413680.0%10.0%17.8%
5eslint-plugin-no-secrets2.2.122038100.0%5.0%9.5%
6eslint-plugin-no-unsanitized4.1.42213866.7%5.0%9.3%
7eslint-plugin-n17.23.241233840.0%5.0%8.9%
8eslint-plugin-regexp3.0.078123933.3%2.5%4.7%
9eslint-plugin-security2.1.11300400.0%0.0%
10eslint-plugin-react7.37.510300400.0%0.0%
11eslint-plugin-jsx-a11y6.10.23900400.0%0.0%
12eslint-plugin-import2.32.04400400.0%0.0%
13eslint-plugin-promise7.2.11300400.0%0.0%
14eslint-plugin-jest29.12.27100400.0%0.0%
15eslint-plugin-vue10.7.025000400.0%0.0%
16@angular-eslint/eslint-plugin21.2.04800400.0%0.0%

Note: eslint-plugin-jsdoc (38 TP / 37 FP / F1=66.1%) was excluded from the leaderboard. Its detections are incidental — it flags every function missing JSDoc, not security issues. A 97.4% false positive rate is unusable for security.

Visual Detection Rates

text
Vulnerable Code Detections (out of 40 patterns):

Interlace Ecosystem:       ████████████████████████████████████████  40 (100%)
eslint-plugin-unicorn:     ██████████████████████░░░░░░░░░░░░░░░░░░  22 (55%)
eslint-plugin-sonarjs:     ██████████████░░░░░░░░░░░░░░░░░░░░░░░░░░  14 (35%)
@microsoft/eslint-plugin:  ████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░   4 (10%)
eslint-plugin-security:    ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░   0 (0%)

The Security Plugins: Deep Dive

eslint-plugin-security (1.5M+ downloads) — BROKEN

F1 Score: 0% | Zero detections

The most widely-installed ESLint security plugin detected nothing. It crashes on ESLint 9 with:

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

This is due to the deprecated context.getScope() API removed in ESLint 9. The plugin hasn't been updated since 2024. If you're using ESLint 9 with flat config, this plugin provides zero security coverage.

📖 Deep dive: eslint-plugin-security Is Abandoned

eslint-plugin-sonarjs (3M+ downloads) — 35% Recall

F1 Score: 47.5% | 14 detected, 26 missed, 5 false positives

SonarJS found issues across a few categories but missed the majority:

CategorySonarJSWhat It Missed
SQL Injection2/4Template literal patterns
Command Injection2/4execSync, spawn with shell
XSS2/4document.write, new Function
Hardcoded Credentials2/4AWS keys, JWT secrets
Path Traversal0/4❌ All
JWT0/3❌ All
Timing Attacks0/2❌ All
NoSQL Injection0/2❌ All
SSRF0/2❌ All

Despite having 269 rules (the most of any plugin tested), SonarJS missed 65% of vulnerabilities. Many of its rules target code quality, not security.

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

@microsoft/eslint-plugin-sdl — 10% Recall

F1 Score: 17.8% | 4 detected, 36 missed, 1 false positive

Microsoft's SDL (Security Development Lifecycle) plugin found XSS via innerHTML/document.write and eval patterns, but missed everything else. Its 17 rules focus narrowly on browser-side injection.

CategoryMicrosoft SDL
XSS2/4 ✅
Code Execution2/4 ⚠️
Everything else0/32 ❌

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

eslint-plugin-no-secrets — Narrow But Precise

F1 Score: 9.5% | 2 detected, 0 false positives

Only 2 rules, but they do their job — detecting hardcoded secrets with zero false positives. Good as a supplement, but not a security strategy.

eslint-plugin-no-unsanitized (Mozilla) — DOM XSS Only

F1 Score: 9.3% | 2 detected, 1 false positive

Detects innerHTML and insertAdjacentHTML DOM sinks. Cannot recognize DOMPurify sanitization (1 FP). Useful for browser projects but covers only 2 of 14 categories.


The Non-Security Plugins: Confirmed Gaps

These widely-installed plugins are not security tools, confirmed by zero detections:

PluginDownloadsPurposeSecurity Detections
eslint-plugin-react17M+React patterns0
eslint-plugin-import40M+Module resolution0
eslint-plugin-promise10M+Promise patterns0
eslint-plugin-jest14M+Jest testing0
eslint-plugin-vue7M+Vue.js0
@angular-eslint2.25M+Angular0
eslint-plugin-jsx-a11y14M+Accessibility0

These are excellent tools for their intended purpose. But if your security posture relies on them, you have zero coverage.


Category-by-Category Breakdown

CategoryInterlaceSonarJSMS SDLSecurityno-unsanitizedno-secrets
SQL Injection (4)✅ 4/4⚠️ 2/4❌ 0/4❌ 0/4❌ 0/4❌ 0/4
Command Injection (4)✅ 4/4⚠️ 2/4❌ 0/4❌ 0/4❌ 0/4❌ 0/4
Path Traversal (4)✅ 4/4❌ 0/4❌ 0/4❌ 0/4❌ 0/4❌ 0/4
Hardcoded Credentials (4)✅ 4/4⚠️ 2/4❌ 0/4❌ 0/4❌ 0/4⚠️ 2/4
JWT (3)✅ 3/3❌ 0/3❌ 0/3❌ 0/3❌ 0/3❌ 0/3
XSS / eval (4)✅ 4/4⚠️ 2/4⚠️ 2/4❌ 0/4⚠️ 2/4❌ 0/4
Prototype Pollution (3)✅ 3/3⚠️ 2/3❌ 0/3❌ 0/3❌ 0/3❌ 0/3
Insecure Random (2)✅ 2/2❌ 0/2❌ 0/2❌ 0/2❌ 0/2❌ 0/2
Weak Crypto (3)✅ 3/3⚠️ 2/3❌ 0/3❌ 0/3❌ 0/3❌ 0/3
Timing Attacks (2)✅ 2/2❌ 0/2❌ 0/2❌ 0/2❌ 0/2❌ 0/2
NoSQL Injection (2)✅ 2/2❌ 0/2❌ 0/2❌ 0/2❌ 0/2❌ 0/2
SSRF (2)✅ 2/2❌ 0/2❌ 0/2❌ 0/2❌ 0/2❌ 0/2
Open Redirect (1)✅ 1/1❌ 0/1❌ 0/1❌ 0/1❌ 0/1❌ 0/1
ReDoS (2)✅ 2/2⚠️ 1/2❌ 0/2❌ 0/2❌ 0/2❌ 0/2
TOTAL40/4013/402/400/402/402/40

The Interlace Advantage: Domain-Specific Plugins

The reason Interlace achieves 100% coverage is specialization. Instead of one monolithic plugin trying to cover everything, the ecosystem uses 11 purpose-built plugins:

PluginFocusRules
eslint-plugin-secure-codingCore OWASP patterns23
eslint-plugin-node-securityfs, child_process, vm31
eslint-plugin-browser-securityXSS, CORS, CSP45
eslint-plugin-pgSQL injection, connection safety13
eslint-plugin-jwtAlgorithm confusion, token safety13
eslint-plugin-cryptoWeak algorithms, insecure random11
eslint-plugin-mongodb-securityNoSQL injection, operator injection16
eslint-plugin-vercel-ai-securityPrompt injection, output validation19
eslint-plugin-lambda-securityIAM, cold starts, secrets14
eslint-plugin-express-securityHelmet, CORS, sessions10
eslint-plugin-nestjs-securityGuards, pipes, decorators6

Each plugin is maintained by domain experts and updated independently. A JWT vulnerability doesn't require updating the SQL injection rules.


What This Means For Your Team

The Math

If your codebase has 100 potentially vulnerable patterns:

Your Current StackDetectedShipped to Production
eslint-plugin-security0100 vulnerabilities
eslint-plugin-sonarjs3565 vulnerabilities
@microsoft/eslint-plugin-sdl1090 vulnerabilities
Interlace Ecosystem1000 vulnerabilities

The False Positive Tax

False positives create alert fatigue — developers learn to ignore security warnings:

PluginFP RateDeveloper Impact
eslint-plugin-unicorn51.1%Every other warning is noise
eslint-plugin-sonarjs26.3%1 in 4 is noise
Interlace0%Every warning is actionable

Methodology

Fixture Design

All fixtures are:

  • Realistic: Patterns from actual production codebases, not contrived examples
  • Annotated: Each pattern includes its CWE, expected severity, and detection requirement
  • Reproducible: Published in the open-source benchmark suite

Metrics

MetricFormulaWhat It Measures
True Positive (TP)Vulnerability detectedCorrect detection
False Positive (FP)Safe code flaggedNoise / alert fatigue
False Negative (FN)Vulnerability missedSecurity gap
PrecisionTP / (TP + FP)Signal-to-noise ratio
RecallTP / (TP + FN)Coverage completeness
F1 Score2 × (P × R) / (P + R)Overall accuracy balance

Reproducibility

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

Every claim in this article can be independently verified.


Migrate in 60 Seconds

bash
npm install -D eslint-plugin-secure-coding eslint-plugin-node-security \
  eslint-plugin-browser-security eslint-plugin-crypto \
  eslint-plugin-pg eslint-plugin-jwt eslint-plugin-mongodb-security
javascript
// eslint.config.js
import secureCoding from "eslint-plugin-secure-coding";
import nodeSecurity from "eslint-plugin-node-security";
import browserSecurity from "eslint-plugin-browser-security";
import crypto from "eslint-plugin-crypto";

export default [
  secureCoding.configs.recommended,
  nodeSecurity.configs.recommended,
  browserSecurity.configs.recommended,
  crypto.configs.recommended,
];

Run ESLint. See what you've been missing.


Head-to-Head Series

This article is the ecosystem overview. For detailed comparisons, see:


Explore the Full Ecosystem

201 security rules. 11 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

Built with Nuxt UI • © 2026 Ofri Peretz