你的 ESLint 安全插件遗漏了 80% 的漏洞(我有证据)

发布: (2025年12月21日 GMT+8 00:25)
8 min read
原文: Dev.to

Source: Dev.to

请提供您希望翻译的具体文本内容,我将把它翻译成简体中文并保持原有的格式、Markdown 语法以及技术术语不变。谢谢!

基准方法论

测试文件

vulnerable.js (218 行) – 包含 12 类真实漏洞

// 1. Command Injection
exec(`ls -la ${userInput}`);
execSync('echo ' + userInput);
spawn('bash', ['-c', userInput]);

// 2. Path Traversal
fs.readFile(filename, 'utf8', callback);
fs.readFileSync(filename);

// 3. Object Injection
obj[key] = value;
data[key][value] = 'test';

// 4. SQL Injection
db.query('SELECT * FROM users WHERE id = ' + userId);

// 5. Code Execution
eval(code);
new Function(code);

// 6. Regex DoS
const evilRegex = /^(a+)+$/;
new RegExp(userInput);

// 7. Weak Cryptography
crypto.createHash('md5').update(password);
Math.random().toString(36);

// 8. Timing Attacks
if (inputToken === storedToken) {
  return true;
}

// 9. XSS
document.getElementById('output').innerHTML = userContent;

// 10. Insecure Cookies
document.cookie = `${name}=${value}`;

// 11. Dynamic Require
require(moduleName);

// 12. Buffer Issues
const buf = new Buffer(size);

safe-patterns.js (167 行) – 包含不应触发警告的防御模式

// Safe: Validated key access with allowlist
const VALID_KEYS = ['name', 'email', 'age'];
if (VALID_KEYS.includes(key)) {
  return obj[key];
}

// Safe: hasOwnProperty check
if (Object.prototype.hasOwnProperty.call(obj, key)) {
  return obj[key];
}

// Safe: Path validation with startsWith
if (!safePath.startsWith(SAFE_DIR)) throw new Error('Invalid');
fs.readFileSync(safePath);

// Safe: Timing‑safe comparison
crypto.timingSafeEqual(bufA, bufB);

// Safe: DOMPurify sanitization
const clean = DOMPurify.sanitize(userContent);
element.innerHTML = clean;

Benchmark Configuration

  • Iterations: 每个测试 5 次运行
  • Metrics: 平均时间、最小/最大时间、发现的问题、触发的规则
  • Assumption: 运行间方差 ≤ 15 %;报告的差异 (2.83×, 3.8×) 超出此范围

Source:

测试 1 – 公平对决(相同的 14 条规则)

首先,我仅使用两套插件中 相同的 14 条等价规则 进行测试。这确保了在相同条件下的对比。

结果

指标secure-codingsecurity胜者
性能 / 问题24.95 ms25.12 ms🟢 secure-coding
总耗时723.54 ms527.58 ms🔵 security
发现的问题数2921🟢 secure-coding
检测率138 %100 %🟢 secure-coding

按规则检测情况

规则类别securitysecure-coding差异
Timing Attacks15+4 🟢
Child Process24+2 🟢
Non‑literal Regexp13+2 🟢
Eval / Code Execution12+1 🟢
Insufficient Randomness01+1 🟢
FS Path Traversal55=
Object Injection55=
Dynamic Require22=
Unsafe Regex22=
Buffer APIs20-2 🔵
TOTAL2129+8

关键发现: 在相同的规则类别下,secure-coding 发现了 38 % 更多的问题,同时每个问题的效率几乎相同。

Source:

测试 2 – 推荐预设

接下来,我测试了每个插件的推荐配置——开箱即用的体验。

结果

指标secure-codingsecurity胜者
性能 / 问题9.95 ms28.16 ms🟢 secure-coding
总耗时795.99 ms591.41 ms🔵 security
发现的问题8021🟢 secure-coding
触发的规则3010🟢 secure-coding
规则总数8914🟢 secure-coding

检测细分

secure-codingvulnerable.js 上触发的规则:

• no-unvalidated-user-input: 8 个问题
• detect-non-literal-fs-filename: 5 个问题
• detect-object-injection: 5 个问题
• no-timing-attack: 5 个问题
• detect-child-process: 4 个问题
• database-injection: 4 个问题
• no-unsafe-deserialization: 4 个问题
• no-sql-injection: 3 个问题
• detect-non-literal-regexp: 3 个问题
• no-hardcoded-credentials: 2 个问题
• detect-eval-with-expression: 2 个问题
• no-weak-crypto: 2 个问题
... 等等 18 个其他类别

security 触发的规则:

• detect-non-literal-fs-filename: 5 个问题
• detect-object-injection: 5 个问题
• detect-child-process: 2 个问题
• detect-unsafe-regex: 2 个问题
... 等等 6 个其他类别

测试 3 – 假阳性分析

这是精确度至关重要的地方。我对 safe-patterns.js(一个仅包含安全、已验证代码的文件)运行了两个插件。

结果

插件误报数精确率
secure-coding0100 %
security484 %

来自 eslint-plugin-security 的 4 条误报

