eslint-plugin-secure-coding 3.0.1 → 3.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.
Files changed (128) hide show
  1. package/README.md +2 -1
  2. package/package.json +4 -3
  3. package/src/index.d.ts +2 -2
  4. package/src/index.js +29 -263
  5. package/src/rules/detect-non-literal-regexp/index.d.ts +3 -1
  6. package/src/rules/detect-object-injection/index.d.ts +3 -1
  7. package/src/rules/detect-weak-password-validation/index.d.ts +3 -1
  8. package/src/rules/no-directive-injection/index.d.ts +3 -1
  9. package/src/rules/no-electron-security-issues/index.d.ts +3 -1
  10. package/src/rules/no-format-string-injection/index.d.ts +3 -1
  11. package/src/rules/no-graphql-injection/index.d.ts +3 -1
  12. package/src/rules/no-hardcoded-credentials/index.d.ts +3 -1
  13. package/src/rules/no-hardcoded-session-tokens/index.d.ts +3 -1
  14. package/src/rules/no-improper-sanitization/index.d.ts +3 -1
  15. package/src/rules/no-improper-type-validation/index.d.ts +3 -1
  16. package/src/rules/no-insecure-comparison/index.d.ts +3 -1
  17. package/src/rules/no-ldap-injection/index.d.ts +3 -1
  18. package/src/rules/no-missing-authentication/index.d.ts +3 -1
  19. package/src/rules/no-pii-in-logs/index.d.ts +3 -1
  20. package/src/rules/no-privilege-escalation/index.d.ts +3 -1
  21. package/src/rules/no-redos-vulnerable-regex/index.d.ts +3 -1
  22. package/src/rules/no-sensitive-data-exposure/index.d.ts +3 -1
  23. package/src/rules/no-unchecked-loop-condition/index.d.ts +3 -1
  24. package/src/rules/no-unlimited-resource-allocation/index.d.ts +3 -1
  25. package/src/rules/no-unsafe-deserialization/index.d.ts +3 -1
  26. package/src/rules/no-unsafe-regex-construction/index.d.ts +3 -1
  27. package/src/rules/no-weak-password-recovery/index.d.ts +3 -1
  28. package/src/rules/no-xpath-injection/index.d.ts +3 -1
  29. package/src/rules/no-xxe-injection/index.d.ts +3 -1
  30. package/src/rules/require-backend-authorization/index.d.ts +3 -1
  31. package/src/rules/require-secure-defaults/index.d.ts +3 -1
  32. package/src/types/index.d.ts +5 -52
  33. package/src/rules/detect-child-process/index.d.ts +0 -28
  34. package/src/rules/detect-child-process/index.js +0 -534
  35. package/src/rules/detect-eval-with-expression/index.d.ts +0 -26
  36. package/src/rules/detect-eval-with-expression/index.js +0 -397
  37. package/src/rules/detect-mixed-content/index.d.ts +0 -10
  38. package/src/rules/detect-mixed-content/index.js +0 -45
  39. package/src/rules/detect-non-literal-fs-filename/index.d.ts +0 -24
  40. package/src/rules/detect-non-literal-fs-filename/index.js +0 -459
  41. package/src/rules/detect-suspicious-dependencies/index.d.ts +0 -10
  42. package/src/rules/detect-suspicious-dependencies/index.js +0 -76
  43. package/src/rules/no-allow-arbitrary-loads/index.d.ts +0 -10
  44. package/src/rules/no-allow-arbitrary-loads/index.js +0 -48
  45. package/src/rules/no-arbitrary-file-access/index.d.ts +0 -10
  46. package/src/rules/no-arbitrary-file-access/index.js +0 -200
  47. package/src/rules/no-buffer-overread/index.d.ts +0 -37
  48. package/src/rules/no-buffer-overread/index.js +0 -611
  49. package/src/rules/no-clickjacking/index.d.ts +0 -34
  50. package/src/rules/no-clickjacking/index.js +0 -401
  51. package/src/rules/no-client-side-auth-logic/index.d.ts +0 -10
  52. package/src/rules/no-client-side-auth-logic/index.js +0 -74
  53. package/src/rules/no-credentials-in-query-params/index.d.ts +0 -10
  54. package/src/rules/no-credentials-in-query-params/index.js +0 -62
  55. package/src/rules/no-data-in-temp-storage/index.d.ts +0 -10
  56. package/src/rules/no-data-in-temp-storage/index.js +0 -69
  57. package/src/rules/no-debug-code-in-production/index.d.ts +0 -10
  58. package/src/rules/no-debug-code-in-production/index.js +0 -54
  59. package/src/rules/no-disabled-certificate-validation/index.d.ts +0 -10
  60. package/src/rules/no-disabled-certificate-validation/index.js +0 -66
  61. package/src/rules/no-dynamic-dependency-loading/index.d.ts +0 -10
  62. package/src/rules/no-dynamic-dependency-loading/index.js +0 -54
  63. package/src/rules/no-exposed-debug-endpoints/index.d.ts +0 -10
  64. package/src/rules/no-exposed-debug-endpoints/index.js +0 -67
  65. package/src/rules/no-exposed-sensitive-data/index.d.ts +0 -28
  66. package/src/rules/no-exposed-sensitive-data/index.js +0 -345
  67. package/src/rules/no-http-urls/index.d.ts +0 -15
  68. package/src/rules/no-http-urls/index.js +0 -119
  69. package/src/rules/no-insecure-redirects/index.d.ts +0 -24
  70. package/src/rules/no-insecure-redirects/index.js +0 -221
  71. package/src/rules/no-insecure-websocket/index.d.ts +0 -10
  72. package/src/rules/no-insecure-websocket/index.js +0 -66
  73. package/src/rules/no-missing-cors-check/index.d.ts +0 -26
  74. package/src/rules/no-missing-cors-check/index.js +0 -404
  75. package/src/rules/no-missing-csrf-protection/index.d.ts +0 -28
  76. package/src/rules/no-missing-csrf-protection/index.js +0 -185
  77. package/src/rules/no-missing-security-headers/index.d.ts +0 -24
  78. package/src/rules/no-missing-security-headers/index.js +0 -223
  79. package/src/rules/no-password-in-url/index.d.ts +0 -10
  80. package/src/rules/no-password-in-url/index.js +0 -55
  81. package/src/rules/no-permissive-cors/index.d.ts +0 -10
  82. package/src/rules/no-permissive-cors/index.js +0 -74
  83. package/src/rules/no-sensitive-data-in-analytics/index.d.ts +0 -10
  84. package/src/rules/no-sensitive-data-in-analytics/index.js +0 -66
  85. package/src/rules/no-sensitive-data-in-cache/index.d.ts +0 -10
  86. package/src/rules/no-sensitive-data-in-cache/index.js +0 -53
  87. package/src/rules/no-toctou-vulnerability/index.d.ts +0 -24
  88. package/src/rules/no-toctou-vulnerability/index.js +0 -213
  89. package/src/rules/no-tracking-without-consent/index.d.ts +0 -10
  90. package/src/rules/no-tracking-without-consent/index.js +0 -72
  91. package/src/rules/no-unencrypted-transmission/index.d.ts +0 -28
  92. package/src/rules/no-unencrypted-transmission/index.js +0 -241
  93. package/src/rules/no-unescaped-url-parameter/index.d.ts +0 -26
  94. package/src/rules/no-unescaped-url-parameter/index.js +0 -360
  95. package/src/rules/no-unsafe-dynamic-require/index.d.ts +0 -17
  96. package/src/rules/no-unsafe-dynamic-require/index.js +0 -111
  97. package/src/rules/no-unvalidated-deeplinks/index.d.ts +0 -10
  98. package/src/rules/no-unvalidated-deeplinks/index.js +0 -67
  99. package/src/rules/no-unvalidated-user-input/index.d.ts +0 -26
  100. package/src/rules/no-unvalidated-user-input/index.js +0 -425
  101. package/src/rules/no-verbose-error-messages/index.d.ts +0 -10
  102. package/src/rules/no-verbose-error-messages/index.js +0 -73
  103. package/src/rules/no-zip-slip/index.d.ts +0 -33
  104. package/src/rules/no-zip-slip/index.js +0 -450
  105. package/src/rules/require-code-minification/index.d.ts +0 -10
  106. package/src/rules/require-code-minification/index.js +0 -48
  107. package/src/rules/require-csp-headers/index.d.ts +0 -10
  108. package/src/rules/require-csp-headers/index.js +0 -69
  109. package/src/rules/require-data-minimization/index.d.ts +0 -10
  110. package/src/rules/require-data-minimization/index.js +0 -55
  111. package/src/rules/require-dependency-integrity/index.d.ts +0 -10
  112. package/src/rules/require-dependency-integrity/index.js +0 -69
  113. package/src/rules/require-https-only/index.d.ts +0 -10
  114. package/src/rules/require-https-only/index.js +0 -67
  115. package/src/rules/require-mime-type-validation/index.d.ts +0 -10
  116. package/src/rules/require-mime-type-validation/index.js +0 -71
  117. package/src/rules/require-network-timeout/index.d.ts +0 -10
  118. package/src/rules/require-network-timeout/index.js +0 -57
  119. package/src/rules/require-package-lock/index.d.ts +0 -10
  120. package/src/rules/require-package-lock/index.js +0 -64
  121. package/src/rules/require-secure-credential-storage/index.d.ts +0 -10
  122. package/src/rules/require-secure-credential-storage/index.js +0 -53
  123. package/src/rules/require-secure-deletion/index.d.ts +0 -10
  124. package/src/rules/require-secure-deletion/index.js +0 -45
  125. package/src/rules/require-storage-encryption/index.d.ts +0 -10
  126. package/src/rules/require-storage-encryption/index.js +0 -53
  127. package/src/rules/require-url-validation/index.d.ts +0 -10
  128. package/src/rules/require-url-validation/index.js +0 -77
