eslint-plugin-secure-coding 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +196 -0
- package/CHANGELOG.md +105 -0
- package/LICENSE +23 -0
- package/README.md +377 -0
- package/package.json +80 -0
- package/src/index.d.ts +32 -0
- package/src/index.js +345 -0
- package/src/index.js.map +1 -0
- package/src/rules/security/database-injection.d.ts +13 -0
- package/src/rules/security/database-injection.js +407 -0
- package/src/rules/security/database-injection.js.map +1 -0
- package/src/rules/security/detect-child-process.d.ts +11 -0
- package/src/rules/security/detect-child-process.js +460 -0
- package/src/rules/security/detect-child-process.js.map +1 -0
- package/src/rules/security/detect-eval-with-expression.d.ts +9 -0
- package/src/rules/security/detect-eval-with-expression.js +393 -0
- package/src/rules/security/detect-eval-with-expression.js.map +1 -0
- package/src/rules/security/detect-non-literal-fs-filename.d.ts +7 -0
- package/src/rules/security/detect-non-literal-fs-filename.js +322 -0
- package/src/rules/security/detect-non-literal-fs-filename.js.map +1 -0
- package/src/rules/security/detect-non-literal-regexp.d.ts +9 -0
- package/src/rules/security/detect-non-literal-regexp.js +387 -0
- package/src/rules/security/detect-non-literal-regexp.js.map +1 -0
- package/src/rules/security/detect-object-injection.d.ts +11 -0
- package/src/rules/security/detect-object-injection.js +411 -0
- package/src/rules/security/detect-object-injection.js.map +1 -0
- package/src/rules/security/no-buffer-overread.d.ts +14 -0
- package/src/rules/security/no-buffer-overread.js +519 -0
- package/src/rules/security/no-buffer-overread.js.map +1 -0
- package/src/rules/security/no-clickjacking.d.ts +10 -0
- package/src/rules/security/no-clickjacking.js +381 -0
- package/src/rules/security/no-clickjacking.js.map +1 -0
- package/src/rules/security/no-directive-injection.d.ts +12 -0
- package/src/rules/security/no-directive-injection.js +446 -0
- package/src/rules/security/no-directive-injection.js.map +1 -0
- package/src/rules/security/no-document-cookie.d.ts +5 -0
- package/src/rules/security/no-document-cookie.js +90 -0
- package/src/rules/security/no-document-cookie.js.map +1 -0
- package/src/rules/security/no-electron-security-issues.d.ts +10 -0
- package/src/rules/security/no-electron-security-issues.js +421 -0
- package/src/rules/security/no-electron-security-issues.js.map +1 -0
- package/src/rules/security/no-exposed-sensitive-data.d.ts +11 -0
- package/src/rules/security/no-exposed-sensitive-data.js +341 -0
- package/src/rules/security/no-exposed-sensitive-data.js.map +1 -0
- package/src/rules/security/no-format-string-injection.d.ts +17 -0
- package/src/rules/security/no-format-string-injection.js +653 -0
- package/src/rules/security/no-format-string-injection.js.map +1 -0
- package/src/rules/security/no-graphql-injection.d.ts +12 -0
- package/src/rules/security/no-graphql-injection.js +410 -0
- package/src/rules/security/no-graphql-injection.js.map +1 -0
- package/src/rules/security/no-hardcoded-credentials.d.ts +26 -0
- package/src/rules/security/no-hardcoded-credentials.js +377 -0
- package/src/rules/security/no-hardcoded-credentials.js.map +1 -0
- package/src/rules/security/no-improper-sanitization.d.ts +12 -0
- package/src/rules/security/no-improper-sanitization.js +408 -0
- package/src/rules/security/no-improper-sanitization.js.map +1 -0
- package/src/rules/security/no-improper-type-validation.d.ts +10 -0
- package/src/rules/security/no-improper-type-validation.js +420 -0
- package/src/rules/security/no-improper-type-validation.js.map +1 -0
- package/src/rules/security/no-insecure-comparison.d.ts +7 -0
- package/src/rules/security/no-insecure-comparison.js +125 -0
- package/src/rules/security/no-insecure-comparison.js.map +1 -0
- package/src/rules/security/no-insecure-cookie-settings.d.ts +9 -0
- package/src/rules/security/no-insecure-cookie-settings.js +305 -0
- package/src/rules/security/no-insecure-cookie-settings.js.map +1 -0
- package/src/rules/security/no-insecure-jwt.d.ts +10 -0
- package/src/rules/security/no-insecure-jwt.js +338 -0
- package/src/rules/security/no-insecure-jwt.js.map +1 -0
- package/src/rules/security/no-insecure-redirects.d.ts +7 -0
- package/src/rules/security/no-insecure-redirects.js +215 -0
- package/src/rules/security/no-insecure-redirects.js.map +1 -0
- package/src/rules/security/no-insufficient-postmessage-validation.d.ts +14 -0
- package/src/rules/security/no-insufficient-postmessage-validation.js +390 -0
- package/src/rules/security/no-insufficient-postmessage-validation.js.map +1 -0
- package/src/rules/security/no-insufficient-random.d.ts +9 -0
- package/src/rules/security/no-insufficient-random.js +207 -0
- package/src/rules/security/no-insufficient-random.js.map +1 -0
- package/src/rules/security/no-ldap-injection.d.ts +10 -0
- package/src/rules/security/no-ldap-injection.js +449 -0
- package/src/rules/security/no-ldap-injection.js.map +1 -0
- package/src/rules/security/no-missing-authentication.d.ts +13 -0
- package/src/rules/security/no-missing-authentication.js +322 -0
- package/src/rules/security/no-missing-authentication.js.map +1 -0
- package/src/rules/security/no-missing-cors-check.d.ts +9 -0
- package/src/rules/security/no-missing-cors-check.js +449 -0
- package/src/rules/security/no-missing-cors-check.js.map +1 -0
- package/src/rules/security/no-missing-csrf-protection.d.ts +11 -0
- package/src/rules/security/no-missing-csrf-protection.js +183 -0
- package/src/rules/security/no-missing-csrf-protection.js.map +1 -0
- package/src/rules/security/no-missing-security-headers.d.ts +7 -0
- package/src/rules/security/no-missing-security-headers.js +217 -0
- package/src/rules/security/no-missing-security-headers.js.map +1 -0
- package/src/rules/security/no-privilege-escalation.d.ts +13 -0
- package/src/rules/security/no-privilege-escalation.js +321 -0
- package/src/rules/security/no-privilege-escalation.js.map +1 -0
- package/src/rules/security/no-redos-vulnerable-regex.d.ts +7 -0
- package/src/rules/security/no-redos-vulnerable-regex.js +307 -0
- package/src/rules/security/no-redos-vulnerable-regex.js.map +1 -0
- package/src/rules/security/no-sensitive-data-exposure.d.ts +11 -0
- package/src/rules/security/no-sensitive-data-exposure.js +251 -0
- package/src/rules/security/no-sensitive-data-exposure.js.map +1 -0
- package/src/rules/security/no-sql-injection.d.ts +10 -0
- package/src/rules/security/no-sql-injection.js +332 -0
- package/src/rules/security/no-sql-injection.js.map +1 -0
- package/src/rules/security/no-timing-attack.d.ts +10 -0
- package/src/rules/security/no-timing-attack.js +358 -0
- package/src/rules/security/no-timing-attack.js.map +1 -0
- package/src/rules/security/no-toctou-vulnerability.d.ts +7 -0
- package/src/rules/security/no-toctou-vulnerability.js +165 -0
- package/src/rules/security/no-toctou-vulnerability.js.map +1 -0
- package/src/rules/security/no-unchecked-loop-condition.d.ts +12 -0
- package/src/rules/security/no-unchecked-loop-condition.js +635 -0
- package/src/rules/security/no-unchecked-loop-condition.js.map +1 -0
- package/src/rules/security/no-unencrypted-transmission.d.ts +11 -0
- package/src/rules/security/no-unencrypted-transmission.js +237 -0
- package/src/rules/security/no-unencrypted-transmission.js.map +1 -0
- package/src/rules/security/no-unescaped-url-parameter.d.ts +9 -0
- package/src/rules/security/no-unescaped-url-parameter.js +266 -0
- package/src/rules/security/no-unescaped-url-parameter.js.map +1 -0
- package/src/rules/security/no-unlimited-resource-allocation.d.ts +12 -0
- package/src/rules/security/no-unlimited-resource-allocation.js +659 -0
- package/src/rules/security/no-unlimited-resource-allocation.js.map +1 -0
- package/src/rules/security/no-unsafe-deserialization.d.ts +10 -0
- package/src/rules/security/no-unsafe-deserialization.js +501 -0
- package/src/rules/security/no-unsafe-deserialization.js.map +1 -0
- package/src/rules/security/no-unsafe-dynamic-require.d.ts +5 -0
- package/src/rules/security/no-unsafe-dynamic-require.js +107 -0
- package/src/rules/security/no-unsafe-dynamic-require.js.map +1 -0
- package/src/rules/security/no-unsafe-regex-construction.d.ts +9 -0
- package/src/rules/security/no-unsafe-regex-construction.js +292 -0
- package/src/rules/security/no-unsafe-regex-construction.js.map +1 -0
- package/src/rules/security/no-unsanitized-html.d.ts +9 -0
- package/src/rules/security/no-unsanitized-html.js +347 -0
- package/src/rules/security/no-unsanitized-html.js.map +1 -0
- package/src/rules/security/no-unvalidated-user-input.d.ts +9 -0
- package/src/rules/security/no-unvalidated-user-input.js +418 -0
- package/src/rules/security/no-unvalidated-user-input.js.map +1 -0
- package/src/rules/security/no-weak-crypto.d.ts +11 -0
- package/src/rules/security/no-weak-crypto.js +350 -0
- package/src/rules/security/no-weak-crypto.js.map +1 -0
- package/src/rules/security/no-weak-password-recovery.d.ts +12 -0
- package/src/rules/security/no-weak-password-recovery.js +401 -0
- package/src/rules/security/no-weak-password-recovery.js.map +1 -0
- package/src/rules/security/no-xpath-injection.d.ts +10 -0
- package/src/rules/security/no-xpath-injection.js +487 -0
- package/src/rules/security/no-xpath-injection.js.map +1 -0
- package/src/rules/security/no-xxe-injection.d.ts +7 -0
- package/src/rules/security/no-xxe-injection.js +270 -0
- package/src/rules/security/no-xxe-injection.js.map +1 -0
- package/src/rules/security/no-zip-slip.d.ts +9 -0
- package/src/rules/security/no-zip-slip.js +446 -0
- package/src/rules/security/no-zip-slip.js.map +1 -0
- package/src/types/index.d.ts +131 -0
- package/src/types/index.js +18 -0
- package/src/types/index.js.map +1 -0
package/README.md
ADDED
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
# eslint-plugin-secure-coding
|
|
2
|
+
|
|
3
|
+
**Feature-based security rules that AI assistants can actually understand and fix.**
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/eslint-plugin-secure-coding)
|
|
6
|
+
[](https://www.npmjs.com/package/eslint-plugin-secure-coding)
|
|
7
|
+
[](https://opensource.org/licenses/MIT)
|
|
8
|
+
|
|
9
|
+
> A comprehensive, feature-based security ESLint plugin with **45+ rules** mapped to OWASP Top 10, CWE, and CVSS, featuring LLM-optimized (MCP-ready) messages that guide developers toward secure code in enterprise environments.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## 💡 What you get
|
|
14
|
+
|
|
15
|
+
- **Feature-based coverage:** 45+ rules grouped by attack surface (injection, crypto, auth, cookies, headers, resource limits, platform specifics).
|
|
16
|
+
- **LLM-optimized & MCP-ready:** Structured 2-line messages with CWE + OWASP + CVSS + concrete fixes so humans _and_ AI auto-fixers stay aligned.
|
|
17
|
+
- **Standards aligned:** OWASP Top 10, CWE tagging, CVSS scoring in every finding for compliance mapping.
|
|
18
|
+
- **Tiered presets:** `recommended`, `strict`, `owasp-top-10`, plus LLM/MCP presets for agent/tool code.
|
|
19
|
+
- **False-positive reduction:** Sanitizer awareness, annotations, ORM patterns, and safe-library detection keep noise low for org rollouts.
|
|
20
|
+
|
|
21
|
+
Every security rule produces a **structured 2-line error message**:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
src/api.ts
|
|
25
|
+
42:15 error 🔒 CWE-89 OWASP:A03-Injection CVSS:9.8 | SQL Injection detected | CRITICAL [SOC2,PCI-DSS,HIPAA]
|
|
26
|
+
Fix: Use parameterized query: db.query("SELECT * FROM users WHERE id = ?", [userId]) | https://owasp.org/...
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
**Each message includes:**
|
|
30
|
+
|
|
31
|
+
- 🔒 **CWE reference** - vulnerability classification
|
|
32
|
+
- 📋 **OWASP category** - Top 10 mapping (e.g., `OWASP:A03-Injection`)
|
|
33
|
+
- 📊 **CVSS score** - severity rating (0.0-10.0)
|
|
34
|
+
- 🏢 **Compliance tags** - affected frameworks (SOC2, PCI-DSS, HIPAA)
|
|
35
|
+
- ✅ **Fix instruction** - exact code to write
|
|
36
|
+
- 📚 **Documentation link** - learn more
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## 🚀 Quick Start (Org-friendly)
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
# Install
|
|
44
|
+
npm install --save-dev eslint-plugin-secure-coding
|
|
45
|
+
|
|
46
|
+
# Add to eslint.config.js
|
|
47
|
+
import secureCoding from 'eslint-plugin-secure-coding';
|
|
48
|
+
|
|
49
|
+
export default [
|
|
50
|
+
secureCoding.configs.recommended, // baseline for most repos
|
|
51
|
+
{ files: ['apps/**'], ...secureCoding.configs['owasp-top-10'] }, // public-facing
|
|
52
|
+
{ files: ['services/auth/**', 'services/payments/**'], ...secureCoding.configs.strict }, // crown jewels
|
|
53
|
+
];
|
|
54
|
+
|
|
55
|
+
# Run
|
|
56
|
+
npx eslint .
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## 📋 Available Presets (policy tiers)
|
|
62
|
+
|
|
63
|
+
| Preset | Description |
|
|
64
|
+
| --------------------- | --------------------------------------------------------------------------- |
|
|
65
|
+
| **`recommended`** | Balanced security for most projects (45+ rules, mixed severity) |
|
|
66
|
+
| **`strict`** | Maximum security enforcement (all rules as errors) |
|
|
67
|
+
| **`owasp-top-10`** | OWASP Top 10 2021 compliance focused |
|
|
68
|
+
| **`recommended-llm`** | LLM-friendly baseline; adds harder stances on deserialization/network paths |
|
|
69
|
+
| **`recommended-mcp`** | MCP/agent-focused; tightens process/fs/net/deserialize/resource controls |
|
|
70
|
+
| **`strict-mcp`** | All rules as errors for MCP/agent surfaces |
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## 📚 Documentation
|
|
75
|
+
|
|
76
|
+
- **[Rules Reference](./docs/RULES.md)** - Complete list of all 48 rules with configuration options
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## 🤖 LLM/MCP Hardening & Quickstart
|
|
81
|
+
|
|
82
|
+
| Use case | Config snippet |
|
|
83
|
+
| ----------------------- | ----------------------------------------- |
|
|
84
|
+
| LLM-aware defaults | `secureCoding.configs['recommended-llm']` |
|
|
85
|
+
| MCP/tool-aware defaults | `secureCoding.configs['recommended-mcp']` |
|
|
86
|
+
| Strict for agents/tools | `secureCoding.configs['strict-mcp']` |
|
|
87
|
+
|
|
88
|
+
Example `eslint.config.js`:
|
|
89
|
+
|
|
90
|
+
```js
|
|
91
|
+
import secureCoding from 'eslint-plugin-secure-coding';
|
|
92
|
+
|
|
93
|
+
export default [
|
|
94
|
+
secureCoding.configs.recommended,
|
|
95
|
+
secureCoding.configs['recommended-llm'],
|
|
96
|
+
secureCoding.configs['recommended-mcp'],
|
|
97
|
+
];
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
**eslint.config.js (CommonJS with types):**
|
|
101
|
+
|
|
102
|
+
```js
|
|
103
|
+
// @ts-check
|
|
104
|
+
const secureCoding = require('eslint-plugin-secure-coding');
|
|
105
|
+
|
|
106
|
+
/** @type {import('eslint').Linter.FlatConfig[]} */
|
|
107
|
+
module.exports = [
|
|
108
|
+
secureCoding.configs.recommended,
|
|
109
|
+
secureCoding.configs['recommended-llm'],
|
|
110
|
+
secureCoding.configs['recommended-mcp'],
|
|
111
|
+
];
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
**eslint.config.ts (TypeScript):**
|
|
115
|
+
|
|
116
|
+
```ts
|
|
117
|
+
import type { Linter } from 'eslint';
|
|
118
|
+
import secureCoding from 'eslint-plugin-secure-coding';
|
|
119
|
+
|
|
120
|
+
export default [
|
|
121
|
+
secureCoding.configs.recommended,
|
|
122
|
+
secureCoding.configs['recommended-llm'],
|
|
123
|
+
secureCoding.configs['recommended-mcp'],
|
|
124
|
+
] satisfies Linter.FlatConfig[];
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Hardening highlights (LLM/MCP):
|
|
128
|
+
|
|
129
|
+
- Treat model/tool outputs as untrusted: schema-validate, size-cap, and allowlist fields before using.
|
|
130
|
+
- Block risky surfaces from agent code: require allowlists for fs/net/exec/tool params; set timeouts and retries.
|
|
131
|
+
- Redact secrets/PII before sending to models or logs.
|
|
132
|
+
- Prefer `execFile`/`shell:false` and HTTPS-only URLs; disallow internal IP ranges.
|
|
133
|
+
|
|
134
|
+
Troubleshooting:
|
|
135
|
+
|
|
136
|
+
- False positives on known-safe keys: add allowlists/ignore patterns sparingly; keep validation in place.
|
|
137
|
+
- Slow runs: disable unused presets per `files` globs or narrow include paths.
|
|
138
|
+
- Still noisy: tighten options on specific rules (deserialization/object-injection/child-process/fs filename).
|
|
139
|
+
|
|
140
|
+
### What an error looks like (LLM-optimized)
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
src/api.ts
|
|
144
|
+
42:15 error 🔒 CWE-89 OWASP:A03-Injection CVSS:9.8 | SQL Injection detected | CRITICAL [SOC2,PCI-DSS,HIPAA]
|
|
145
|
+
Fix: Use parameterized query: db.query("SELECT * FROM users WHERE id = ?", [userId]) | https://owasp.org/...
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Each finding includes:
|
|
149
|
+
|
|
150
|
+
- CWE + OWASP + CVSS for compliance mapping
|
|
151
|
+
- Severity and compliance tags
|
|
152
|
+
- A ready-to-apply fix suggestion and a doc link (LLM-friendly)
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## 🏢 Enterprise Integration Example
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
# Install once at the repo root
|
|
160
|
+
pnpm add -D eslint-plugin-secure-coding
|
|
161
|
+
|
|
162
|
+
# eslint.config.js (org-standard)
|
|
163
|
+
import secureCoding from 'eslint-plugin-secure-coding';
|
|
164
|
+
|
|
165
|
+
export default [
|
|
166
|
+
// Baseline for all services (balanced)
|
|
167
|
+
secureCoding.configs.recommended,
|
|
168
|
+
|
|
169
|
+
// LLM-aware defaults (prompts/templates/logging safeguards)
|
|
170
|
+
secureCoding.configs['recommended-llm'],
|
|
171
|
+
|
|
172
|
+
// MCP/tool-aware defaults (process/fs/net/deserialize/resource tightened)
|
|
173
|
+
secureCoding.configs['recommended-mcp'],
|
|
174
|
+
|
|
175
|
+
// Add OWASP Top 10 enforcement for internet-facing apps
|
|
176
|
+
{
|
|
177
|
+
files: ['apps/**'],
|
|
178
|
+
...secureCoding.configs['owasp-top-10'],
|
|
179
|
+
},
|
|
180
|
+
|
|
181
|
+
// Force strict mode for critical backend services
|
|
182
|
+
{
|
|
183
|
+
files: ['services/payments/**', 'services/auth/**'],
|
|
184
|
+
...secureCoding.configs.strict,
|
|
185
|
+
},
|
|
186
|
+
];
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
What this gives organizations:
|
|
190
|
+
|
|
191
|
+
- OWASP/CWE/CVSS metadata in every finding for compliance mapping
|
|
192
|
+
- Consistent, LLM-ready fixes that teammates and AI can apply safely
|
|
193
|
+
- Tiered policies (baseline, OWASP-focused, strict) per surface area
|
|
194
|
+
|
|
195
|
+
---
|
|
196
|
+
|
|
197
|
+
## 🔐 48 Security Rules
|
|
198
|
+
|
|
199
|
+
💼 = Set in `recommended` | ⚠️ = Warns in `recommended` | 🔧 = Auto-fixable | 💡 = Suggestions
|
|
200
|
+
|
|
201
|
+
### Injection Prevention (11 rules)
|
|
202
|
+
|
|
203
|
+
| Rule | CWE | OWASP | CVSS | Description | 💼 | ⚠️ | 🔧 | 💡 |
|
|
204
|
+
| -------------------------------------------------------------------------- | ------- | ----- | ---- | ----------------------------------------------- | --- | --- | --- | --- |
|
|
205
|
+
| [no-sql-injection](./docs/rules/no-sql-injection.md) | CWE-89 | A03 | 9.8 | Prevent SQL injection via string concatenation | 💼 | | | |
|
|
206
|
+
| [database-injection](./docs/rules/database-injection.md) | CWE-89 | A03 | 9.8 | Comprehensive SQL/NoSQL/ORM injection detection | 💼 | | | |
|
|
207
|
+
| [detect-eval-with-expression](./docs/rules/detect-eval-with-expression.md) | CWE-95 | A03 | 9.8 | Detect eval() with dynamic expressions | 💼 | | | |
|
|
208
|
+
| [detect-child-process](./docs/rules/detect-child-process.md) | CWE-78 | A03 | 9.8 | Detect command injection in child_process | 💼 | | | |
|
|
209
|
+
| [no-unsafe-dynamic-require](./docs/rules/no-unsafe-dynamic-require.md) | CWE-95 | A03 | 7.5 | Forbid dynamic require() calls | 💼 | | | |
|
|
210
|
+
| [no-graphql-injection](./docs/rules/no-graphql-injection.md) | CWE-943 | A03 | 8.6 | Prevent GraphQL injection attacks | 💼 | | | |
|
|
211
|
+
| [no-xxe-injection](./docs/rules/no-xxe-injection.md) | CWE-611 | A03 | 9.1 | Prevent XML External Entity injection | 💼 | | | |
|
|
212
|
+
| [no-xpath-injection](./docs/rules/no-xpath-injection.md) | CWE-643 | A03 | 9.8 | Prevent XPath injection attacks | 💼 | | | |
|
|
213
|
+
| [no-ldap-injection](./docs/rules/no-ldap-injection.md) | CWE-90 | A03 | 9.8 | Prevent LDAP injection attacks | 💼 | | | |
|
|
214
|
+
| [no-directive-injection](./docs/rules/no-directive-injection.md) | CWE-94 | A03 | 8.8 | Prevent template directive injection | 💼 | | | |
|
|
215
|
+
| [no-format-string-injection](./docs/rules/no-format-string-injection.md) | CWE-134 | A03 | 9.8 | Prevent format string vulnerabilities | 💼 | | | |
|
|
216
|
+
|
|
217
|
+
### Path & File Security (3 rules)
|
|
218
|
+
|
|
219
|
+
| Rule | CWE | OWASP | CVSS | Description | 💼 | ⚠️ | 🔧 | 💡 |
|
|
220
|
+
| -------------------------------------------------------------------------------- | ------- | ----- | ---- | ----------------------------------------- | --- | --- | --- | --- |
|
|
221
|
+
| [detect-non-literal-fs-filename](./docs/rules/detect-non-literal-fs-filename.md) | CWE-22 | A01 | 7.5 | Detect path traversal in fs operations | 💼 | | | |
|
|
222
|
+
| [no-zip-slip](./docs/rules/no-zip-slip.md) | CWE-22 | A01 | 8.1 | Prevent zip slip vulnerabilities | 💼 | | | |
|
|
223
|
+
| [no-toctou-vulnerability](./docs/rules/no-toctou-vulnerability.md) | CWE-367 | A01 | 7.0 | Detect time-of-check to time-of-use races | 💼 | | | 💡 |
|
|
224
|
+
|
|
225
|
+
### Regex Security (3 rules)
|
|
226
|
+
|
|
227
|
+
| Rule | CWE | OWASP | CVSS | Description | 💼 | ⚠️ | 🔧 | 💡 |
|
|
228
|
+
| ---------------------------------------------------------------------------- | -------- | ----- | ---- | ------------------------------------ | --- | --- | --- | --- |
|
|
229
|
+
| [detect-non-literal-regexp](./docs/rules/detect-non-literal-regexp.md) | CWE-400 | A03 | 7.5 | Detect ReDoS in RegExp construction | | ⚠️ | | |
|
|
230
|
+
| [no-redos-vulnerable-regex](./docs/rules/no-redos-vulnerable-regex.md) | CWE-1333 | A03 | 7.5 | Detect ReDoS-vulnerable patterns | 💼 | | | 💡 |
|
|
231
|
+
| [no-unsafe-regex-construction](./docs/rules/no-unsafe-regex-construction.md) | CWE-400 | A03 | 7.5 | Prevent unsafe regex from user input | | ⚠️ | | 💡 |
|
|
232
|
+
|
|
233
|
+
### Object & Prototype (2 rules)
|
|
234
|
+
|
|
235
|
+
| Rule | CWE | OWASP | CVSS | Description | 💼 | ⚠️ | 🔧 | 💡 |
|
|
236
|
+
| ---------------------------------------------------------------------- | ------- | ----- | ---- | ------------------------------ | --- | --- | --- | --- |
|
|
237
|
+
| [detect-object-injection](./docs/rules/detect-object-injection.md) | CWE-915 | A03 | 7.3 | Detect prototype pollution | | ⚠️ | | |
|
|
238
|
+
| [no-unsafe-deserialization](./docs/rules/no-unsafe-deserialization.md) | CWE-502 | A08 | 9.8 | Prevent unsafe deserialization | 💼 | | | |
|
|
239
|
+
|
|
240
|
+
### Cryptography (6 rules)
|
|
241
|
+
|
|
242
|
+
| Rule | CWE | OWASP | CVSS | Description | 💼 | ⚠️ | 🔧 | 💡 |
|
|
243
|
+
| -------------------------------------------------------------------- | ------- | ----- | ---- | ------------------------------------ | --- | --- | --- | --- |
|
|
244
|
+
| [no-hardcoded-credentials](./docs/rules/no-hardcoded-credentials.md) | CWE-798 | A07 | 7.5 | Detect hardcoded passwords/keys | 💼 | | | |
|
|
245
|
+
| [no-weak-crypto](./docs/rules/no-weak-crypto.md) | CWE-327 | A02 | 7.5 | Detect weak algorithms (MD5, SHA1) | 💼 | | | |
|
|
246
|
+
| [no-insufficient-random](./docs/rules/no-insufficient-random.md) | CWE-330 | A02 | 5.3 | Detect Math.random() for security | | ⚠️ | | |
|
|
247
|
+
| [no-timing-attack](./docs/rules/no-timing-attack.md) | CWE-208 | A02 | 5.9 | Detect timing attack vulnerabilities | 💼 | | | |
|
|
248
|
+
| [no-insecure-comparison](./docs/rules/no-insecure-comparison.md) | CWE-697 | A02 | 5.3 | Detect insecure string comparison | | ⚠️ | 🔧 | |
|
|
249
|
+
| [no-insecure-jwt](./docs/rules/no-insecure-jwt.md) | CWE-347 | A02 | 7.5 | Detect JWT security issues | 💼 | | | |
|
|
250
|
+
|
|
251
|
+
### Input Validation & XSS (5 rules)
|
|
252
|
+
|
|
253
|
+
| Rule | CWE | OWASP | CVSS | Description | 💼 | ⚠️ | 🔧 | 💡 |
|
|
254
|
+
| -------------------------------------------------------------------------- | ------- | ----- | ---- | ------------------------------------- | --- | --- | --- | --- |
|
|
255
|
+
| [no-unvalidated-user-input](./docs/rules/no-unvalidated-user-input.md) | CWE-20 | A03 | 8.6 | Detect unvalidated user input | | ⚠️ | | |
|
|
256
|
+
| [no-unsanitized-html](./docs/rules/no-unsanitized-html.md) | CWE-79 | A03 | 6.1 | Detect XSS via innerHTML | 💼 | | | |
|
|
257
|
+
| [no-unescaped-url-parameter](./docs/rules/no-unescaped-url-parameter.md) | CWE-79 | A03 | 6.1 | Detect XSS via URL parameters | | ⚠️ | | |
|
|
258
|
+
| [no-improper-sanitization](./docs/rules/no-improper-sanitization.md) | CWE-116 | A03 | 7.5 | Detect improper output encoding | 💼 | | | |
|
|
259
|
+
| [no-improper-type-validation](./docs/rules/no-improper-type-validation.md) | CWE-20 | A04 | 5.3 | Detect type confusion vulnerabilities | | ⚠️ | | |
|
|
260
|
+
|
|
261
|
+
### Authentication & Authorization (3 rules)
|
|
262
|
+
|
|
263
|
+
| Rule | CWE | OWASP | CVSS | Description | 💼 | ⚠️ | 🔧 | 💡 |
|
|
264
|
+
| ---------------------------------------------------------------------- | ------- | ----- | ---- | ------------------------------ | --- | --- | --- | --- |
|
|
265
|
+
| [no-missing-authentication](./docs/rules/no-missing-authentication.md) | CWE-306 | A07 | 9.8 | Detect missing auth checks | | ⚠️ | | |
|
|
266
|
+
| [no-privilege-escalation](./docs/rules/no-privilege-escalation.md) | CWE-269 | A01 | 8.8 | Detect privilege escalation | | ⚠️ | | |
|
|
267
|
+
| [no-weak-password-recovery](./docs/rules/no-weak-password-recovery.md) | CWE-640 | A07 | 9.8 | Detect insecure password reset | 💼 | | | |
|
|
268
|
+
|
|
269
|
+
### Session & Cookies (3 rules)
|
|
270
|
+
|
|
271
|
+
| Rule | CWE | OWASP | CVSS | Description | 💼 | ⚠️ | 🔧 | 💡 |
|
|
272
|
+
| -------------------------------------------------------------------------- | ------- | ----- | ---- | --------------------------------- | --- | --- | --- | --- |
|
|
273
|
+
| [no-insecure-cookie-settings](./docs/rules/no-insecure-cookie-settings.md) | CWE-614 | A07 | 5.3 | Detect missing Secure/HttpOnly | | ⚠️ | | |
|
|
274
|
+
| [no-missing-csrf-protection](./docs/rules/no-missing-csrf-protection.md) | CWE-352 | A07 | 8.8 | Detect missing CSRF tokens | | ⚠️ | | |
|
|
275
|
+
| [no-document-cookie](./docs/rules/no-document-cookie.md) | CWE-565 | A07 | 4.3 | Detect direct cookie manipulation | | ⚠️ | | 💡 |
|
|
276
|
+
|
|
277
|
+
### Network & Headers (5 rules)
|
|
278
|
+
|
|
279
|
+
| Rule | CWE | OWASP | CVSS | Description | 💼 | ⚠️ | 🔧 | 💡 |
|
|
280
|
+
| -------------------------------------------------------------------------- | -------- | ----- | ---- | ------------------------------------ | --- | --- | --- | --- |
|
|
281
|
+
| [no-missing-cors-check](./docs/rules/no-missing-cors-check.md) | CWE-942 | A05 | 7.5 | Detect missing CORS validation | | ⚠️ | | |
|
|
282
|
+
| [no-missing-security-headers](./docs/rules/no-missing-security-headers.md) | CWE-693 | A05 | 5.3 | Detect missing security headers | | ⚠️ | | 💡 |
|
|
283
|
+
| [no-insecure-redirects](./docs/rules/no-insecure-redirects.md) | CWE-601 | A01 | 6.1 | Detect open redirect vulnerabilities | | ⚠️ | | 💡 |
|
|
284
|
+
| [no-unencrypted-transmission](./docs/rules/no-unencrypted-transmission.md) | CWE-319 | A02 | 7.5 | Detect HTTP instead of HTTPS | | ⚠️ | | |
|
|
285
|
+
| [no-clickjacking](./docs/rules/no-clickjacking.md) | CWE-1021 | A05 | 6.1 | Detect clickjacking vulnerabilities | 💼 | | | |
|
|
286
|
+
|
|
287
|
+
### Data Exposure (2 rules)
|
|
288
|
+
|
|
289
|
+
| Rule | CWE | OWASP | CVSS | Description | 💼 | ⚠️ | 🔧 | 💡 |
|
|
290
|
+
| ------------------------------------------------------------------------ | ------- | ----- | ---- | ---------------------------------- | --- | --- | --- | --- |
|
|
291
|
+
| [no-exposed-sensitive-data](./docs/rules/no-exposed-sensitive-data.md) | CWE-200 | A01 | 7.5 | Detect sensitive data in responses | 💼 | | | |
|
|
292
|
+
| [no-sensitive-data-exposure](./docs/rules/no-sensitive-data-exposure.md) | CWE-532 | A09 | 5.5 | Detect sensitive data in logs | | ⚠️ | | 💡 |
|
|
293
|
+
|
|
294
|
+
### Buffer, Memory & DoS (3 rules)
|
|
295
|
+
|
|
296
|
+
| Rule | CWE | OWASP | CVSS | Description | 💼 | ⚠️ | 🔧 | 💡 |
|
|
297
|
+
| ------------------------------------------------------------------------------------ | ------- | ----- | ---- | ------------------------------- | --- | --- | --- | --- |
|
|
298
|
+
| [no-buffer-overread](./docs/rules/no-buffer-overread.md) | CWE-126 | A06 | 7.5 | Detect buffer over-read | 💼 | | | |
|
|
299
|
+
| [no-unlimited-resource-allocation](./docs/rules/no-unlimited-resource-allocation.md) | CWE-770 | A05 | 7.5 | Detect unbounded allocations | 💼 | | | |
|
|
300
|
+
| [no-unchecked-loop-condition](./docs/rules/no-unchecked-loop-condition.md) | CWE-835 | A05 | 7.5 | Detect infinite loop conditions | 💼 | | | |
|
|
301
|
+
|
|
302
|
+
### Platform-Specific (2 rules)
|
|
303
|
+
|
|
304
|
+
| Rule | CWE | OWASP | CVSS | Description | 💼 | ⚠️ | 🔧 | 💡 |
|
|
305
|
+
| ------------------------------------------------------------------------------------------------ | ------- | ----- | ---- | ---------------------------------- | --- | --- | --- | --- |
|
|
306
|
+
| [no-electron-security-issues](./docs/rules/no-electron-security-issues.md) | CWE-693 | A05 | 8.8 | Detect Electron security misconfig | 💼 | | | |
|
|
307
|
+
| [no-insufficient-postmessage-validation](./docs/rules/no-insufficient-postmessage-validation.md) | CWE-346 | A07 | 8.8 | Detect postMessage origin issues | 💼 | | | |
|
|
308
|
+
|
|
309
|
+
---
|
|
310
|
+
|
|
311
|
+
## 🧭 Type-safe rule configuration (eslint.config.ts)
|
|
312
|
+
|
|
313
|
+
This package ships rule option types to keep flat configs type-safe.
|
|
314
|
+
|
|
315
|
+
```ts
|
|
316
|
+
import type { Linter } from 'eslint';
|
|
317
|
+
import type { AllSecurityRulesOptions } from 'eslint-plugin-secure-coding/types';
|
|
318
|
+
import secureCoding from 'eslint-plugin-secure-coding';
|
|
319
|
+
|
|
320
|
+
const secureCodingRuleOptions: AllSecurityRulesOptions = {
|
|
321
|
+
'no-sql-injection': { strategy: 'parameterize' },
|
|
322
|
+
'no-unsafe-deserialization': { allowJSON: false },
|
|
323
|
+
};
|
|
324
|
+
|
|
325
|
+
export default [
|
|
326
|
+
{
|
|
327
|
+
...secureCoding.configs.recommended,
|
|
328
|
+
rules: {
|
|
329
|
+
...secureCoding.configs.recommended.rules,
|
|
330
|
+
'secure-coding/no-sql-injection': [
|
|
331
|
+
'error',
|
|
332
|
+
secureCodingRuleOptions['no-sql-injection'],
|
|
333
|
+
],
|
|
334
|
+
'secure-coding/no-unsafe-deserialization': [
|
|
335
|
+
'error',
|
|
336
|
+
secureCodingRuleOptions['no-unsafe-deserialization'],
|
|
337
|
+
],
|
|
338
|
+
},
|
|
339
|
+
},
|
|
340
|
+
secureCoding.configs['recommended-llm'],
|
|
341
|
+
secureCoding.configs['recommended-mcp'],
|
|
342
|
+
] satisfies Linter.FlatConfig[];
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
---
|
|
346
|
+
|
|
347
|
+
## 🤖 LLM & AI Integration
|
|
348
|
+
|
|
349
|
+
This plugin is optimized for ESLint's [Model Context Protocol (MCP)](https://eslint.org/docs/latest/use/mcp), enabling AI assistants like **Cursor**, **GitHub Copilot**, and **Claude** to:
|
|
350
|
+
|
|
351
|
+
- Understand the exact vulnerability type via CWE references
|
|
352
|
+
- Apply the correct fix using structured guidance
|
|
353
|
+
- Provide educational context to developers
|
|
354
|
+
|
|
355
|
+
```json
|
|
356
|
+
// .cursor/mcp.json
|
|
357
|
+
{
|
|
358
|
+
"mcpServers": {
|
|
359
|
+
"eslint": {
|
|
360
|
+
"command": "npx",
|
|
361
|
+
"args": ["@eslint/mcp@latest"]
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
---
|
|
368
|
+
|
|
369
|
+
## 🔒 Privacy
|
|
370
|
+
|
|
371
|
+
This plugin runs **100% locally**. No data ever leaves your machine.
|
|
372
|
+
|
|
373
|
+
---
|
|
374
|
+
|
|
375
|
+
## 📄 License
|
|
376
|
+
|
|
377
|
+
MIT © [Ofri Peretz](https://github.com/ofri-peretz)
|
package/package.json
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "eslint-plugin-secure-coding",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Security-focused ESLint plugin with 48 LLM-optimized rules for detecting and preventing vulnerabilities. OWASP Top 10 coverage, CWE references, and AI-assisted fix guidance.",
|
|
5
|
+
"type": "commonjs",
|
|
6
|
+
"main": "./src/index.js",
|
|
7
|
+
"types": "./src/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./src/index.d.ts",
|
|
11
|
+
"default": "./src/index.js"
|
|
12
|
+
},
|
|
13
|
+
"./types": {
|
|
14
|
+
"types": "./src/types/index.d.ts",
|
|
15
|
+
"default": "./src/types/index.js"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"author": "Ofri Peretz <ofriperetzdev@gmail.com>",
|
|
19
|
+
"license": "MIT",
|
|
20
|
+
"homepage": "https://github.com/ofri-peretz/eslint#readme",
|
|
21
|
+
"repository": {
|
|
22
|
+
"type": "git",
|
|
23
|
+
"url": "git+https://github.com/ofri-peretz/eslint.git",
|
|
24
|
+
"directory": "packages/eslint-plugin-secure-coding"
|
|
25
|
+
},
|
|
26
|
+
"bugs": {
|
|
27
|
+
"url": "https://github.com/ofri-peretz/eslint/issues"
|
|
28
|
+
},
|
|
29
|
+
"publishConfig": {
|
|
30
|
+
"access": "public"
|
|
31
|
+
},
|
|
32
|
+
"files": [
|
|
33
|
+
"src/",
|
|
34
|
+
"dist/",
|
|
35
|
+
"README.md",
|
|
36
|
+
"LICENSE",
|
|
37
|
+
"CHANGELOG.md",
|
|
38
|
+
"AGENTS.md"
|
|
39
|
+
],
|
|
40
|
+
"keywords": [
|
|
41
|
+
"eslint",
|
|
42
|
+
"eslint-plugin",
|
|
43
|
+
"eslintplugin",
|
|
44
|
+
"security",
|
|
45
|
+
"secure-coding",
|
|
46
|
+
"owasp",
|
|
47
|
+
"owasp-top-10",
|
|
48
|
+
"cwe",
|
|
49
|
+
"vulnerability",
|
|
50
|
+
"sql-injection",
|
|
51
|
+
"xss",
|
|
52
|
+
"csrf",
|
|
53
|
+
"injection",
|
|
54
|
+
"llm-optimized",
|
|
55
|
+
"ai-assistant",
|
|
56
|
+
"auto-fix",
|
|
57
|
+
"typescript",
|
|
58
|
+
"linting",
|
|
59
|
+
"code-quality",
|
|
60
|
+
"ast",
|
|
61
|
+
"static-analysis",
|
|
62
|
+
"mcp",
|
|
63
|
+
"model-context-protocol",
|
|
64
|
+
"github-copilot",
|
|
65
|
+
"cursor-ai",
|
|
66
|
+
"claude-ai"
|
|
67
|
+
],
|
|
68
|
+
"engines": {
|
|
69
|
+
"node": ">=18.0.0"
|
|
70
|
+
},
|
|
71
|
+
"dependencies": {
|
|
72
|
+
"tslib": "^2.3.0",
|
|
73
|
+
"@interlace/eslint-devkit": "^1.0.0"
|
|
74
|
+
},
|
|
75
|
+
"devDependencies": {
|
|
76
|
+
"@typescript-eslint/parser": "^8.46.2",
|
|
77
|
+
"@typescript-eslint/rule-tester": "^8.46.2",
|
|
78
|
+
"vitest": "^4.0.6"
|
|
79
|
+
}
|
|
80
|
+
}
|
package/src/index.d.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* eslint-plugin-secure-coding
|
|
3
|
+
*
|
|
4
|
+
* A comprehensive security-focused ESLint plugin with 48+ rules
|
|
5
|
+
* for detecting and preventing security vulnerabilities in JavaScript/TypeScript code.
|
|
6
|
+
*
|
|
7
|
+
* Features:
|
|
8
|
+
* - LLM-optimized error messages with CWE references
|
|
9
|
+
* - OWASP Top 10 coverage
|
|
10
|
+
* - Auto-fix capabilities where safe
|
|
11
|
+
* - Structured context for AI assistants
|
|
12
|
+
*
|
|
13
|
+
* @see https://github.com/ofri-peretz/eslint#readme
|
|
14
|
+
*/
|
|
15
|
+
import type { TSESLint } from '@interlace/eslint-devkit';
|
|
16
|
+
/**
|
|
17
|
+
* Collection of all security ESLint rules
|
|
18
|
+
*/
|
|
19
|
+
export declare const rules: Record<string, TSESLint.RuleModule<string, readonly unknown[]>>;
|
|
20
|
+
/**
|
|
21
|
+
* ESLint Plugin object
|
|
22
|
+
*/
|
|
23
|
+
export declare const plugin: TSESLint.FlatConfig.Plugin;
|
|
24
|
+
export declare const configs: Record<string, TSESLint.FlatConfig.Config>;
|
|
25
|
+
/**
|
|
26
|
+
* Default export for ESLint plugin
|
|
27
|
+
*/
|
|
28
|
+
export default plugin;
|
|
29
|
+
/**
|
|
30
|
+
* Re-export all types from the types barrel
|
|
31
|
+
*/
|
|
32
|
+
export type { NoSqlInjectionOptions, DatabaseInjectionOptions, DetectEvalWithExpressionOptions, DetectChildProcessOptions, NoUnsafeDynamicRequireOptions, NoGraphqlInjectionOptions, NoXxeInjectionOptions, NoXpathInjectionOptions, NoLdapInjectionOptions, NoDirectiveInjectionOptions, NoFormatStringInjectionOptions, DetectNonLiteralFsFilenameOptions, NoZipSlipOptions, NoToctouVulnerabilityOptions, DetectNonLiteralRegexpOptions, NoRedosVulnerableRegexOptions, NoUnsafeRegexConstructionOptions, DetectObjectInjectionOptions, NoUnsafeDeserializationOptions, NoHardcodedCredentialsOptions, NoWeakCryptoOptions, NoInsufficientRandomOptions, NoTimingAttackOptions, NoInsecureComparisonOptions, NoInsecureJwtOptions, NoUnvalidatedUserInputOptions, NoUnsanitizedHtmlOptions, NoUnescapedUrlParameterOptions, NoImproperSanitizationOptions, NoImproperTypeValidationOptions, NoMissingAuthenticationOptions, NoPrivilegeEscalationOptions, NoWeakPasswordRecoveryOptions, NoInsecureCookieSettingsOptions, NoMissingCsrfProtectionOptions, NoDocumentCookieOptions, NoMissingCorsCheckOptions, NoMissingSecurityHeadersOptions, NoInsecureRedirectsOptions, NoUnencryptedTransmissionOptions, NoClickjackingOptions, NoExposedSensitiveDataOptions, NoSensitiveDataExposureOptions, NoBufferOverreadOptions, NoUnlimitedResourceAllocationOptions, NoUncheckedLoopConditionOptions, NoElectronSecurityIssuesOptions, NoInsufficientPostmessageValidationOptions, AllSecurityRulesOptions, } from './types/index';
|