eslint-plugin-node-security 4.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.
Files changed (102) hide show
  1. package/CHANGELOG.md +83 -0
  2. package/README.md +50 -0
  3. package/package.json +79 -0
  4. package/src/index.d.ts +10 -0
  5. package/src/index.js +118 -0
  6. package/src/index.js.map +1 -0
  7. package/src/rules/detect-child-process/index.d.ts +30 -0
  8. package/src/rules/detect-child-process/index.js +535 -0
  9. package/src/rules/detect-child-process/index.js.map +1 -0
  10. package/src/rules/detect-eval-with-expression/index.d.ts +28 -0
  11. package/src/rules/detect-eval-with-expression/index.js +398 -0
  12. package/src/rules/detect-eval-with-expression/index.js.map +1 -0
  13. package/src/rules/detect-non-literal-fs-filename/index.d.ts +26 -0
  14. package/src/rules/detect-non-literal-fs-filename/index.js +460 -0
  15. package/src/rules/detect-non-literal-fs-filename/index.js.map +1 -0
  16. package/src/rules/detect-suspicious-dependencies/index.d.ts +12 -0
  17. package/src/rules/detect-suspicious-dependencies/index.js +77 -0
  18. package/src/rules/detect-suspicious-dependencies/index.js.map +1 -0
  19. package/src/rules/lock-file/index.d.ts +13 -0
  20. package/src/rules/lock-file/index.js +94 -0
  21. package/src/rules/lock-file/index.js.map +1 -0
  22. package/src/rules/no-arbitrary-file-access/index.d.ts +12 -0
  23. package/src/rules/no-arbitrary-file-access/index.js +201 -0
  24. package/src/rules/no-arbitrary-file-access/index.js.map +1 -0
  25. package/src/rules/no-buffer-overread/index.d.ts +39 -0
  26. package/src/rules/no-buffer-overread/index.js +612 -0
  27. package/src/rules/no-buffer-overread/index.js.map +1 -0
  28. package/src/rules/no-cryptojs/index.d.ts +24 -0
  29. package/src/rules/no-cryptojs/index.js +104 -0
  30. package/src/rules/no-cryptojs/index.js.map +1 -0
  31. package/src/rules/no-cryptojs-weak-random/index.d.ts +24 -0
  32. package/src/rules/no-cryptojs-weak-random/index.js +112 -0
  33. package/src/rules/no-cryptojs-weak-random/index.js.map +1 -0
  34. package/src/rules/no-data-in-temp-storage/index.d.ts +14 -0
  35. package/src/rules/no-data-in-temp-storage/index.js +99 -0
  36. package/src/rules/no-data-in-temp-storage/index.js.map +1 -0
  37. package/src/rules/no-deprecated-cipher-method/index.d.ts +23 -0
  38. package/src/rules/no-deprecated-cipher-method/index.js +118 -0
  39. package/src/rules/no-deprecated-cipher-method/index.js.map +1 -0
  40. package/src/rules/no-dynamic-dependency-loading/index.d.ts +12 -0
  41. package/src/rules/no-dynamic-dependency-loading/index.js +55 -0
  42. package/src/rules/no-dynamic-dependency-loading/index.js.map +1 -0
  43. package/src/rules/no-dynamic-require/index.d.ts +21 -0
  44. package/src/rules/no-dynamic-require/index.js +122 -0
  45. package/src/rules/no-dynamic-require/index.js.map +1 -0
  46. package/src/rules/no-ecb-mode/index.d.ts +23 -0
  47. package/src/rules/no-ecb-mode/index.js +113 -0
  48. package/src/rules/no-ecb-mode/index.js.map +1 -0
  49. package/src/rules/no-insecure-key-derivation/index.d.ts +24 -0
  50. package/src/rules/no-insecure-key-derivation/index.js +116 -0
  51. package/src/rules/no-insecure-key-derivation/index.js.map +1 -0
  52. package/src/rules/no-insecure-rsa-padding/index.d.ts +24 -0
  53. package/src/rules/no-insecure-rsa-padding/index.js +110 -0
  54. package/src/rules/no-insecure-rsa-padding/index.js.map +1 -0
  55. package/src/rules/no-pii-in-logs/index.d.ts +12 -0
  56. package/src/rules/no-pii-in-logs/index.js +74 -0
  57. package/src/rules/no-pii-in-logs/index.js.map +1 -0
  58. package/src/rules/no-self-signed-certs/index.d.ts +23 -0
  59. package/src/rules/no-self-signed-certs/index.js +116 -0
  60. package/src/rules/no-self-signed-certs/index.js.map +1 -0
  61. package/src/rules/no-sha1-hash/index.d.ts +24 -0
  62. package/src/rules/no-sha1-hash/index.js +128 -0
  63. package/src/rules/no-sha1-hash/index.js.map +1 -0
  64. package/src/rules/no-static-iv/index.d.ts +23 -0
  65. package/src/rules/no-static-iv/index.js +147 -0
  66. package/src/rules/no-static-iv/index.js.map +1 -0
  67. package/src/rules/no-timing-unsafe-compare/index.d.ts +23 -0
  68. package/src/rules/no-timing-unsafe-compare/index.js +114 -0
  69. package/src/rules/no-timing-unsafe-compare/index.js.map +1 -0
  70. package/src/rules/no-toctou-vulnerability/index.d.ts +26 -0
  71. package/src/rules/no-toctou-vulnerability/index.js +214 -0
  72. package/src/rules/no-toctou-vulnerability/index.js.map +1 -0
  73. package/src/rules/no-unsafe-dynamic-require/index.d.ts +19 -0
  74. package/src/rules/no-unsafe-dynamic-require/index.js +112 -0
  75. package/src/rules/no-unsafe-dynamic-require/index.js.map +1 -0
  76. package/src/rules/no-weak-cipher-algorithm/index.d.ts +25 -0
  77. package/src/rules/no-weak-cipher-algorithm/index.js +190 -0
  78. package/src/rules/no-weak-cipher-algorithm/index.js.map +1 -0
  79. package/src/rules/no-weak-hash-algorithm/index.d.ts +25 -0
  80. package/src/rules/no-weak-hash-algorithm/index.js +218 -0
  81. package/src/rules/no-weak-hash-algorithm/index.js.map +1 -0
  82. package/src/rules/no-zip-slip/index.d.ts +35 -0
  83. package/src/rules/no-zip-slip/index.js +451 -0
  84. package/src/rules/no-zip-slip/index.js.map +1 -0
  85. package/src/rules/prefer-native-crypto/index.d.ts +23 -0
  86. package/src/rules/prefer-native-crypto/index.js +124 -0
  87. package/src/rules/prefer-native-crypto/index.js.map +1 -0
  88. package/src/rules/require-dependency-integrity/index.d.ts +12 -0
  89. package/src/rules/require-dependency-integrity/index.js +70 -0
  90. package/src/rules/require-dependency-integrity/index.js.map +1 -0
  91. package/src/rules/require-secure-credential-storage/index.d.ts +12 -0
  92. package/src/rules/require-secure-credential-storage/index.js +54 -0
  93. package/src/rules/require-secure-credential-storage/index.js.map +1 -0
  94. package/src/rules/require-secure-deletion/index.d.ts +12 -0
  95. package/src/rules/require-secure-deletion/index.js +46 -0
  96. package/src/rules/require-secure-deletion/index.js.map +1 -0
  97. package/src/rules/require-storage-encryption/index.d.ts +12 -0
  98. package/src/rules/require-storage-encryption/index.js +54 -0
  99. package/src/rules/require-storage-encryption/index.js.map +1 -0
  100. package/src/types/index.d.ts +24 -0
  101. package/src/types/index.js +8 -0
  102. package/src/types/index.js.map +1 -0