@@ -1,223 +0,0 @@
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.noMissingSecurityHeaders = void 0;
9
- const eslint_devkit_1 = require("@interlace/eslint-devkit");
10
- const eslint_devkit_2 = require("@interlace/eslint-devkit");
11
- const DEFAULT_REQUIRED_HEADERS = [
12
- 'Content-Security-Policy',
13
- 'X-Frame-Options',
14
- 'X-Content-Type-Options',
15
- ];
16
- /**
17
- * Extract header name from setHeader call
18
- */
19
- function extractHeaderName(node) {
20
- if (node.arguments.length > 0 && node.arguments[0].type === 'Literal') {
21
- return String(node.arguments[0].value);
22
- }
23
- return null;
24
- }
25
- /**
26
- * Check if all security headers are set in the current scope
27
- */
28
- function checkFunctionForSecurityHeaders(node, requiredHeaders, context) {
29
- const setHeaders = new Set();
30
- // Find the function that contains this setHeader call
31
- let current = node;
32
- let scopeNode = null;
33
- while (current) {
34
- if (current.type === 'FunctionDeclaration' ||
35
- current.type === 'FunctionExpression' ||
36
- current.type === 'ArrowFunctionExpression') {
37
- scopeNode = current;
38
- break;
39
- }
40
- current = current.parent ?? null;
41
- }
42
- // If no function found, use the program scope (for test cases)
43
- if (!scopeNode) {
44
- scopeNode = context.sourceCode.ast;
45
- }
46
- // Collect all setHeader calls in this scope
47
- function collectHeaders(node) {
48
- if (node.type === 'CallExpression' &&
49
- node.callee.type === 'MemberExpression' &&
50
- node.callee.property.type === 'Identifier' &&
51
- ['setHeader', 'header', 'set'].includes(node.callee.property.name)) {
52
- const headerName = extractHeaderName(node);
53
- if (headerName) {
54
- setHeaders.add(headerName);
55
- }
56
- }
57
- // Recursively check children - only traverse standard AST properties
58
- if (node.type === 'Program' && node.body) {
59
- node.body.forEach(collectHeaders);
60
- }
61
- else if ((node.type === 'FunctionDeclaration' ||
62
- node.type === 'FunctionExpression' ||
63
- node.type === 'ArrowFunctionExpression') && node.body) {
64
- collectHeaders(node.body);
65
- }
66
- else if (node.type === 'BlockStatement' && node.body) {
67
- node.body.forEach(collectHeaders);
68
- }
69
- else if (node.type === 'ExpressionStatement' && node.expression) {
70
- collectHeaders(node.expression);
71
- }
72
- }
73
- if (scopeNode) {
74
- collectHeaders(scopeNode);
75
- }
76
- // Return missing headers
77
- return requiredHeaders.filter(header => !setHeaders.has(header));
78
- }
79
- exports.noMissingSecurityHeaders = (0, eslint_devkit_2.createRule)({
80
- name: 'no-missing-security-headers',
81
- meta: {
82
- type: 'problem',
83
- deprecated: true,
84
- replacedBy: ['@see eslint-plugin-express-security/require-helmet'],
85
- docs: {
86
- description: 'Detects missing security headers in HTTP responses',
87
- },
88
- hasSuggestions: true,
89
- messages: {
90
- missingSecurityHeader: (0, eslint_devkit_1.formatLLMMessage)({
91
- icon: eslint_devkit_1.MessageIcons.SECURITY,
92
- issueName: 'Missing security headers',
93
- cwe: 'CWE-693',
94
- description: 'Missing security headers: {{headers}}',
95
- severity: 'HIGH',
96
- fix: 'Set security headers: Content-Security-Policy, X-Frame-Options, X-Content-Type-Options',
97
- documentationLink: 'https://owasp.org/www-project-secure-headers/',
98
- }),
99
- addSecurityHeaders: (0, eslint_devkit_1.formatLLMMessage)({
100
- icon: eslint_devkit_1.MessageIcons.INFO,
101
- issueName: 'Add Security Headers',
102
- description: 'Add security headers middleware',
103
- severity: 'LOW',
104
- fix: 'Add Content-Security-Policy, X-Frame-Options headers',
105
- documentationLink: 'https://owasp.org/www-project-secure-headers/',
106
- }),
107
- useMiddleware: (0, eslint_devkit_1.formatLLMMessage)({
108
- icon: eslint_devkit_1.MessageIcons.INFO,
109
- issueName: 'Use Helmet',
110
- description: 'Use helmet.js for security headers',
111
- severity: 'LOW',
112
- fix: 'app.use(helmet())',
113
- documentationLink: 'https://helmetjs.github.io/',
114
- }),
115
- setHeader: (0, eslint_devkit_1.formatLLMMessage)({
116
- icon: eslint_devkit_1.MessageIcons.INFO,
117
- issueName: 'Set Headers',
118
- description: 'Set security headers manually',
119
- severity: 'LOW',
120
- fix: 'res.setHeader("X-Frame-Options", "DENY")',
121
- documentationLink: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers',
122
- }),
123
- },
124
- schema: [
125
- {
126
- type: 'object',
127
- properties: {
128
- requiredHeaders: {
129
- type: 'array',
130
- items: { type: 'string' },
131
- default: DEFAULT_REQUIRED_HEADERS,
132
- },
133
- ignoreInTests: {
134
- type: 'boolean',
135
- default: true,
136
- },
137
- },
138
- additionalProperties: false,
139
- },
140
- ],
141
- },
142
- defaultOptions: [
143
- {
144
- requiredHeaders: DEFAULT_REQUIRED_HEADERS,
145
- ignoreInTests: true,
146
- },
147
- ],
148
- create(context, [options = {}]) {
149
- const { requiredHeaders = DEFAULT_REQUIRED_HEADERS, ignoreInTests = true, } = options || {};
150
- const filename = context.getFilename();
151
- const isTestFile = ignoreInTests && /\.(test|spec)\.(ts|tsx|js|jsx)$/.test(filename);
152
- if (isTestFile) {
153
- return {};
154
- }
155
- const reportedScopes = new Set();
156
- /**
157
- * Get a unique key for the current scope
158
- */
159
- function getScopeKey(node) {
160
- // Find the function that contains this call
161
- let current = node;
162
- while (current) {
163
- if (current.type === 'FunctionDeclaration' ||
164
- current.type === 'FunctionExpression' ||
165
- current.type === 'ArrowFunctionExpression') {
166
- return `${current.range?.[0]}-${current.range?.[1]}`;
167
- }
168
- current = current.parent ?? null;
169
- }
170
- // If no function found, use program scope
171
- return 'program';
172
- }
173
- /**
174
- * Check for response header setting
175
- */
176
- function checkCallExpression(node) {
177
- // Check for res.setHeader, res.header, res.set
178
- if (node.callee.type === 'MemberExpression' &&
179
- node.callee.property.type === 'Identifier') {
180
- const methodName = node.callee.property.name;
181
- if (['setHeader', 'header', 'set'].includes(methodName)) {
182
- const scopeKey = getScopeKey(node);
183
- // Only check once per scope
184
- if (reportedScopes.has(scopeKey)) {
185
- return;
186
- }
187
- const missing = checkFunctionForSecurityHeaders(node, requiredHeaders, context);
188
- if (missing.length > 0) {
189
- reportedScopes.add(scopeKey);
190
- context.report({
191
- node,
192
- messageId: 'missingSecurityHeader',
193
- data: {
194
- headers: missing.join(', '),
195
- },
196
- suggest: [
197
- {
198
- messageId: 'addSecurityHeaders',
199
- fix: () => null,
200
- },
201
- {
202
- messageId: 'useMiddleware',
203
- fix: () => null,
204
- },
205
- {
206
- messageId: 'setHeader',
207
- fix: () => null,
208
- },
209
- ],
210
- });
211
- }
212
- else {
213
- // Mark as checked even if no error
214
- reportedScopes.add(scopeKey);
215
- }
216
- }
217
- }
218
- }
219
- return {
220
- CallExpression: checkCallExpression,
221
- };
222
- },
223
- });
@@ -1,10 +0,0 @@
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 noPasswordInUrl: import("@typescript-eslint/utils/ts-eslint").RuleModule<"violationDetected", RuleOptions, unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
10
- export {};
@@ -1,55 +0,0 @@
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.noPasswordInUrl = void 0;
9
- /**
10
- * @fileoverview Prevent passwords in URLs
11
- * @see https://owasp.org/www-project-mobile-top-10/
12
- * @see https://cwe.mitre.org/data/definitions/598.html
13
- */
14
- const eslint_devkit_1 = require("@interlace/eslint-devkit");
15
- exports.noPasswordInUrl = (0, eslint_devkit_1.createRule)({
16
- name: 'no-password-in-url',
17
- meta: {
18
- type: 'problem',
19
- docs: {
20
- description: 'Prevent passwords in URLs',
21
- },
22
- messages: {
23
- violationDetected: (0, eslint_devkit_1.formatLLMMessage)({
24
- icon: eslint_devkit_1.MessageIcons.SECURITY,
25
- issueName: 'violation Detected',
26
- cwe: 'CWE-521',
27
- description: 'Prevent passwords in URLs detected - this is a security risk',
28
- severity: 'CRITICAL',
29
- fix: 'Review and apply secure practices',
30
- documentationLink: 'https://cwe.mitre.org/data/definitions/521.html',
31
- })
32
- },
33
- schema: [],
34
- },
35
- defaultOptions: [],
36
- create(context) {
37
- function report(node) {
38
- context.report({
39
- node,
40
- messageId: 'violationDetected',
41
- });
42
- }
43
- return {
44
- Literal(node) {
45
- // Check for http://user:password@host patterns
46
- if (node.type === 'Literal' && typeof node.value === 'string') {
47
- const urlPattern = /https?:\/\/[^:]+:[^@]+@/;
48
- if (urlPattern.test(node.value)) {
49
- report(node);
50
- }
51
- }
52
- },
53
- };
54
- },
55
- });
@@ -1,10 +0,0 @@
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 noPermissiveCors: import("@typescript-eslint/utils/ts-eslint").RuleModule<"violationDetected", RuleOptions, unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
10
- export {};
@@ -1,74 +0,0 @@
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.noPermissiveCors = void 0;
9
- /**
10
- * @fileoverview Prevent overly permissive CORS configuration
11
- * @see https://owasp.org/www-project-mobile-top-10/
12
- * @see https://cwe.mitre.org/data/definitions/942.html
13
- */
14
- const eslint_devkit_1 = require("@interlace/eslint-devkit");
15
- exports.noPermissiveCors = (0, eslint_devkit_1.createRule)({
16
- name: 'no-permissive-cors',
17
- meta: {
18
- type: 'problem',
19
- deprecated: true,
20
- replacedBy: ['@see eslint-plugin-express-security/no-permissive-cors'],
21
- docs: {
22
- description: 'Prevent overly permissive CORS configuration',
23
- },
24
- messages: {
25
- violationDetected: (0, eslint_devkit_1.formatLLMMessage)({
26
- icon: eslint_devkit_1.MessageIcons.SECURITY,
27
- issueName: 'violation Detected',
28
- cwe: 'CWE-942',
29
- description: 'Prevent overly permissive CORS configuration detected - this is a security risk',
30
- severity: 'HIGH',
31
- fix: 'Review and apply secure practices',
32
- documentationLink: 'https://cwe.mitre.org/data/definitions/942.html',
33
- })
34
- },
35
- schema: [],
36
- },
37
- defaultOptions: [],
38
- create(context) {
39
- function report(node) {
40
- context.report({
41
- node,
42
- messageId: 'violationDetected',
43
- });
44
- }
45
- return {
46
- CallExpression(node) {
47
- // Check for Access-Control-Allow-Origin: *
48
- // res.setHeader('Access-Control-Allow-Origin', '*')
49
- if (node.callee.type === eslint_devkit_1.AST_NODE_TYPES.MemberExpression &&
50
- node.callee.property.type === eslint_devkit_1.AST_NODE_TYPES.Identifier &&
51
- node.callee.property.name === 'setHeader' &&
52
- node.arguments[0]?.type === eslint_devkit_1.AST_NODE_TYPES.Literal &&
53
- node.arguments[0].value === 'Access-Control-Allow-Origin' &&
54
- node.arguments[1]?.type === eslint_devkit_1.AST_NODE_TYPES.Literal &&
55
- node.arguments[1].value === '*') {
56
- report(node);
57
- }
58
- // Check cors({ origin: '*' })
59
- if (node.callee.type === eslint_devkit_1.AST_NODE_TYPES.Identifier &&
60
- node.callee.name === 'cors' &&
61
- node.arguments[0]?.type === eslint_devkit_1.AST_NODE_TYPES.ObjectExpression) {
62
- const originProp = node.arguments[0].properties.find((p) => p.type === eslint_devkit_1.AST_NODE_TYPES.Property &&
63
- p.key.type === eslint_devkit_1.AST_NODE_TYPES.Identifier &&
64
- p.key.name === 'origin');
65
- if (originProp &&
66
- originProp.value.type === eslint_devkit_1.AST_NODE_TYPES.Literal &&
67
- originProp.value.value === '*') {
68
- report(node);
69
- }
70
- }
71
- },
72
- };
73
- },
74
- });
@@ -1,10 +0,0 @@
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 noSensitiveDataInAnalytics: import("@typescript-eslint/utils/ts-eslint").RuleModule<"violationDetected", RuleOptions, unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
10
- export {};
@@ -1,66 +0,0 @@
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.noSensitiveDataInAnalytics = void 0;
9
- /**
10
- * @fileoverview Prevent PII sent to analytics
11
- * @see https://owasp.org/www-project-mobile-top-10/
12
- * @see https://cwe.mitre.org/data/definitions/359.html
13
- */
14
- const eslint_devkit_1 = require("@interlace/eslint-devkit");
15
- exports.noSensitiveDataInAnalytics = (0, eslint_devkit_1.createRule)({
16
- name: 'no-sensitive-data-in-analytics',
17
- meta: {
18
- type: 'problem',
19
- docs: {
20
- description: 'Prevent PII being sent to analytics services',
21
- },
22
- messages: {
23
- violationDetected: (0, eslint_devkit_1.formatLLMMessage)({
24
- icon: eslint_devkit_1.MessageIcons.SECURITY,
25
- issueName: 'Sensitive Data in Analytics',
26
- cwe: 'CWE-359',
27
- description: 'Sensitive field sent to analytics - this is a privacy violation',
28
- severity: 'HIGH',
29
- fix: 'Remove PII from analytics tracking data',
30
- documentationLink: 'https://cwe.mitre.org/data/definitions/359.html',
31
- })
32
- },
33
- schema: [],
34
- },
35
- defaultOptions: [],
36
- create(context) {
37
- const sensitiveFields = ['email', 'ssn', 'creditcard', 'password', 'phone', 'address'];
38
- function report(node, field) {
39
- context.report({ node, messageId: 'violationDetected', data: { field } });
40
- }
41
- return {
42
- CallExpression(node) {
43
- // analytics.track() with sensitive data
44
- if (node.callee.type === eslint_devkit_1.AST_NODE_TYPES.MemberExpression &&
45
- node.callee.object.type === eslint_devkit_1.AST_NODE_TYPES.Identifier &&
46
- node.callee.object.name === 'analytics' &&
47
- node.callee.property.type === eslint_devkit_1.AST_NODE_TYPES.Identifier &&
48
- node.callee.property.name === 'track') {
49
- const dataArg = node.arguments[1];
50
- if (dataArg?.type === eslint_devkit_1.AST_NODE_TYPES.ObjectExpression) {
51
- dataArg.properties.forEach(prop => {
52
- if (prop.type === eslint_devkit_1.AST_NODE_TYPES.Property &&
53
- prop.key.type === eslint_devkit_1.AST_NODE_TYPES.Identifier) {
54
- const key = prop.key.name.toLowerCase();
55
- const matchedField = sensitiveFields.find(f => key.includes(f));
56
- if (matchedField) {
57
- report(prop, matchedField);
58
- }
59
- }
60
- });
61
- }
62
- }
63
- },
64
- };
65
- },
66
- });
@@ -1,10 +0,0 @@
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 noSensitiveDataInCache: import("@typescript-eslint/utils/ts-eslint").RuleModule<"violationDetected", RuleOptions, unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
10
- export {};
@@ -1,53 +0,0 @@
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.noSensitiveDataInCache = void 0;
9
- /**
10
- * @fileoverview Prevent caching sensitive data without encryption
11
- * @see https://owasp.org/www-project-mobile-top-10/
12
- * @see https://cwe.mitre.org/data/definitions/524.html
13
- */
14
- const eslint_devkit_1 = require("@interlace/eslint-devkit");
15
- exports.noSensitiveDataInCache = (0, eslint_devkit_1.createRule)({
16
- name: 'no-sensitive-data-in-cache',
17
- meta: {
18
- type: 'problem',
19
- docs: {
20
- description: 'Prevent caching sensitive data without encryption',
21
- },
22
- messages: {
23
- violationDetected: (0, eslint_devkit_1.formatLLMMessage)({
24
- icon: eslint_devkit_1.MessageIcons.SECURITY,
25
- issueName: 'violation Detected',
26
- cwe: 'CWE-200',
27
- description: 'Prevent caching sensitive data without encryption detected - Sensitive data in cache',
28
- severity: 'HIGH',
29
- fix: 'Review and apply secure practices',
30
- documentationLink: 'https://cwe.mitre.org/data/definitions/200.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
- ['set', 'put', 'store'].includes(node.callee.property.name)) {
42
- const keyArg = node.arguments[0];
43
- if (keyArg && keyArg.type === 'Literal') {
44
- const key = keyArg.value.toString().toLowerCase();
45
- if (['password', 'token', 'credit', 'ssn'].some(k => key.includes(k))) {
46
- context.report({ node, messageId: 'violationDetected' });
47
- }
48
- }
49
- }
50
- },
51
- };
52
- },
53
- });
@@ -1,24 +0,0 @@
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
- * ESLint Rule: no-toctou-vulnerability
8
- * Detects Time-of-Check-Time-of-Use vulnerabilities
9
- * CWE-367: Time-of-check Time-of-use (TOCTOU) Race Condition
10
- *
11
- * @see https://cwe.mitre.org/data/definitions/367.html
12
- * @see https://owasp.org/www-community/vulnerabilities/TOCTOU_Race_Condition
13
- */
14
- import type { TSESLint } from '@interlace/eslint-devkit';
15
- type MessageIds = 'toctouVulnerability' | 'useAtomicOperations' | 'useFsPromises' | 'addProperLocking';
16
- export interface Options {
17
- /** Ignore in test files. Default: true */
18
- ignoreInTests?: boolean;
19
- /** File system methods to check. Default: ['fs.existsSync', 'fs.statSync', 'fs.accessSync'] */
20
- fsMethods?: string[];
21
- }
22
- type RuleOptions = [Options?];
23
- export declare const noToctouVulnerability: TSESLint.RuleModule<MessageIds, RuleOptions, unknown, TSESLint.RuleListener>;
24
- export {};