误报 #1 – 已验证的键访问(第 38 行)

// Pattern: Allowlist validation before access
const VALID_KEYS = ['name', 'email', 'age'];
function getField(obj, key) {
  if (VALID_KEYS.includes(key)) {
    return obj[key]; // ⚠️ security flags "Generic Object Injection Sink"
  }
}

误报 #2 – hasOwnProperty 检查(第 45 行)

// Pattern: Property existence check before access
function safeGet(obj, key) {
  if (Object.prototype.hasOwnProperty.call(obj, key)) {
    return obj[key]; // ⚠️ security flags "Generic Object Injection Sink"
  }
}

误报 #3 – 带 throw 的守卫语句(第 153 行)

// Pattern: Early exit guard clause
const ALLOWED_THEMES = ['light', 'dark', 'system'];
function setTheme(userTheme) {
  if (!ALLOWED_THEMES.includes(userTheme)) {
    throw new Error('Invalid theme');
  }
  config[userTheme] = true; // ⚠️ security flags "Unsafe Assignment"
}

误报 #4 – 时间安全比较(第 212 行)

// Pattern: Timing‑safe equality check
if (crypto.timingSafeEqual(bufA, bufB)) {
  // safe branch
}

误报 #4:路径验证(第 107 行)

// Pattern: basename + startsWith validation
function safeReadFile(userFilename) {
  const safeName = path.basename(userFilename);
  const safePath = path.join(SAFE_DIR, safeName);

  if (!safePath.startsWith(SAFE_DIR)) {
    throw new Error('Invalid path');
  }

  return fs.readFileSync(safePath); // ⚠️ security flags "non literal argument"
}

该路径已完全验证:basename 去除路径遍历,startsWith 确认目录。

为什么 secure-coding 能避免这些

我们使用 基于 AST 的验证检测

模式检测方法
allowlist.includes(key)检查在外层 if 语句中是否使用 includes()
hasOwnProperty(key)检查是否调用 hasOwnProperty / hasOwn
Guard clause + throw检测前置的带提前退出的 IfStatement
startsWith() 验证检测路径验证模式

OWASP 覆盖比较

覆盖范围secure-codingsecurity
OWASP Web Top 1010/10 (100 %)~3/10 (~30 %)
OWASP Mobile Top 1010/10 (100 %)0/10 (0 %)
总计20/20~3/20

LLM/AI 消息比较

安全规则正被 AI 编码助手越来越多地使用。比较以下消息:

eslint-plugin-security

Found child_process.exec() with non Literal first argument

eslint-plugin-secure-coding

🔒 CWE-78 OWASP:A03‑Injection CVSS:9.8 | Command injection detected | CRITICAL
   Fix: Use execFile/spawn with {shell: false} and array args
   📚 https://owasp.org/www-community/attacks/Command_Injection
Featuresecure-codingsecurity
CWE ID
OWASP Category
CVSS Score
Fix Instructions
Documentation Link

功能与文档比较

功能secure-codingsecurity
规则总数8914
文档Comprehensive (per‑rule) → 全面(每条规则)Basic → 基础
修复建议/规则3‑6 suggestions → 3‑6 条建议0
CWE 引用✅ All rules → ✅ 所有规则❌ None → ❌ 无
CVSS 分数✅ Yes → ✅ 是❌ No → ❌ 否
OWASP 映射✅ Web + Mobile❌ None
TypeScript 支持✅ Full → ✅ 完整⚠️ Partial → ⚠️ 部分
Flat Config 支持✅ Native✅ Native
预设minimal, recommended, strictrecommended
最近更新Active → 活跃Maintenance mode → 维护模式

最终判定

类别secure-codingsecurity胜者
性能/问题9.95 ms28.16 ms🟢 secure-coding
检测80 个问题21 个问题🟢 secure-coding
假阳性04🟢 secure-coding
精确率100 %84 %🟢 secure-coding
规则总数8914🟢 secure-coding
OWASP 覆盖率20/20~3/20🟢 secure-coding
文档完整基础🟢 secure-coding
修复建议每条规则 3‑6 条0🟢 secure-coding
LLM 优化⭐⭐⭐⭐⭐⭐⭐🟢 secure-coding

关键洞察

  • 每个问题的性能很重要secure-coding 在每个检测到的问题上效率提升 2.83×
  • “速度优势” = 检测差距 – 现有方案看似更快,仅因为它 漏掉 漏洞。
  • 0 假阳性 – 每个标记的问题都是实际漏洞。
  • 规则数量提升 6 倍 – 89 条规则对比 14 条,覆盖 Web、移动、API 和 AI 安全。
  • 开发者体验 – 每条规则都包含 CWE/OWASP 引用、CVSS 分数以及 3‑6 条修复建议。

立即尝试

npm install eslint-plugin-secure-coding --save-dev
// eslint.config.js
import secureCoding from 'eslint-plugin-secure-coding';

export default [secureCoding.configs.recommended];

基准代码是开源的:
benchmark on GitHub

Back to Blog

相关文章

阅读更多 »