eslint-plugin-node-security 4.6.0 → 4.7.1

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.
Files changed (120) hide show
  1. package/README.md +1 -0
  2. package/package.json +5 -18
  3. package/src/index.d.ts +17 -10
  4. package/src/index.js +5 -36
  5. package/src/oxlint.d.ts +17 -20
  6. package/src/oxlint.js +0 -19
  7. package/src/rules/detect-child-process/index.js +0 -107
  8. package/src/rules/detect-eval-with-expression/index.js +2 -48
  9. package/src/rules/detect-non-literal-fs-filename/index.js +0 -82
  10. package/src/rules/detect-suspicious-dependencies/index.js +0 -12
  11. package/src/rules/lock-file/index.js +0 -18
  12. package/src/rules/no-arbitrary-file-access/index.js +0 -52
  13. package/src/rules/no-buffer-overread/index.js +3 -96
  14. package/src/rules/no-cryptojs/index.js +2 -10
  15. package/src/rules/no-cryptojs-weak-random/index.js +1 -13
  16. package/src/rules/no-data-in-temp-storage/index.js +0 -12
  17. package/src/rules/no-deprecated-buffer/index.js +0 -15
  18. package/src/rules/no-deprecated-cipher-method/index.js +0 -9
  19. package/src/rules/no-dynamic-algorithm-selection/index.js +0 -13
  20. package/src/rules/no-dynamic-command-string/index.js +201 -0
  21. package/src/rules/no-dynamic-dependency-loading/index.js +0 -13
  22. package/src/rules/no-dynamic-require/index.js +0 -10
  23. package/src/rules/no-ecb-mode/index.js +0 -7
  24. package/src/rules/no-insecure-key-derivation/index.js +0 -10
  25. package/src/rules/no-insecure-rsa-padding/index.js +0 -9
  26. package/src/rules/no-math-random-crypto/index.js +1 -17
  27. package/src/rules/no-self-signed-certs/index.js +1 -9
  28. package/src/rules/no-sha1-hash/index.js +0 -9
  29. package/src/rules/no-shell-injection/index.js +0 -20
  30. package/src/rules/no-ssrf/index.js +4 -80
  31. package/src/rules/no-static-iv/index.js +2 -21
  32. package/src/rules/no-timing-unsafe-compare/index.js +1 -11
  33. package/src/rules/no-toctou-vulnerability/index.js +0 -22
  34. package/src/rules/no-unsafe-buffer-alloc/index.js +0 -13
  35. package/src/rules/no-unsafe-dynamic-require/index.js +0 -22
  36. package/src/rules/no-weak-cipher-algorithm/index.js +0 -19
  37. package/src/rules/no-weak-hash-algorithm/index.js +0 -22
  38. package/src/rules/no-zip-slip/index.js +3 -81
  39. package/src/rules/prefer-native-crypto/index.js +4 -11
  40. package/src/rules/require-dependency-integrity/index.js +0 -11
  41. package/src/rules/require-secure-credential-storage/index.js +0 -12
  42. package/src/rules/require-secure-deletion/index.js +0 -29
  43. package/src/rules/require-storage-encryption/index.js +0 -12
  44. package/src/types/index.js +0 -6
  45. package/CHANGELOG.md +0 -413
  46. package/src/index.js.map +0 -1
  47. package/src/oxlint.js.map +0 -1
  48. package/src/rules/detect-child-process/index.d.ts +0 -52
  49. package/src/rules/detect-child-process/index.js.map +0 -1
  50. package/src/rules/detect-eval-with-expression/index.d.ts +0 -46
  51. package/src/rules/detect-eval-with-expression/index.js.map +0 -1
  52. package/src/rules/detect-non-literal-fs-filename/index.d.ts +0 -52
  53. package/src/rules/detect-non-literal-fs-filename/index.js.map +0 -1
  54. package/src/rules/detect-suspicious-dependencies/index.d.ts +0 -12
  55. package/src/rules/detect-suspicious-dependencies/index.js.map +0 -1
  56. package/src/rules/lock-file/index.d.ts +0 -13
  57. package/src/rules/lock-file/index.js.map +0 -1
  58. package/src/rules/no-arbitrary-file-access/index.d.ts +0 -12
  59. package/src/rules/no-arbitrary-file-access/index.js.map +0 -1
  60. package/src/rules/no-buffer-overread/index.d.ts +0 -39
  61. package/src/rules/no-buffer-overread/index.js.map +0 -1
  62. package/src/rules/no-cryptojs/index.d.ts +0 -24
  63. package/src/rules/no-cryptojs/index.js.map +0 -1
  64. package/src/rules/no-cryptojs-weak-random/index.d.ts +0 -24
  65. package/src/rules/no-cryptojs-weak-random/index.js.map +0 -1
  66. package/src/rules/no-data-in-temp-storage/index.d.ts +0 -14
  67. package/src/rules/no-data-in-temp-storage/index.js.map +0 -1
  68. package/src/rules/no-deprecated-buffer/index.d.ts +0 -23
  69. package/src/rules/no-deprecated-buffer/index.js.map +0 -1
  70. package/src/rules/no-deprecated-cipher-method/index.d.ts +0 -23
  71. package/src/rules/no-deprecated-cipher-method/index.js.map +0 -1
  72. package/src/rules/no-dynamic-algorithm-selection/index.d.ts +0 -26
  73. package/src/rules/no-dynamic-algorithm-selection/index.js.map +0 -1
  74. package/src/rules/no-dynamic-dependency-loading/index.d.ts +0 -12
  75. package/src/rules/no-dynamic-dependency-loading/index.js.map +0 -1
  76. package/src/rules/no-dynamic-require/index.d.ts +0 -21
  77. package/src/rules/no-dynamic-require/index.js.map +0 -1
  78. package/src/rules/no-ecb-mode/index.d.ts +0 -23
  79. package/src/rules/no-ecb-mode/index.js.map +0 -1
  80. package/src/rules/no-insecure-key-derivation/index.d.ts +0 -24
  81. package/src/rules/no-insecure-key-derivation/index.js.map +0 -1
  82. package/src/rules/no-insecure-rsa-padding/index.d.ts +0 -24
  83. package/src/rules/no-insecure-rsa-padding/index.js.map +0 -1
  84. package/src/rules/no-math-random-crypto/index.d.ts +0 -26
  85. package/src/rules/no-math-random-crypto/index.js.map +0 -1
  86. package/src/rules/no-self-signed-certs/index.d.ts +0 -23
  87. package/src/rules/no-self-signed-certs/index.js.map +0 -1
  88. package/src/rules/no-sha1-hash/index.d.ts +0 -24
  89. package/src/rules/no-sha1-hash/index.js.map +0 -1
  90. package/src/rules/no-shell-injection/index.d.ts +0 -20
  91. package/src/rules/no-shell-injection/index.js.map +0 -1
  92. package/src/rules/no-ssrf/index.d.ts +0 -25
  93. package/src/rules/no-ssrf/index.js.map +0 -1
  94. package/src/rules/no-static-iv/index.d.ts +0 -23
  95. package/src/rules/no-static-iv/index.js.map +0 -1
  96. package/src/rules/no-timing-unsafe-compare/index.d.ts +0 -23
  97. package/src/rules/no-timing-unsafe-compare/index.js.map +0 -1
  98. package/src/rules/no-toctou-vulnerability/index.d.ts +0 -26
  99. package/src/rules/no-toctou-vulnerability/index.js.map +0 -1
  100. package/src/rules/no-unsafe-buffer-alloc/index.d.ts +0 -47
  101. package/src/rules/no-unsafe-buffer-alloc/index.js.map +0 -1
  102. package/src/rules/no-unsafe-dynamic-require/index.d.ts +0 -19
  103. package/src/rules/no-unsafe-dynamic-require/index.js.map +0 -1
  104. package/src/rules/no-weak-cipher-algorithm/index.d.ts +0 -25
  105. package/src/rules/no-weak-cipher-algorithm/index.js.map +0 -1
  106. package/src/rules/no-weak-hash-algorithm/index.d.ts +0 -25
  107. package/src/rules/no-weak-hash-algorithm/index.js.map +0 -1
  108. package/src/rules/no-zip-slip/index.d.ts +0 -35
  109. package/src/rules/no-zip-slip/index.js.map +0 -1
  110. package/src/rules/prefer-native-crypto/index.d.ts +0 -23
  111. package/src/rules/prefer-native-crypto/index.js.map +0 -1
  112. package/src/rules/require-dependency-integrity/index.d.ts +0 -12
  113. package/src/rules/require-dependency-integrity/index.js.map +0 -1
  114. package/src/rules/require-secure-credential-storage/index.d.ts +0 -12
  115. package/src/rules/require-secure-credential-storage/index.js.map +0 -1
  116. package/src/rules/require-secure-deletion/index.d.ts +0 -17
  117. package/src/rules/require-secure-deletion/index.js.map +0 -1
  118. package/src/rules/require-storage-encryption/index.d.ts +0 -12
  119. package/src/rules/require-storage-encryption/index.js.map +0 -1
  120. package/src/types/index.js.map +0 -1