@@ -0,0 +1,70 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.requireDependencyIntegrity = void 0;
9
+ /**
10
+ * @fileoverview Require integrity hashes for external resources
11
+ */
12
+ const eslint_devkit_1 = require("@interlace/eslint-devkit");
13
+ exports.requireDependencyIntegrity = (0, eslint_devkit_1.createRule)({
14
+ name: 'require-dependency-integrity',
15
+ meta: {
16
+ type: 'problem',
17
+ docs: {
18
+ description: 'Require SRI (Subresource Integrity) for CDN resources',
19
+ },
20
+ messages: {
21
+ violationDetected: (0, eslint_devkit_1.formatLLMMessage)({
22
+ icon: eslint_devkit_1.MessageIcons.SECURITY,
23
+ issueName: 'Missing SRI',
24
+ cwe: 'CWE-494',
25
+ description: 'External resource loaded without integrity hash - supply chain risk',
26
+ severity: 'HIGH',
27
+ fix: 'Add integrity="sha384-..." and crossorigin="anonymous" attributes',
28
+ documentationLink: 'https://cwe.mitre.org/data/definitions/494.html',
29
+ })
30
+ },
31
+ schema: [],
32
+ },
33
+ defaultOptions: [],
34
+ create(context) {
35
+ function report(node) {
36
+ context.report({ node, messageId: 'violationDetected' });
37
+ }
38
+ return {
39
+ Literal(node) {
40
+ if (typeof node.value !== 'string')
41
+ return;
42
+ // Check for script/link tags without integrity
43
+ const value = node.value.toLowerCase();
44
+ if ((value.includes('<script') && value.includes('src=')) ||
45
+ (value.includes('<link') && value.includes('href='))) {
46
+ // Check if CDN source
47
+ if (value.includes('cdn.') || value.includes('cdnjs.') ||
48
+ value.includes('unpkg.') || value.includes('jsdelivr.')) {
49
+ if (!value.includes('integrity=')) {
50
+ report(node);
51
+ }
52
+ }
53
+ }
54
+ },
55
+ TemplateLiteral(node) {
56
+ const text = context.sourceCode.getText(node).toLowerCase();
57
+ if ((text.includes('<script') && text.includes('src=')) ||
58
+ (text.includes('<link') && text.includes('href='))) {
59
+ if (text.includes('cdn.') || text.includes('cdnjs.') ||
60
+ text.includes('unpkg.') || text.includes('jsdelivr.')) {
61
+ if (!text.includes('integrity=')) {
62
+ report(node);
63
+ }
64
+ }
65
+ }
66
+ },
67
+ };
68
+ },
69
+ });
70
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../packages/eslint-plugin-node-security/src/rules/require-dependency-integrity/index.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAEH;;GAEG;AAEH,4DAAsF;AAUzE,QAAA,0BAA0B,GAAG,IAAA,0BAAU,EAA0B;IAC5E,IAAI,EAAE,8BAA8B;IACpC,IAAI,EAAE;QACJ,IAAI,EAAE,SAAS;QACf,IAAI,EAAE;YACJ,WAAW,EAAE,uDAAuD;SACrE;QACD,QAAQ,EAAE;YACR,iBAAiB,EAAE,IAAA,gCAAgB,EAAC;gBAClC,IAAI,EAAE,4BAAY,CAAC,QAAQ;gBAC3B,SAAS,EAAE,aAAa;gBACxB,GAAG,EAAE,SAAS;gBACd,WAAW,EAAE,qEAAqE;gBAClF,QAAQ,EAAE,MAAM;gBAChB,GAAG,EAAE,mEAAmE;gBACxE,iBAAiB,EAAE,iDAAiD;aACrE,CAAC;SACH;QACD,MAAM,EAAE,EAAE;KACX;IACD,cAAc,EAAE,EAAE;IAClB,MAAM,CAAC,OAAO;QACZ,SAAS,MAAM,CAAC,IAAmB;YACjC,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,mBAAmB,EAAE,CAAC,CAAC;QAC3D,CAAC;QAED,OAAO;YACL,OAAO,CAAC,IAAsB;gBAC5B,IAAI,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ;oBAAE,OAAO;gBAE3C,+CAA+C;gBAC/C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;gBACvC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;oBACrD,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC;oBAEzD,sBAAsB;oBACtB,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC;wBAClD,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;wBAE5D,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;4BAClC,MAAM,CAAC,IAAI,CAAC,CAAC;wBACf,CAAC;oBACH,CAAC;gBACH,CAAC;YACH,CAAC;YAED,eAAe,CAAC,IAA8B;gBAC5C,MAAM,IAAI,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;gBAE5D,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;oBACnD,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC;oBAEvD,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;wBAChD,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;wBAE1D,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;4BACjC,MAAM,CAAC,IAAI,CAAC,CAAC;wBACf,CAAC;oBACH,CAAC;gBACH,CAAC;YACH,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC,CAAC"}
@@ -0,0 +1,12 @@
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
+ export interface Options {
7
+ }
8
+ type RuleOptions = [Options?];
9
+ export declare const requireSecureCredentialStorage: import("@typescript-eslint/utils/ts-eslint").RuleModule<"violationDetected", RuleOptions, unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
10
+ name: string;
11
+ };
12
+ export {};
@@ -0,0 +1,54 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ 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
+ const eslint_devkit_1 = require("@interlace/eslint-devkit");
15
+ exports.requireSecureCredentialStorage = (0, eslint_devkit_1.createRule)({
16
+ name: 'require-secure-credential-storage',
17
+ meta: {
18
+ type: 'problem',
19
+ docs: {
20
+ description: 'Enforce secure storage patterns for credentials',
21
+ },
22
+ messages: {
23
+ violationDetected: (0, eslint_devkit_1.formatLLMMessage)({
24
+ icon: eslint_devkit_1.MessageIcons.SECURITY,
25
+ issueName: 'violation Detected',
26
+ cwe: 'CWE-312',
27
+ description: 'Enforce secure storage patterns for credentials detected - Credentials without encryption',
28
+ severity: 'HIGH',
29
+ fix: 'Review and apply secure practices',
30
+ documentationLink: 'https://cwe.mitre.org/data/definitions/312.html',
31
+ })
32
+ },
33
+ schema: [],
34
+ },
35
+ defaultOptions: [],
36
+ create(context) {
37
+ return {
38
+ CallExpression(node) {
39
+ if (node.callee.type === eslint_devkit_1.AST_NODE_TYPES.MemberExpression &&
40
+ node.callee.property.type === eslint_devkit_1.AST_NODE_TYPES.Identifier &&
41
+ ['setItem', 'writeFile'].includes(node.callee.property.name)) {
42
+ // Check for encryption wrapper
43
+ const hasEncryption = node.arguments.some(arg => arg.type === eslint_devkit_1.AST_NODE_TYPES.CallExpression &&
44
+ arg.callee.type === eslint_devkit_1.AST_NODE_TYPES.Identifier &&
45
+ arg.callee.name.includes('encrypt'));
46
+ if (!hasEncryption) {
47
+ context.report({ node, messageId: 'violationDetected' });
48
+ }
49
+ }
50
+ },
51
+ };
52
+ },
53
+ });
54
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../packages/eslint-plugin-node-security/src/rules/require-secure-credential-storage/index.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAEH;;;;GAIG;AAEH,4DAAsG;AAUzF,QAAA,8BAA8B,GAAG,IAAA,0BAAU,EAA0B;IAChF,IAAI,EAAE,mCAAmC;IACzC,IAAI,EAAE;QACJ,IAAI,EAAE,SAAS;QACf,IAAI,EAAE;YACJ,WAAW,EAAE,iDAAiD;SAC/D;QACD,QAAQ,EAAE;YACR,iBAAiB,EAAE,IAAA,gCAAgB,EAAC;gBAClC,IAAI,EAAE,4BAAY,CAAC,QAAQ;gBAC3B,SAAS,EAAE,oBAAoB;gBAC/B,GAAG,EAAE,SAAS;gBACd,WAAW,EAAE,2FAA2F;gBACxG,QAAQ,EAAE,MAAM;gBAChB,GAAG,EAAE,mCAAmC;gBACxC,iBAAiB,EAAE,iDAAiD;aACrE,CAAC;SACH;QACD,MAAM,EAAE,EAAE;KACX;IACD,cAAc,EAAE,EAAE;IAClB,MAAM,CAAC,OAAO;QACZ,OAAO;YACL,cAAc,CAAC,IAA6B;gBAC1C,IACE,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,8BAAc,CAAC,gBAAgB;oBACpD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,KAAK,8BAAc,CAAC,UAAU;oBACvD,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,EAC5D,CAAC;oBACD,+BAA+B;oBAC/B,MAAM,aAAa,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAC9C,GAAG,CAAC,IAAI,KAAK,8BAAc,CAAC,cAAc;wBAC1C,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,8BAAc,CAAC,UAAU;wBAC7C,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CACpC,CAAC;oBACF,IAAI,CAAC,aAAa,EAAE,CAAC;wBACnB,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,mBAAmB,EAAE,CAAC,CAAC;oBAC3D,CAAC;gBACH,CAAC;YACH,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC,CAAC"}
@@ -0,0 +1,12 @@
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
+ export interface Options {
7
+ }
8
+ type RuleOptions = [Options?];
9
+ export declare const requireSecureDeletion: import("@typescript-eslint/utils/ts-eslint").RuleModule<"violationDetected", RuleOptions, unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
10
+ name: string;
11
+ };
12
+ export {};
@@ -0,0 +1,46 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ 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
+ const eslint_devkit_1 = require("@interlace/eslint-devkit");
15
+ exports.requireSecureDeletion = (0, eslint_devkit_1.createRule)({
16
+ name: 'require-secure-deletion',
17
+ meta: {
18
+ type: 'problem',
19
+ docs: {
20
+ description: 'Require secure data deletion patterns',
21
+ },
22
+ messages: {
23
+ violationDetected: (0, eslint_devkit_1.formatLLMMessage)({
24
+ icon: eslint_devkit_1.MessageIcons.SECURITY,
25
+ issueName: 'violation Detected',
26
+ cwe: 'CWE-459',
27
+ description: 'Require secure data deletion patterns detected - delete without secure wipe',
28
+ severity: 'MEDIUM',
29
+ fix: 'Review and apply secure practices',
30
+ documentationLink: 'https://cwe.mitre.org/data/definitions/459.html',
31
+ })
32
+ },
33
+ schema: [],
34
+ },
35
+ defaultOptions: [],
36
+ create(context) {
37
+ return {
38
+ UnaryExpression(node) {
39
+ if (node.operator === 'delete') {
40
+ context.report({ node, messageId: 'violationDetected' });
41
+ }
42
+ },
43
+ };
44
+ },
45
+ });
46
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../packages/eslint-plugin-node-security/src/rules/require-secure-deletion/index.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAEH;;;;GAIG;AAEH,4DAAsF;AAUzE,QAAA,qBAAqB,GAAG,IAAA,0BAAU,EAA0B;IACvE,IAAI,EAAE,yBAAyB;IAC/B,IAAI,EAAE;QACJ,IAAI,EAAE,SAAS;QACf,IAAI,EAAE;YACJ,WAAW,EAAE,uCAAuC;SACrD;QACD,QAAQ,EAAE;YACR,iBAAiB,EAAE,IAAA,gCAAgB,EAAC;gBAClC,IAAI,EAAE,4BAAY,CAAC,QAAQ;gBAC3B,SAAS,EAAE,oBAAoB;gBAC/B,GAAG,EAAE,SAAS;gBACd,WAAW,EAAE,6EAA6E;gBAC1F,QAAQ,EAAE,QAAQ;gBAClB,GAAG,EAAE,mCAAmC;gBACxC,iBAAiB,EAAE,iDAAiD;aACrE,CAAC;SACH;QACD,MAAM,EAAE,EAAE;KACX;IACD,cAAc,EAAE,EAAE;IAClB,MAAM,CAAC,OAAO;QACZ,OAAO;YAEL,eAAe,CAAC,IAA8B;gBAC5C,IAAI,IAAI,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;oBAC/B,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,mBAAmB,EAAE,CAAC,CAAC;gBAC3D,CAAC;YACH,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC,CAAC"}
@@ -0,0 +1,12 @@
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
+ export interface Options {
7
+ }
8
+ type RuleOptions = [Options?];
9
+ export declare const requireStorageEncryption: import("@typescript-eslint/utils/ts-eslint").RuleModule<"violationDetected", RuleOptions, unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
10
+ name: string;
11
+ };
12
+ export {};
@@ -0,0 +1,54 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ 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
+ const eslint_devkit_1 = require("@interlace/eslint-devkit");
15
+ exports.requireStorageEncryption = (0, eslint_devkit_1.createRule)({
16
+ name: 'require-storage-encryption',
17
+ meta: {
18
+ type: 'problem',
19
+ docs: {
20
+ description: 'Require encryption for persistent storage',
21
+ },
22
+ messages: {
23
+ violationDetected: (0, eslint_devkit_1.formatLLMMessage)({
24
+ icon: eslint_devkit_1.MessageIcons.SECURITY,
25
+ issueName: 'violation Detected',
26
+ cwe: 'CWE-312',
27
+ description: 'Require encryption for persistent storage detected - Storage without encryption',
28
+ severity: 'HIGH',
29
+ fix: 'Review and apply secure practices',
30
+ documentationLink: 'https://cwe.mitre.org/data/definitions/312.html',
31
+ })
32
+ },
33
+ schema: [],
34
+ },
35
+ defaultOptions: [],
36
+ create(context) {
37
+ return {
38
+ CallExpression(node) {
39
+ if (node.callee.type === 'MemberExpression' &&
40
+ node.callee.property.type === 'Identifier' &&
41
+ ['setItem', 'writeFile'].includes(node.callee.property.name)) {
42
+ // Check for encryption wrapper
43
+ const hasEncryption = node.arguments.some(arg => arg.type === 'CallExpression' &&
44
+ arg.callee.type === 'Identifier' &&
45
+ arg.callee.name.includes('encrypt'));
46
+ if (!hasEncryption) {
47
+ context.report({ node, messageId: 'violationDetected' });
48
+ }
49
+ }
50
+ },
51
+ };
52
+ },
53
+ });
54
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../packages/eslint-plugin-node-security/src/rules/require-storage-encryption/index.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAEH;;;;GAIG;AAEH,4DAAsF;AAUzE,QAAA,wBAAwB,GAAG,IAAA,0BAAU,EAA0B;IAC1E,IAAI,EAAE,4BAA4B;IAClC,IAAI,EAAE;QACJ,IAAI,EAAE,SAAS;QACf,IAAI,EAAE;YACJ,WAAW,EAAE,2CAA2C;SACzD;QACD,QAAQ,EAAE;YACR,iBAAiB,EAAE,IAAA,gCAAgB,EAAC;gBAClC,IAAI,EAAE,4BAAY,CAAC,QAAQ;gBAC3B,SAAS,EAAE,oBAAoB;gBAC/B,GAAG,EAAE,SAAS;gBACd,WAAW,EAAE,iFAAiF;gBAC9F,QAAQ,EAAE,MAAM;gBAChB,GAAG,EAAE,mCAAmC;gBACxC,iBAAiB,EAAE,iDAAiD;aACrE,CAAC;SACH;QACD,MAAM,EAAE,EAAE;KACX;IACD,cAAc,EAAE,EAAE;IAClB,MAAM,CAAC,OAAO;QACZ,OAAO;YAEL,cAAc,CAAC,IAA6B;gBAC1C,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,kBAAkB;oBACvC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,KAAK,YAAY;oBAC1C,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;oBACjE,+BAA+B;oBAC/B,MAAM,aAAa,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAC9C,GAAG,CAAC,IAAI,KAAK,gBAAgB;wBAC7B,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,YAAY;wBAChC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CACpC,CAAC;oBACF,IAAI,CAAC,aAAa,EAAE,CAAC;wBACnB,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,mBAAmB,EAAE,CAAC,CAAC;oBAC3D,CAAC;gBACH,CAAC;YACH,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC,CAAC"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * eslint-plugin-node-security Type Exports
3
+ *
4
+ * Barrel file that exports all Node.js security rule Options types.
5
+ */
6
+ import type { Options as DetectChildProcessOptions } from '../rules/detect-child-process';
7
+ import type { Options as DetectEvalWithExpressionOptions } from '../rules/detect-eval-with-expression';
8
+ import type { Options as DetectNonLiteralFsFilenameOptions } from '../rules/detect-non-literal-fs-filename';
9
+ import type { Options as NoUnsafeDynamicRequireOptions } from '../rules/no-unsafe-dynamic-require';
10
+ import type { Options as NoBufferOverreadOptions } from '../rules/no-buffer-overread';
11
+ import type { Options as NoToctouVulnerabilityOptions } from '../rules/no-toctou-vulnerability';
12
+ import type { Options as NoZipSlipOptions } from '../rules/no-zip-slip';
13
+ import type { Options as NoArbitraryFileAccessOptions } from '../rules/no-arbitrary-file-access';
14
+ export type { DetectChildProcessOptions, DetectEvalWithExpressionOptions, DetectNonLiteralFsFilenameOptions, NoUnsafeDynamicRequireOptions, NoBufferOverreadOptions, NoToctouVulnerabilityOptions, NoZipSlipOptions, NoArbitraryFileAccessOptions, };
15
+ export type AllNodeSecurityRulesOptions = {
16
+ 'detect-child-process'?: DetectChildProcessOptions;
17
+ 'detect-eval-with-expression'?: DetectEvalWithExpressionOptions;
18
+ 'detect-non-literal-fs-filename'?: DetectNonLiteralFsFilenameOptions;
19
+ 'no-unsafe-dynamic-require'?: NoUnsafeDynamicRequireOptions;
20
+ 'no-buffer-overread'?: NoBufferOverreadOptions;
21
+ 'no-toctou-vulnerability'?: NoToctouVulnerabilityOptions;
22
+ 'no-zip-slip'?: NoZipSlipOptions;
23
+ 'no-arbitrary-file-access'?: NoArbitraryFileAccessOptions;
24
+ };
@@ -0,0 +1,8 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../packages/eslint-plugin-node-security/src/types/index.ts"],"names":[],"mappings":";AAAA;;;;GAIG"}