eslint-plugin-node-security 4.0.3 → 4.1.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/CHANGELOG.md +42 -0
- package/LICENSE +23 -0
- package/README.md +57 -46
- package/package.json +15 -2
- package/src/index.js +19 -2
- package/src/index.js.map +1 -1
- package/src/oxlint.d.ts +20 -0
- package/src/oxlint.js +22 -0
- package/src/oxlint.js.map +1 -0
- package/src/rules/detect-child-process/index.js +121 -58
- package/src/rules/detect-child-process/index.js.map +1 -1
- package/src/rules/detect-eval-with-expression/index.js +16 -5
- package/src/rules/detect-eval-with-expression/index.js.map +1 -1
- package/src/rules/detect-non-literal-fs-filename/index.js +30 -7
- package/src/rules/detect-non-literal-fs-filename/index.js.map +1 -1
- package/src/rules/detect-suspicious-dependencies/index.js +4 -0
- package/src/rules/detect-suspicious-dependencies/index.js.map +1 -1
- package/src/rules/lock-file/index.js +25 -9
- package/src/rules/lock-file/index.js.map +1 -1
- package/src/rules/no-arbitrary-file-access/index.js +5 -2
- package/src/rules/no-arbitrary-file-access/index.js.map +1 -1
- package/src/rules/no-buffer-overread/index.js +36 -2
- package/src/rules/no-buffer-overread/index.js.map +1 -1
- package/src/rules/no-cryptojs/index.js +3 -0
- package/src/rules/no-cryptojs/index.js.map +1 -1
- package/src/rules/no-cryptojs-weak-random/index.js +3 -0
- package/src/rules/no-cryptojs-weak-random/index.js.map +1 -1
- package/src/rules/no-data-in-temp-storage/index.js +3 -0
- package/src/rules/no-data-in-temp-storage/index.js.map +1 -1
- package/src/rules/no-deprecated-buffer/index.d.ts +23 -0
- package/src/rules/no-deprecated-buffer/index.js +73 -0
- package/src/rules/no-deprecated-buffer/index.js.map +1 -0
- package/src/rules/no-deprecated-cipher-method/index.js +3 -0
- package/src/rules/no-deprecated-cipher-method/index.js.map +1 -1
- package/src/rules/no-dynamic-dependency-loading/index.js +3 -0
- package/src/rules/no-dynamic-dependency-loading/index.js.map +1 -1
- package/src/rules/no-dynamic-require/index.js +6 -1
- package/src/rules/no-dynamic-require/index.js.map +1 -1
- package/src/rules/no-ecb-mode/index.js +3 -0
- package/src/rules/no-ecb-mode/index.js.map +1 -1
- package/src/rules/no-insecure-key-derivation/index.js +3 -0
- package/src/rules/no-insecure-key-derivation/index.js.map +1 -1
- package/src/rules/no-insecure-rsa-padding/index.js +3 -0
- package/src/rules/no-insecure-rsa-padding/index.js.map +1 -1
- package/src/rules/no-pii-in-logs/index.js +3 -0
- package/src/rules/no-pii-in-logs/index.js.map +1 -1
- package/src/rules/no-self-signed-certs/index.js +3 -0
- package/src/rules/no-self-signed-certs/index.js.map +1 -1
- package/src/rules/no-sha1-hash/index.js +3 -0
- package/src/rules/no-sha1-hash/index.js.map +1 -1
- package/src/rules/no-ssrf/index.d.ts +25 -0
- package/src/rules/no-ssrf/index.js +228 -0
- package/src/rules/no-ssrf/index.js.map +1 -0
- package/src/rules/no-static-iv/index.js +3 -0
- package/src/rules/no-static-iv/index.js.map +1 -1
- package/src/rules/no-timing-unsafe-compare/index.js +3 -0
- package/src/rules/no-timing-unsafe-compare/index.js.map +1 -1
- package/src/rules/no-toctou-vulnerability/index.js +5 -2
- package/src/rules/no-toctou-vulnerability/index.js.map +1 -1
- package/src/rules/no-unsafe-dynamic-require/index.js +4 -0
- package/src/rules/no-unsafe-dynamic-require/index.js.map +1 -1
- package/src/rules/no-weak-cipher-algorithm/index.js +3 -0
- package/src/rules/no-weak-cipher-algorithm/index.js.map +1 -1
- package/src/rules/no-weak-hash-algorithm/index.js +3 -0
- package/src/rules/no-weak-hash-algorithm/index.js.map +1 -1
- package/src/rules/no-zip-slip/index.js +40 -62
- package/src/rules/no-zip-slip/index.js.map +1 -1
- package/src/rules/prefer-native-crypto/index.js +3 -0
- package/src/rules/prefer-native-crypto/index.js.map +1 -1
- package/src/rules/require-dependency-integrity/index.js +3 -0
- package/src/rules/require-dependency-integrity/index.js.map +1 -1
- package/src/rules/require-secure-credential-storage/index.js +3 -0
- package/src/rules/require-secure-credential-storage/index.js.map +1 -1
- package/src/rules/require-secure-deletion/index.js +3 -0
- package/src/rules/require-secure-deletion/index.js.map +1 -1
- package/src/rules/require-storage-encryption/index.js +3 -0
- package/src/rules/require-storage-encryption/index.js.map +1 -1
- package/src/types/index.js.map +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,45 @@
|
|
|
1
|
+
## [4.1.0] - 2026-05-03
|
|
2
|
+
|
|
3
|
+
### Added
|
|
4
|
+
|
|
5
|
+
- New rule `no-deprecated-buffer` — flags use of the deprecated `Buffer()` constructor (Node.js security advisory; `Buffer.from`/`Buffer.alloc` should be used instead). Enabled in the `recommended` preset at `warn` to avoid breaking adopters with legacy `Buffer()` calls; will be promoted to `error` in the next major.
|
|
6
|
+
|
|
7
|
+
### Bug Fixes
|
|
8
|
+
|
|
9
|
+
- `no-zip-slip`: removed redundant dangerous-destination check from the literal handler. Extraction-call handler already reports `dangerousArchiveDestination`; the literal-side check was producing duplicate errors and (separately) firing on unrelated calls like `fs.readFileSync('/etc/app/config')`.
|
|
10
|
+
- `lock-file`, `detect-child-process`: minor refinements (see source diff).
|
|
11
|
+
|
|
12
|
+
## [4.0.4] - 2026-02-08
|
|
13
|
+
|
|
14
|
+
### Bug Fixes
|
|
15
|
+
|
|
16
|
+
- align codecov component IDs with full package names ([2831b968](https://github.com/ofri-peretz/eslint/commit/2831b968))
|
|
17
|
+
- resolve all benchmark FN/FP across security rules ([45ffb791](https://github.com/ofri-peretz/eslint/commit/45ffb791))
|
|
18
|
+
- **rules:** reduce false positives across security rules ([c192233c](https://github.com/ofri-peretz/eslint/commit/c192233c))
|
|
19
|
+
|
|
20
|
+
### Documentation
|
|
21
|
+
|
|
22
|
+
- fix changelog header format across all packages ([c3a15082](https://github.com/ofri-peretz/eslint/commit/c3a15082))
|
|
23
|
+
|
|
24
|
+
### ❤️ Thank You
|
|
25
|
+
|
|
26
|
+
- Ofri Peretz
|
|
27
|
+
|
|
28
|
+
## [4.0.3] - 2026-02-06
|
|
29
|
+
|
|
30
|
+
### Bug Fixes
|
|
31
|
+
|
|
32
|
+
- ⚠️ **rules:** reduce false positives across security rules ([af4ca0e7](https://github.com/ofri-peretz/eslint/commit/af4ca0e7))
|
|
33
|
+
- align codecov component names and update docs components ([0a59a86c](https://github.com/ofri-peretz/eslint/commit/0a59a86c))
|
|
34
|
+
|
|
35
|
+
### ⚠️ Breaking Changes
|
|
36
|
+
|
|
37
|
+
- **rules:** Some previously flagged patterns are now correctly allowed ([af4ca0e7](https://github.com/ofri-peretz/eslint/commit/af4ca0e7))
|
|
38
|
+
|
|
39
|
+
### ❤️ Thank You
|
|
40
|
+
|
|
41
|
+
- Ofri Peretz
|
|
42
|
+
|
|
1
43
|
## [4.0.2] - 2026-02-02
|
|
2
44
|
|
|
3
45
|
This was a version bump only for eslint-plugin-node-security to align it with other projects, there were no code changes.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Ofri Peretz
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
|
23
|
+
|
package/README.md
CHANGED
|
@@ -17,7 +17,6 @@
|
|
|
17
17
|
## Description
|
|
18
18
|
|
|
19
19
|
This plugin provides Security rules for Node.js core modules (fs, child_process, crypto, etc).
|
|
20
|
-
By using this plugin, you can proactively identify and mitigate security risks across your entire codebase.
|
|
21
20
|
|
|
22
21
|
## Philosophy
|
|
23
22
|
|
|
@@ -36,6 +35,14 @@ By using this plugin, you can proactively identify and mitigate security risks a
|
|
|
36
35
|
npm install eslint-plugin-node-security --save-dev
|
|
37
36
|
```
|
|
38
37
|
|
|
38
|
+
## ⚙️ Configuration Presets
|
|
39
|
+
| Preset | Description |
|
|
40
|
+
| :------------ | :---------------------------------------------------- |
|
|
41
|
+
| `recommended` | Balanced security for most Node.js projects |
|
|
42
|
+
| `strict` | Maximum security enforcement (all rules as errors) |
|
|
43
|
+
| `fs-security` | Focus on file system vulnerabilities (CWE-22, CWE-73) |
|
|
44
|
+
| `crypto` | Cryptographic security rules only |
|
|
45
|
+
|
|
39
46
|
## 💡 What You Get
|
|
40
47
|
- **31 security rules** covering Node.js core module vulnerabilities
|
|
41
48
|
- **Command Injection Detection** for `child_process.exec`, `spawn`, and `execFile`
|
|
@@ -44,15 +51,13 @@ npm install eslint-plugin-node-security --save-dev
|
|
|
44
51
|
- **Cryptographic Security** for weak algorithms and key management
|
|
45
52
|
- **LLM-optimized messages** with CWE references and fix guidance
|
|
46
53
|
|
|
47
|
-
##
|
|
48
|
-
|
|
|
49
|
-
|
|
|
50
|
-
|
|
|
51
|
-
|
|
|
52
|
-
| `fs-security` | Focus on file system vulnerabilities (CWE-22, CWE-73) |
|
|
53
|
-
| `crypto` | Cryptographic security rules only |
|
|
54
|
+
## 📦 Compatibility
|
|
55
|
+
| Package | Version |
|
|
56
|
+
| :--- | :--- |
|
|
57
|
+
| ESLint | `^8.0.0 \|\| ^9.0.0 \|\| ^10.0.0` |
|
|
58
|
+
| Node.js | `>=18.0.0` |
|
|
54
59
|
|
|
55
|
-
|
|
60
|
+
See the [ESLint Version Support Policy](../../docs/ESLINT_VERSION_SUPPORT.md) — current ecosystem share data, the 20% gate, and the forward-looking exception that covers v10.
|
|
56
61
|
|
|
57
62
|
## Rules
|
|
58
63
|
|
|
@@ -61,45 +66,51 @@ npm install eslint-plugin-node-security --save-dev
|
|
|
61
66
|
| Icon | Description |
|
|
62
67
|
| :---: | :--- |
|
|
63
68
|
| 💼 | **Recommended**: Included in the recommended preset. |
|
|
64
|
-
| ⚠️ | **Warns**: Set
|
|
69
|
+
| ⚠️ | **Warns**: Set to warn in recommended preset. |
|
|
65
70
|
| 🔧 | **Auto-fixable**: Automatically fixable by the `--fix` CLI option. |
|
|
66
71
|
| 💡 | **Suggestions**: Providing code suggestions in IDE. |
|
|
67
72
|
| 🚫 | **Deprecated**: This rule is deprecated. |
|
|
68
|
-
|
|
69
|
-
|
|
|
70
|
-
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
|
74
|
-
|
|
|
75
|
-
| [
|
|
76
|
-
| [
|
|
77
|
-
| [
|
|
78
|
-
| [
|
|
79
|
-
| [
|
|
80
|
-
| [no-
|
|
81
|
-
| [no-
|
|
82
|
-
| [no-
|
|
83
|
-
| [no-
|
|
84
|
-
| [no-
|
|
85
|
-
| [no-
|
|
86
|
-
| [no-
|
|
87
|
-
| [no-
|
|
88
|
-
| [no-
|
|
89
|
-
| [no-
|
|
90
|
-
| [no-
|
|
91
|
-
| [no-
|
|
92
|
-
| [no-
|
|
93
|
-
| [no-
|
|
94
|
-
| [no-
|
|
95
|
-
| [no-
|
|
96
|
-
| [no-
|
|
97
|
-
| [
|
|
98
|
-
| [
|
|
99
|
-
| [
|
|
100
|
-
| [
|
|
101
|
-
| [
|
|
102
|
-
|
|
73
|
+
| 🟢 | **Type-unaware**: AST-only, runs in oxlint JS-plugin tier. |
|
|
74
|
+
| 🟡 | **Type-aware (refining)**: pure-AST primary path; types refine precision. |
|
|
75
|
+
| 🟠 | **Type-aware (graceful)**: requires TS program; silent without it. |
|
|
76
|
+
|
|
77
|
+
<!-- AUTO-GENERATED:RULES_TABLE:START - Do not edit manually -->
|
|
78
|
+
| Rule | CWE | OWASP | CVSS | Description | 🧠 | 💼 | ⚠️ | 🔧 | 💡 | 🚫 |
|
|
79
|
+
| :--- | :---: | :---: | :---: | :--- | :---: | :---: | :---: | :---: | :---: | :---: |
|
|
80
|
+
| [detect-child-process](https://eslint.interlace.tools/docs/security/plugin-node-security/rules/detect-child-process) | CWE-78 | | | Detects instances of childprocess & non-literal exec() calls that may allow command injection | 🟢 | | | | | |
|
|
81
|
+
| [detect-eval-with-expression](https://eslint.interlace.tools/docs/security/plugin-node-security/rules/detect-eval-with-expression) | CWE-95 | A03:2021 | | Detects eval(variable) which can allow an attacker to run arbitrary code inside your process | 🟢 | | | | | |
|
|
82
|
+
| [detect-non-literal-fs-filename](https://eslint.interlace.tools/docs/security/plugin-node-security/rules/detect-non-literal-fs-filename) | CWE-22 | | | Detects variable in filename argument of fs calls, which might allow an attacker to access anything on your… | 🟢 | | | | | |
|
|
83
|
+
| [detect-suspicious-dependencies](https://eslint.interlace.tools/docs/security/plugin-node-security/rules/detect-suspicious-dependencies) | CWE-506 | | | This rule detects package imports that look like typosquatting attempts on popular npm packages | 🟢 | | | | | |
|
|
84
|
+
| [lock-file](https://eslint.interlace.tools/docs/security/plugin-node-security/rules/lock-file) | CWE-829 | | | CWE: [CWE-829](https://cwe.mitre.org/data/definitions/829.html) | 🟢 | | | | | |
|
|
85
|
+
| [no-arbitrary-file-access](https://eslint.interlace.tools/docs/security/plugin-node-security/rules/no-arbitrary-file-access) | CWE-22 | A01:2021 | | Prevents file system access with unsanitized user input to protect against path traversal attacks. | 🟢 | | | | | |
|
|
86
|
+
| [no-buffer-overread](https://eslint.interlace.tools/docs/security/plugin-node-security/rules/no-buffer-overread) | CWE-126 | | | Detects buffer access beyond bounds | 🟢 | | | | | |
|
|
87
|
+
| [no-cryptojs](https://eslint.interlace.tools/docs/security/plugin-node-security/rules/no-cryptojs) | CWE-1104 | A06:2021 | | Disallow deprecated crypto-js library (use native crypto instead) | 🟢 | | | | | |
|
|
88
|
+
| [no-cryptojs-weak-random](https://eslint.interlace.tools/docs/security/plugin-node-security/rules/no-cryptojs-weak-random) | CWE-338 | A02:2021 | | Disallow crypto-js WordArray.random() (CVE-2020-36732) | 🟢 | | | | | |
|
|
89
|
+
| [no-data-in-temp-storage](https://eslint.interlace.tools/docs/security/plugin-node-security/rules/no-data-in-temp-storage) | CWE-312 | | | Temporary directories (/tmp, /var/tmp, temp/) are often world-readable or persist longer than expected | 🟢 | | | | | |
|
|
90
|
+
| [no-deprecated-buffer](https://eslint.interlace.tools/docs/security/plugin-node-security/rules/no-deprecated-buffer) | CWE-676 | | | Disallow the deprecated `new Buffer()` constructor and `Buffer()` factory call. | 🟢 | | | | 💡 | |
|
|
91
|
+
| [no-deprecated-cipher-method](https://eslint.interlace.tools/docs/security/plugin-node-security/rules/no-deprecated-cipher-method) | CWE-327 | A02:2021 | | Disallow deprecated crypto.createCipher/createDecipher methods | 🟢 | | | | | |
|
|
92
|
+
| [no-dynamic-dependency-loading](https://eslint.interlace.tools/docs/security/plugin-node-security/rules/no-dynamic-dependency-loading) | CWE-1104 | | | This rule detects dynamically constructed paths in require() and import() statements | 🟢 | | | | | |
|
|
93
|
+
| [no-dynamic-require](https://eslint.interlace.tools/docs/security/plugin-node-security/rules/no-dynamic-require) | | | | Forbid require() calls with non-literal arguments | 🟢 | | | | | |
|
|
94
|
+
| [no-ecb-mode](https://eslint.interlace.tools/docs/security/plugin-node-security/rules/no-ecb-mode) | CWE-327 | A02:2021 | | Disallow ECB encryption mode (use GCM or CBC instead) | 🟢 | | | | | |
|
|
95
|
+
| [no-insecure-key-derivation](https://eslint.interlace.tools/docs/security/plugin-node-security/rules/no-insecure-key-derivation) | CWE-916 | A02:2021 | | Disallow PBKDF2 with insufficient iterations (< 100,000) | 🟢 | | | | | |
|
|
96
|
+
| [no-insecure-rsa-padding](https://eslint.interlace.tools/docs/security/plugin-node-security/rules/no-insecure-rsa-padding) | CWE-327 | A02:2021 | | Disallow RSA PKCS#1 v1.5 padding (CVE-2023-46809 Marvin Attack) | 🟢 | | | | | |
|
|
97
|
+
| [no-pii-in-logs](https://eslint.interlace.tools/docs/security/plugin-node-security/rules/no-pii-in-logs) | CWE-532 | | | CWE: [CWE-532](https://cwe.mitre.org/data/definitions/532.html) | 🟢 | | | | | |
|
|
98
|
+
| [no-self-signed-certs](https://eslint.interlace.tools/docs/security/plugin-node-security/rules/no-self-signed-certs) | CWE-295 | A07:2021 | | Disallow rejectUnauthorized false in TLS options | 🟢 | | | | | |
|
|
99
|
+
| [no-sha1-hash](https://eslint.interlace.tools/docs/security/plugin-node-security/rules/no-sha1-hash) | CWE-327 | A02:2021 | | Disallow sha1() from crypto-hash package (use sha256 or sha512) | 🟢 | | | | | |
|
|
100
|
+
| [no-ssrf](https://eslint.interlace.tools/docs/security/plugin-node-security/rules/no-ssrf) | CWE-918 | A10:2021 | | Detect HTTP requests with user-controlled URLs (server-side request forgery). | 🟢 | | | | 💡 | |
|
|
101
|
+
| [no-static-iv](https://eslint.interlace.tools/docs/security/plugin-node-security/rules/no-static-iv) | CWE-329 | A02:2021 | | Disallow static or hardcoded initialization vectors (IVs) | 🟢 | | | | | |
|
|
102
|
+
| [no-timing-unsafe-compare](https://eslint.interlace.tools/docs/security/plugin-node-security/rules/no-timing-unsafe-compare) | CWE-208 | A02:2021 | | Disallow timing-unsafe comparison of secrets | 🟢 | | | | | |
|
|
103
|
+
| [no-toctou-vulnerability](https://eslint.interlace.tools/docs/security/plugin-node-security/rules/no-toctou-vulnerability) | CWE-367 | A01:2021 | | Detects Time-of-Check-Time-of-Use (TOCTOU) race condition vulnerabilities in file system operations. | 🟢 | | | | | |
|
|
104
|
+
| [no-unsafe-dynamic-require](https://eslint.interlace.tools/docs/security/plugin-node-security/rules/no-unsafe-dynamic-require) | CWE-494 | | | Disallows dynamic require() calls with non-literal arguments that could lead to security vulnerabilities | 🟢 | | | | | |
|
|
105
|
+
| [no-weak-cipher-algorithm](https://eslint.interlace.tools/docs/security/plugin-node-security/rules/no-weak-cipher-algorithm) | CWE-327 | A02:2021 | | Disallow weak cipher algorithms (DES, 3DES, RC4, Blowfish, RC2, IDEA) | 🟢 | | | | | |
|
|
106
|
+
| [no-weak-hash-algorithm](https://eslint.interlace.tools/docs/security/plugin-node-security/rules/no-weak-hash-algorithm) | CWE-327 | A02:2021 | | Disallow weak hash algorithms (MD5, MD4, SHA-1, RIPEMD) | 🟢 | | | | | |
|
|
107
|
+
| [no-zip-slip](https://eslint.interlace.tools/docs/security/plugin-node-security/rules/no-zip-slip) | CWE-22 | | | Detects zip slip/archive extraction vulnerabilities | 🟢 | | | | | |
|
|
108
|
+
| [prefer-native-crypto](https://eslint.interlace.tools/docs/security/plugin-node-security/rules/prefer-native-crypto) | CWE-1104 | A06:2021 | | Prefer native crypto over third-party libraries | 🟢 | | | | | |
|
|
109
|
+
| [require-dependency-integrity](https://eslint.interlace.tools/docs/security/plugin-node-security/rules/require-dependency-integrity) | CWE-494 | | | CWE: [CWE-494](https://cwe.mitre.org/data/definitions/494.html) | 🟢 | | | | | |
|
|
110
|
+
| [require-secure-credential-storage](https://eslint.interlace.tools/docs/security/plugin-node-security/rules/require-secure-credential-storage) | CWE-312 | | | This rule detects when credentials are stored using localStorage.setItem() or fs.writeFile() without encryp… | 🟢 | | | | | |
|
|
111
|
+
| [require-secure-deletion](https://eslint.interlace.tools/docs/security/plugin-node-security/rules/require-secure-deletion) | CWE-459 | | | CWE: [CWE-459](https://cwe.mitre.org/data/definitions/459.html) | 🟢 | | | | | |
|
|
112
|
+
| [require-storage-encryption](https://eslint.interlace.tools/docs/security/plugin-node-security/rules/require-storage-encryption) | CWE-312 | | | CWE: [CWE-312](https://cwe.mitre.org/data/definitions/312.html) | 🟢 | | | | | |
|
|
113
|
+
<!-- AUTO-GENERATED:RULES_TABLE:END -->
|
|
103
114
|
## 🔗 Related ESLint Plugins
|
|
104
115
|
|
|
105
116
|
Part of the **Interlace ESLint Ecosystem** — AI-native security plugins with LLM-optimized error messages:
|
|
@@ -108,7 +119,7 @@ Part of the **Interlace ESLint Ecosystem** — AI-native security plugins with L
|
|
|
108
119
|
| :--- | :---: | :--- |
|
|
109
120
|
| [`eslint-plugin-secure-coding`](https://www.npmjs.com/package/eslint-plugin-secure-coding) | [](https://www.npmjs.com/package/eslint-plugin-secure-coding) | General security rules & OWASP guidelines. |
|
|
110
121
|
| [`eslint-plugin-pg`](https://www.npmjs.com/package/eslint-plugin-pg) | [](https://www.npmjs.com/package/eslint-plugin-pg) | PostgreSQL security & best practices. |
|
|
111
|
-
| [`eslint-plugin-
|
|
122
|
+
| [`eslint-plugin-node-security`](https://www.npmjs.com/package/eslint-plugin-node-security) | [](https://www.npmjs.com/package/eslint-plugin-node-security) | Node.js core-module security (fs, child_process, vm, crypto, Buffer). |
|
|
112
123
|
| [`eslint-plugin-jwt`](https://www.npmjs.com/package/eslint-plugin-jwt) | [](https://www.npmjs.com/package/eslint-plugin-jwt) | JWT security & best practices. |
|
|
113
124
|
| [`eslint-plugin-browser-security`](https://www.npmjs.com/package/eslint-plugin-browser-security) | [](https://www.npmjs.com/package/eslint-plugin-browser-security) | Browser-specific security & XSS prevention. |
|
|
114
125
|
| [`eslint-plugin-express-security`](https://www.npmjs.com/package/eslint-plugin-express-security) | [](https://www.npmjs.com/package/eslint-plugin-express-security) | Express.js security hardening rules. |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-node-security",
|
|
3
|
-
"version": "4.0
|
|
3
|
+
"version": "4.1.0",
|
|
4
4
|
"description": "Security-focused ESLint plugin for Node.js built-in modules (fs, child_process, vm, path, Buffer). Detects command injection, path traversal, code execution vulnerabilities with AI-parseable error messages.",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"main": "./src/index.js",
|
|
@@ -13,6 +13,10 @@
|
|
|
13
13
|
"./types": {
|
|
14
14
|
"types": "./src/types/index.d.ts",
|
|
15
15
|
"default": "./src/types/index.js"
|
|
16
|
+
},
|
|
17
|
+
"./oxlint": {
|
|
18
|
+
"types": "./src/oxlint.d.ts",
|
|
19
|
+
"default": "./src/oxlint.js"
|
|
16
20
|
}
|
|
17
21
|
},
|
|
18
22
|
"author": "Ofri Peretz <ofriperetzdev@gmail.com>",
|
|
@@ -75,5 +79,14 @@
|
|
|
75
79
|
"devDependencies": {
|
|
76
80
|
"@typescript-eslint/parser": "^8.46.2",
|
|
77
81
|
"@typescript-eslint/rule-tester": "^8.46.2"
|
|
82
|
+
},
|
|
83
|
+
"scripts": {
|
|
84
|
+
"build": "tsx ../../scripts/build-package.ts",
|
|
85
|
+
"test": "vitest run",
|
|
86
|
+
"test:coverage": "vitest run --coverage",
|
|
87
|
+
"typecheck": "tsc -p tsconfig.lib.json --noEmit"
|
|
88
|
+
},
|
|
89
|
+
"peerDependencies": {
|
|
90
|
+
"eslint": "^8.0.0 || ^9.0.0 || ^10.0.0"
|
|
78
91
|
}
|
|
79
|
-
}
|
|
92
|
+
}
|
package/src/index.js
CHANGED
|
@@ -11,10 +11,13 @@ const detect_eval_with_expression_1 = require("./rules/detect-eval-with-expressi
|
|
|
11
11
|
const detect_non_literal_fs_filename_1 = require("./rules/detect-non-literal-fs-filename");
|
|
12
12
|
const no_unsafe_dynamic_require_1 = require("./rules/no-unsafe-dynamic-require");
|
|
13
13
|
const no_buffer_overread_1 = require("./rules/no-buffer-overread");
|
|
14
|
+
const no_deprecated_buffer_1 = require("./rules/no-deprecated-buffer");
|
|
14
15
|
const no_toctou_vulnerability_1 = require("./rules/no-toctou-vulnerability");
|
|
15
16
|
const no_zip_slip_1 = require("./rules/no-zip-slip");
|
|
16
17
|
const no_arbitrary_file_access_1 = require("./rules/no-arbitrary-file-access");
|
|
17
18
|
const no_data_in_temp_storage_1 = require("./rules/no-data-in-temp-storage");
|
|
19
|
+
const no_pii_in_logs_1 = require("./rules/no-pii-in-logs");
|
|
20
|
+
const no_ssrf_1 = require("./rules/no-ssrf");
|
|
18
21
|
// Migrated rules from secure-coding
|
|
19
22
|
const detect_suspicious_dependencies_1 = require("./rules/detect-suspicious-dependencies");
|
|
20
23
|
const lock_file_1 = require("./rules/lock-file");
|
|
@@ -44,10 +47,13 @@ exports.rules = {
|
|
|
44
47
|
'detect-non-literal-fs-filename': detect_non_literal_fs_filename_1.detectNonLiteralFsFilename,
|
|
45
48
|
'no-unsafe-dynamic-require': no_unsafe_dynamic_require_1.noUnsafeDynamicRequire,
|
|
46
49
|
'no-buffer-overread': no_buffer_overread_1.noBufferOverread,
|
|
50
|
+
'no-deprecated-buffer': no_deprecated_buffer_1.noDeprecatedBuffer,
|
|
47
51
|
'no-toctou-vulnerability': no_toctou_vulnerability_1.noToctouVulnerability,
|
|
48
52
|
'no-zip-slip': no_zip_slip_1.noZipSlip,
|
|
49
53
|
'no-arbitrary-file-access': no_arbitrary_file_access_1.noArbitraryFileAccess,
|
|
50
54
|
'no-data-in-temp-storage': no_data_in_temp_storage_1.noDataInTempStorage,
|
|
55
|
+
'no-pii-in-logs': no_pii_in_logs_1.noPiiInLogs,
|
|
56
|
+
'no-ssrf': no_ssrf_1.noSsrf,
|
|
51
57
|
// Migrated rules
|
|
52
58
|
'detect-suspicious-dependencies': detect_suspicious_dependencies_1.detectSuspiciousDependencies,
|
|
53
59
|
'lock-file': lock_file_1.lockFile,
|
|
@@ -75,7 +81,7 @@ exports.rules = {
|
|
|
75
81
|
exports.plugin = {
|
|
76
82
|
meta: {
|
|
77
83
|
name: 'eslint-plugin-node-security',
|
|
78
|
-
version: '1.0
|
|
84
|
+
version: '4.1.0',
|
|
79
85
|
},
|
|
80
86
|
rules: exports.rules,
|
|
81
87
|
};
|
|
@@ -84,11 +90,22 @@ const recommendedRules = {
|
|
|
84
90
|
'node-security/detect-eval-with-expression': 'error',
|
|
85
91
|
'node-security/detect-non-literal-fs-filename': 'error',
|
|
86
92
|
'node-security/no-unsafe-dynamic-require': 'error',
|
|
87
|
-
|
|
93
|
+
// no-buffer-overread demoted 2026-05-09 — 95% of Wild hits on adversarial
|
|
94
|
+
// Edge corpus + insufficient fixture coverage for the README §1 promotion
|
|
95
|
+
// gate. Per `npm run ilb:severity-audit` it's both edge-error AND
|
|
96
|
+
// volume-error risk. Promote back to 'error' once Edge ratio drops to
|
|
97
|
+
// ≤ 50% (see `benchmarks/AUDIT_PATTERNS.md` §3.6 — needs typed-array
|
|
98
|
+
// detection like `detect-object-injection` got in audit iter-1).
|
|
99
|
+
'node-security/no-buffer-overread': 'warn',
|
|
100
|
+
// Added in 4.1.0. Set to 'warn' in `recommended` to avoid breaking
|
|
101
|
+
// adopters who already use the preset and have legacy `Buffer()` calls.
|
|
102
|
+
// Promote to 'error' on the next major bump.
|
|
103
|
+
'node-security/no-deprecated-buffer': 'warn',
|
|
88
104
|
'node-security/no-toctou-vulnerability': 'error',
|
|
89
105
|
'node-security/no-zip-slip': 'error',
|
|
90
106
|
'node-security/no-arbitrary-file-access': 'error',
|
|
91
107
|
'node-security/no-data-in-temp-storage': 'error',
|
|
108
|
+
'node-security/no-ssrf': 'error',
|
|
92
109
|
// Migrated Rules
|
|
93
110
|
'node-security/detect-suspicious-dependencies': 'warn',
|
|
94
111
|
'node-security/lock-file': 'error',
|
package/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|
package/src/oxlint.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Ofri Peretz
|
|
3
|
+
* Licensed under the MIT License. Use of this source code is governed by the
|
|
4
|
+
* MIT license that can be found in the LICENSE file.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* oxlint sub-export.
|
|
8
|
+
*
|
|
9
|
+
* Consumers wire oxlint to this entry via:
|
|
10
|
+
* { "jsPlugins": ["eslint-plugin-node-security/oxlint"] }
|
|
11
|
+
*
|
|
12
|
+
* oxlint's JS plugin loader does `require('eslint-plugin-node-security/oxlint')` and reads
|
|
13
|
+
* `.rules` off the result. The compiled output of `export = plugin` is
|
|
14
|
+
* `module.exports = plugin`, which gives oxlint the plugin object directly
|
|
15
|
+
* (`{ meta, rules }`) — no wrapper, no `.default` indirection.
|
|
16
|
+
*
|
|
17
|
+
* Generated by scripts/generate-oxlint-shims.mjs. Do not edit by hand.
|
|
18
|
+
*/
|
|
19
|
+
import { plugin } from './index';
|
|
20
|
+
export = plugin;
|
package/src/oxlint.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) 2025 Ofri Peretz
|
|
4
|
+
* Licensed under the MIT License. Use of this source code is governed by the
|
|
5
|
+
* MIT license that can be found in the LICENSE file.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* oxlint sub-export.
|
|
9
|
+
*
|
|
10
|
+
* Consumers wire oxlint to this entry via:
|
|
11
|
+
* { "jsPlugins": ["eslint-plugin-node-security/oxlint"] }
|
|
12
|
+
*
|
|
13
|
+
* oxlint's JS plugin loader does `require('eslint-plugin-node-security/oxlint')` and reads
|
|
14
|
+
* `.rules` off the result. The compiled output of `export = plugin` is
|
|
15
|
+
* `module.exports = plugin`, which gives oxlint the plugin object directly
|
|
16
|
+
* (`{ meta, rules }`) — no wrapper, no `.default` indirection.
|
|
17
|
+
*
|
|
18
|
+
* Generated by scripts/generate-oxlint-shims.mjs. Do not edit by hand.
|
|
19
|
+
*/
|
|
20
|
+
const index_1 = require("./index");
|
|
21
|
+
module.exports = index_1.plugin;
|
|
22
|
+
//# sourceMappingURL=oxlint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oxlint.js","sourceRoot":"","sources":["../../src/oxlint.ts"],"names":[],"mappings":";AAAA;;;;GAIG;AAEH;;;;;;;;;;;;GAYG;AAEH,mCAAiC;AAEjC,iBAAS,cAAM,CAAC"}
|