@@ -1,29 +1,15 @@
1
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
2
  Object.defineProperty(exports, "__esModule", { value: true });
8
3
  exports.noZipSlip = void 0;
9
4
  const eslint_devkit_1 = require("@interlace/eslint-devkit");
10
5
  const eslint_devkit_2 = require("@interlace/eslint-devkit");
11
- /**
12
- * Check if path contains dangerous traversal sequences
13
- */
14
6
  const containsPathTraversal = (pathText) => {
15
- // Check for ../ sequences
16
7
  return /\.\.\//.test(pathText) ||
17
- /\.\.\\/.test(pathText) || // Windows paths
8
+ /\.\.\\/.test(pathText) ||
18
9
  pathText.startsWith('..') ||
19
- /\/\.\./.test(pathText); // Embedded /..
10
+ /\/\.\./.test(pathText);
20
11
  };
21
- /**
22
- * Check if destination is dangerous (sensitive system directories)
23
- * Note: /tmp is NOT dangerous - it's the standard safe temp location
24
- */
25
12
  const isDangerousDestination = (destText) => {
26
- // /tmp is SAFE - it's the standard temp location
27
13
  if (destText.startsWith('/tmp') || destText.includes('os.tmpdir') || destText.includes('TMPDIR')) {
28
14
  return false;
29
15
  }
@@ -176,42 +162,27 @@ exports.noZipSlip = (0, eslint_devkit_1.createRule)({
176
162
  const options = context.options[0] || {};
177
163
  const { archiveFunctions = ['extract', 'extractAll', 'extractAllTo', 'unzip', 'untar', 'extractArchive'], pathValidationFunctions = ['validatePath', 'sanitizePath', 'checkPath', 'safePath'], safeLibraries = ['yauzl', 'safe-archive-extract', 'tar-stream', 'unzipper'], } = options;
178
164
  const filename = context.filename;
179
- // Safety checks are implemented directly in the handlers
180
- /**
181
- * Check if this is an archive extraction operation
182
- */
183
165
  const isArchiveExtraction = (node) => {
184
166
  const callee = node.callee;
185
- // Check for archive method calls (e.g., zip.extractAllTo)
186
167
  if (callee.type === 'MemberExpression' &&
187
168
  callee.property.type === 'Identifier' &&
188
169
  archiveFunctions.includes(callee.property.name)) {
189
170
  return true;
190
171
  }
191
- // Check for standalone archive functions (e.g., extractArchive)
192
172
  if (callee.type === 'Identifier' &&
193
173
  archiveFunctions.includes(callee.name)) {
194
174
  return true;
195
175
  }
196
176
  return false;
197
177
  };
198
- /**
199
- * Check if path has been validated or sanitized
200
- * Detects patterns like:
201
- * - validatePath(), sanitizePath() custom functions
202
- * - path.basename() sanitization
203
- * - startsWith() validation in preceding if-block
204
- */
205
178
  const isPathValidated = (pathNode) => {
206
179
  let current = pathNode;
207
180
  while (current) {
208
- // Check for custom validation function wrappers
209
181
  if (current.type === 'CallExpression' &&
210
182
  current.callee.type === 'Identifier' &&
211
183
  pathValidationFunctions.includes(current.callee.name)) {
212
184
  return true;
213
185
  }
214
- // Check for path.basename() sanitization
215
186
  if (current.type === 'CallExpression' &&
216
187
  current.callee.type === 'MemberExpression' &&
217
188
  current.callee.object.type === 'Identifier' &&
@@ -220,10 +191,8 @@ exports.noZipSlip = (0, eslint_devkit_1.createRule)({
220
191
  current.callee.property.name === 'basename') {
221
192
  return true;
222
193
  }
223
- // Check for preceding if-block with startsWith validation
224
194
  if (current.type === 'IfStatement') {
225
195
  const test = current.test;
226
- // if (path.startsWith(...)) or if (!path.startsWith(...)) { throw/return }
227
196
  if (test.type === 'CallExpression' &&
228
197
  test.callee.type === 'MemberExpression' &&
229
198
  test.callee.property.type === 'Identifier' &&
@@ -237,7 +206,6 @@ exports.noZipSlip = (0, eslint_devkit_1.createRule)({
237
206
  test.argument.callee.property.name === 'startsWith') {
238
207
  return true;
239
208
  }
240
- // if (path.includes('..')) { throw/return }
241
209
  if (test.type === 'CallExpression' &&
242
210
  test.callee.type === 'MemberExpression' &&
243
211
  test.callee.property.type === 'Identifier' &&
@@ -249,20 +217,13 @@ exports.noZipSlip = (0, eslint_devkit_1.createRule)({
249
217
  }
250
218
  return false;
251
219
  };
252
- /**
253
- * Check if this uses a safe library
254
- * Safe libraries have built-in path validation or are known to be secure
255
- */
256
220
  const isSafeLibrary = (node) => {
257
221
  const callee = node.callee;
258
- // Check for method calls on safe library instances (e.g., yauzl.open())
259
222
  if (callee.type === 'MemberExpression' &&
260
223
  callee.object.type === 'Identifier' &&
261
224
  safeLibraries.includes(callee.object.name)) {
262
225
  return true;
263
226
  }
264
- // Check for direct calls to safe library functions (e.g., extract(file, opts))
265
- // This handles patterns like: const extract = require('extract-zip'); extract(...)
266
227
  if (callee.type === 'Identifier') {
267
228
  const name = callee.name.toLowerCase();
268
229
  if (name === 'extract' || name === 'unzipper' ||
@@ -273,13 +234,10 @@ exports.noZipSlip = (0, eslint_devkit_1.createRule)({
273
234
  return false;
274
235
  };
275
236
  return {
276
- // Check archive extraction calls
277
237
  CallExpression(node) {
278
238
  if (isArchiveExtraction(node) && !isSafeLibrary(node)) {
279
- // Check for @safe annotations in the source
280
239
  const sourceCode = context.sourceCode;
281
240
  let hasSafeAnnotation = false;
282
- // Look for @safe comments in the source code
283
241
  const allComments = sourceCode.getAllComments();
284
242
  for (const comment of allComments) {
285
243
  if (comment.type === 'Block' && comment.value.includes('@safe')) {
@@ -288,36 +246,26 @@ exports.noZipSlip = (0, eslint_devkit_1.createRule)({
288
246
  }
289
247
  }
290
248
  if (hasSafeAnnotation) {
291
- return; // Skip reporting if marked as safe
249
+ return;
292
250
  }
293
- // Check if destination is dangerous
294
251
  const args = node.arguments;
295
252
  let destArg;
296
- // Determine which argument is the destination based on the function
297
253
  if (node.callee.type === 'MemberExpression' && node.callee.property.type === 'Identifier') {
298
254
  const methodName = node.callee.property.name;
299
255
  if (['extractAllTo', 'unzip'].includes(methodName)) {
300
- // Destination is the first argument
301
256
  destArg = args[0];
302
257
  }
303
258
  else {
304
- // For other archive functions, destination is typically the
305
- // second argument. isArchiveExtraction() already guaranteed
306
- // methodName is listed in archiveFunctions for member callees.
307
259
  destArg = args.length >= 2 ? args[1] : undefined;
308
260
  }
309
261
  }
310
262
  else {
311
- // For standalone functions like extractArchive(file, dest);
312
- // isArchiveExtraction() already guaranteed the callee is an
313
- // Identifier naming an archive function.
314
263
  destArg = args.length >= 2 ? args[1] : undefined;
315
264
  }
316
265
  const destText = destArg && destArg.type === 'Literal' && typeof destArg.value === 'string' ? destArg.value : '';
317
266
  const isDestDangerous = isDangerousDestination(destText);
318
267
  const isMethodCall = node.callee.type === 'MemberExpression';
319
268
  if (isMethodCall) {
320
- // Method calls report unsafeArchiveExtraction unless destination is a safe relative path
321
269
  const isSafeRelativePath = destText.startsWith('./') || destText.startsWith('../');
322
270
  if (!isSafeRelativePath) {
323
271
  context.report({
@@ -335,10 +283,6 @@ exports.noZipSlip = (0, eslint_devkit_1.createRule)({
335
283
  ],
336
284
  });
337
285
  }
338
- // For safe relative paths, don't report any error
339
- // Additionally report dangerous destination for dangerous destinations.
340
- // `isDestDangerous` implies `destArg` is a string Literal (destText
341
- // is derived from it), so no `|| node` fallback is needed here.
342
286
  if (isDestDangerous && destArg) {
343
287
  context.report({
344
288
  node: destArg,
@@ -351,7 +295,6 @@ exports.noZipSlip = (0, eslint_devkit_1.createRule)({
351
295
  }
352
296
  }
353
297
  else {
354
- // Standalone calls: report dangerousArchiveDestination for dangerous destinations, unsafeArchiveExtraction otherwise
355
298
  if (isDestDangerous) {
356
299
  context.report({
357
300
  node,
@@ -380,18 +323,15 @@ exports.noZipSlip = (0, eslint_devkit_1.createRule)({
380
323
  }
381
324
  }
382
325
  }
383
- // Check for path.join or similar operations with archive entry names
384
326
  const callee = node.callee;
385
327
  if (callee.type === 'MemberExpression' &&
386
328
  callee.property.type === 'Identifier' &&
387
329
  ['join', 'resolve', 'relative', 'normalize'].includes(callee.property.name)) {
388
- // Check arguments for potential archive entry usage
389
330
  const args = node.arguments;
390
331
  for (const arg of args) {
391
332
  if (arg.type === 'MemberExpression' &&
392
333
  arg.property.type === 'Identifier' &&
393
334
  ['name', 'path', 'fileName', 'entryName', 'relativePath', 'filename', 'pathname'].includes(arg.property.name)) {
394
- // This looks like path.join(dest, entry.name) - check if validated
395
335
  if (!isPathValidated(arg)) {
396
336
  context.report({
397
337
  node: arg,
@@ -406,19 +346,14 @@ exports.noZipSlip = (0, eslint_devkit_1.createRule)({
406
346
  }
407
347
  }
408
348
  },
409
- // Check string literals for dangerous paths
410
349
  Literal(node) {
411
350
  if (typeof node.value !== 'string') {
412
351
  return;
413
352
  }
414
353
  const text = node.value;
415
- // Check for path traversal in strings that look like file paths
416
354
  if ((text.includes('/') || text.includes('\\')) && containsPathTraversal(text)) {
417
- // Check if this is in an archive-related context
418
355
  let current = node;
419
356
  let isArchiveContext = false;
420
- // Every assignment of `isArchiveContext = true` is followed by `break`,
421
- // so the negation is dead (CodeQL: `js/useless-conditional`).
422
357
  while (current) {
423
358
  if (current.type === 'CallExpression' && isArchiveExtraction(current)) {
424
359
  isArchiveContext = true;
@@ -437,7 +372,6 @@ exports.noZipSlip = (0, eslint_devkit_1.createRule)({
437
372
  }
438
373
  current = current.parent;
439
374
  }
440
- // Also check if the variable name suggests archive usage
441
375
  const parent = node.parent;
442
376
  if (parent && parent.type === 'VariableDeclarator' && parent.id.type === 'Identifier') {
443
377
  const varName = parent.id.name.toLowerCase();
@@ -458,31 +392,19 @@ exports.noZipSlip = (0, eslint_devkit_1.createRule)({
458
392
  });
459
393
  }
460
394
  }
461
- // Dangerous-destination check moved to the CallExpression handler
462
- // (see lines 407-427). It already fires `dangerousArchiveDestination`
463
- // for archive-extraction calls; firing again here would duplicate.
464
- // The previous "fire on any /etc or /home literal" logic produced
465
- // false positives on unrelated calls (fs.readFileSync, exec, etc.)
466
- // and is no longer needed now that the call-site check is precise.
467
395
  },
468
- // Check variable assignments
469
396
  VariableDeclarator(node) {
470
397
  if (!node.init || node.id.type !== 'Identifier') {
471
398
  return;
472
399
  }
473
400
  const varName = node.id.name.toLowerCase();
474
- // Check if this variable holds archive-related data
475
401
  if (varName.includes('entry') || varName.includes('file') || varName.includes('path')) {
476
402
  if (node.init.type === 'MemberExpression' &&
477
403
  node.init.property.type === 'Identifier' &&
478
404
  ['name', 'path'].includes(node.init.property.name)) {
479
- // This looks like: const entryName = entry.name;
480
- // Check if this variable is used unsafely later
481
- // This is a simplified check - in practice we'd need more sophisticated analysis
482
405
  }
483
406
  }
484
407
  }
485
408
  };
486
409
  },
487
410
  });
488
- //# sourceMappingURL=index.js.map
@@ -1,21 +1,15 @@
1
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
2
  Object.defineProperty(exports, "__esModule", { value: true });
8
3
  exports.preferNativeCrypto = void 0;
9
4
  const eslint_devkit_1 = require("@interlace/eslint-devkit");
10
- // Third-party crypto libraries that should be replaced with native
11
5
  const THIRD_PARTY_CRYPTO_LIBS = new Set([
12
6
  'crypto-js',
13
7
  'cryptojs',
14
- 'sjcl', // Stanford JavaScript Crypto Library
15
- 'forge', // node-forge
8
+ 'sjcl',
9
+ 'forge',
16
10
  'node-forge',
17
11
  'jsencrypt',
18
- 'bcryptjs', // pure JS bcrypt (prefer native bcrypt)
12
+ 'bcryptjs',
19
13
  'js-sha256',
20
14
  'js-sha512',
21
15
  'js-sha3',
@@ -102,7 +96,7 @@ exports.preferNativeCrypto = (0, eslint_devkit_1.createRule)({
102
96
  return {
103
97
  ImportDeclaration(node) {
104
98
  if (typeof node.source.value === 'string') {
105
- const lib = node.source.value.split('/')[0]; // Get base package name
99
+ const lib = node.source.value.split('/')[0];
106
100
  if (THIRD_PARTY_CRYPTO_LIBS.has(lib)) {
107
101
  reportThirdPartyLib(node, lib);
108
102
  }
@@ -123,4 +117,3 @@ exports.preferNativeCrypto = (0, eslint_devkit_1.createRule)({
123
117
  };
124
118
  },
125
119
  });
126
- //# sourceMappingURL=index.js.map
@@ -1,14 +1,6 @@
1
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
2
  Object.defineProperty(exports, "__esModule", { value: true });
8
3
  exports.requireDependencyIntegrity = void 0;
9
- /**
10
- * @fileoverview Require integrity hashes for external resources
11
- */
12
4
  const eslint_devkit_1 = require("@interlace/eslint-devkit");
13
5
  exports.requireDependencyIntegrity = (0, eslint_devkit_1.createRule)({
14
6
  name: 'require-dependency-integrity',
@@ -42,11 +34,9 @@ exports.requireDependencyIntegrity = (0, eslint_devkit_1.createRule)({
42
34
  Literal(node) {
43
35
  if (typeof node.value !== 'string')
44
36
  return;
45
- // Check for script/link tags without integrity
46
37
  const value = node.value.toLowerCase();
47
38
  if ((value.includes('<script') && value.includes('src=')) ||
48
39
  (value.includes('<link') && value.includes('href='))) {
49
- // Check if CDN source
50
40
  if (value.includes('cdn.') || value.includes('cdnjs.') ||
51
41
  value.includes('unpkg.') || value.includes('jsdelivr.')) {
52
42
  if (!value.includes('integrity=')) {
@@ -70,4 +60,3 @@ exports.requireDependencyIntegrity = (0, eslint_devkit_1.createRule)({
70
60
  };
71
61
  },
72
62
  });
73
- //# sourceMappingURL=index.js.map
@@ -1,16 +1,6 @@
1
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
2
  Object.defineProperty(exports, "__esModule", { value: true });
8
3
  exports.requireSecureCredentialStorage = void 0;
9
- /**
10
- * @fileoverview Enforce secure storage patterns for credentials
11
- * @see https://owasp.org/www-project-mobile-top-10/
12
- * @see https://cwe.mitre.org/data/definitions/522.html
13
- */
14
4
  const eslint_devkit_1 = require("@interlace/eslint-devkit");
15
5
  exports.requireSecureCredentialStorage = (0, eslint_devkit_1.createRule)({
16
6
  name: 'require-secure-credential-storage',
@@ -42,7 +32,6 @@ exports.requireSecureCredentialStorage = (0, eslint_devkit_1.createRule)({
42
32
  if (node.callee.type === eslint_devkit_1.AST_NODE_TYPES.MemberExpression &&
43
33
  node.callee.property.type === eslint_devkit_1.AST_NODE_TYPES.Identifier &&
44
34
  ['setItem', 'writeFile'].includes(node.callee.property.name)) {
45
- // Check for encryption wrapper
46
35
  const hasEncryption = node.arguments.some(arg => arg.type === eslint_devkit_1.AST_NODE_TYPES.CallExpression &&
47
36
  arg.callee.type === eslint_devkit_1.AST_NODE_TYPES.Identifier &&
48
37
  arg.callee.name.includes('encrypt'));
@@ -54,4 +43,3 @@ exports.requireSecureCredentialStorage = (0, eslint_devkit_1.createRule)({
54
43
  };
55
44
  },
56
45
  });
57
- //# sourceMappingURL=index.js.map
@@ -1,29 +1,7 @@
1
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
2
  Object.defineProperty(exports, "__esModule", { value: true });
8
3
  exports.requireSecureDeletion = void 0;
9
- /**
10
- * @fileoverview Require secure data deletion patterns
11
- * @see https://owasp.org/www-project-mobile-top-10/
12
- * @see https://cwe.mitre.org/data/definitions/459.html
13
- */
14
4
  const eslint_devkit_1 = require("@interlace/eslint-devkit");
15
- /**
16
- * Property-name fragments that mark a value as a secret whose lifetime matters.
17
- *
18
- * `delete` unbinds a property; it does not scrub the string, and every other
19
- * reference (a spread copy, a log line, an already-serialised response body)
20
- * keeps the value alive. That is the CWE-459 "incomplete cleanup" this rule is
21
- * about — and it only means anything when the property actually held a secret.
22
- *
23
- * Matching is on the property NAME, deliberately: the value at a `delete` site
24
- * is not available to a syntactic rule, so the name is the only signal there
25
- * is. The cost of that is bounded by keeping this list narrow.
26
- */
27
5
  const SENSITIVE_PROPERTY_FRAGMENTS = [
28
6
  'password', 'passwd', 'pwd', 'passphrase',
29
7
  'secret', 'apikey', 'api_key',
@@ -75,9 +53,7 @@ exports.requireSecureDeletion = (0, eslint_devkit_1.createRule)({
75
53
  ...SENSITIVE_PROPERTY_FRAGMENTS,
76
54
  ...additionalSensitiveProperties.map((f) => f.toLowerCase()),
77
55
  ];
78
- /** The property name being deleted, or undefined if it isn't statically known. */
79
56
  function deletedPropertyName(node) {
80
- // `delete obj?.password` wraps the member expression in a ChainExpression.
81
57
  const argument = node.type === 'ChainExpression' ? node.expression : node;
82
58
  if (argument.type !== 'MemberExpression')
83
59
  return undefined;
@@ -93,10 +69,6 @@ exports.requireSecureDeletion = (0, eslint_devkit_1.createRule)({
93
69
  UnaryExpression(node) {
94
70
  if (node.operator !== 'delete')
95
71
  return;
96
- // Only a `delete` of a *named, statically known, sensitive* property is
97
- // reportable. Firing on every `delete obj.prop` produced 120 findings
98
- // on a 1,470-file corpus with no security content whatsoever — the rule
99
- // was a `delete` detector, not a secret-cleanup detector.
100
72
  const property = deletedPropertyName(node.argument);
101
73
  if (!property)
102
74
  return;
@@ -108,4 +80,3 @@ exports.requireSecureDeletion = (0, eslint_devkit_1.createRule)({
108
80
  };
109
81
  },
110
82
  });
111
- //# sourceMappingURL=index.js.map
@@ -1,16 +1,6 @@
1
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
2
  Object.defineProperty(exports, "__esModule", { value: true });
8
3
  exports.requireStorageEncryption = void 0;
9
- /**
10
- * @fileoverview Require encryption for persistent storage
11
- * @see https://owasp.org/www-project-mobile-top-10/
12
- * @see https://cwe.mitre.org/data/definitions/311.html
13
- */
14
4
  const eslint_devkit_1 = require("@interlace/eslint-devkit");
15
5
  exports.requireStorageEncryption = (0, eslint_devkit_1.createRule)({
16
6
  name: 'require-storage-encryption',
@@ -42,7 +32,6 @@ exports.requireStorageEncryption = (0, eslint_devkit_1.createRule)({
42
32
  if (node.callee.type === 'MemberExpression' &&
43
33
  node.callee.property.type === 'Identifier' &&
44
34
  ['setItem', 'writeFile'].includes(node.callee.property.name)) {
45
- // Check for encryption wrapper
46
35
  const hasEncryption = node.arguments.some(arg => arg.type === 'CallExpression' &&
47
36
  arg.callee.type === 'Identifier' &&
48
37
  arg.callee.name.includes('encrypt'));
@@ -54,4 +43,3 @@ exports.requireStorageEncryption = (0, eslint_devkit_1.createRule)({
54
43
  };
55
44
  },
56
45
  });
57
- //# sourceMappingURL=index.js.map
@@ -1,8 +1,2 @@
1
1
  "use strict";
2
- /**
3
- * eslint-plugin-node-security Type Exports
4
- *
5
- * Barrel file that exports all Node.js security rule Options types.
6
- */
7
2
  Object.defineProperty(exports, "__esModule", { value: true });
8
- //# sourceMappingURL=index.js.map