eslint-plugin-secure-coding 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (155) hide show
  1. package/AGENTS.md +196 -0
  2. package/CHANGELOG.md +105 -0
  3. package/LICENSE +23 -0
  4. package/README.md +377 -0
  5. package/package.json +80 -0
  6. package/src/index.d.ts +32 -0
  7. package/src/index.js +345 -0
  8. package/src/index.js.map +1 -0
  9. package/src/rules/security/database-injection.d.ts +13 -0
  10. package/src/rules/security/database-injection.js +407 -0
  11. package/src/rules/security/database-injection.js.map +1 -0
  12. package/src/rules/security/detect-child-process.d.ts +11 -0
  13. package/src/rules/security/detect-child-process.js +460 -0
  14. package/src/rules/security/detect-child-process.js.map +1 -0
  15. package/src/rules/security/detect-eval-with-expression.d.ts +9 -0
  16. package/src/rules/security/detect-eval-with-expression.js +393 -0
  17. package/src/rules/security/detect-eval-with-expression.js.map +1 -0
  18. package/src/rules/security/detect-non-literal-fs-filename.d.ts +7 -0
  19. package/src/rules/security/detect-non-literal-fs-filename.js +322 -0
  20. package/src/rules/security/detect-non-literal-fs-filename.js.map +1 -0
  21. package/src/rules/security/detect-non-literal-regexp.d.ts +9 -0
  22. package/src/rules/security/detect-non-literal-regexp.js +387 -0
  23. package/src/rules/security/detect-non-literal-regexp.js.map +1 -0
  24. package/src/rules/security/detect-object-injection.d.ts +11 -0
  25. package/src/rules/security/detect-object-injection.js +411 -0
  26. package/src/rules/security/detect-object-injection.js.map +1 -0
  27. package/src/rules/security/no-buffer-overread.d.ts +14 -0
  28. package/src/rules/security/no-buffer-overread.js +519 -0
  29. package/src/rules/security/no-buffer-overread.js.map +1 -0
  30. package/src/rules/security/no-clickjacking.d.ts +10 -0
  31. package/src/rules/security/no-clickjacking.js +381 -0
  32. package/src/rules/security/no-clickjacking.js.map +1 -0
  33. package/src/rules/security/no-directive-injection.d.ts +12 -0
  34. package/src/rules/security/no-directive-injection.js +446 -0
  35. package/src/rules/security/no-directive-injection.js.map +1 -0
  36. package/src/rules/security/no-document-cookie.d.ts +5 -0
  37. package/src/rules/security/no-document-cookie.js +90 -0
  38. package/src/rules/security/no-document-cookie.js.map +1 -0
  39. package/src/rules/security/no-electron-security-issues.d.ts +10 -0
  40. package/src/rules/security/no-electron-security-issues.js +421 -0
  41. package/src/rules/security/no-electron-security-issues.js.map +1 -0
  42. package/src/rules/security/no-exposed-sensitive-data.d.ts +11 -0
  43. package/src/rules/security/no-exposed-sensitive-data.js +341 -0
  44. package/src/rules/security/no-exposed-sensitive-data.js.map +1 -0
  45. package/src/rules/security/no-format-string-injection.d.ts +17 -0
  46. package/src/rules/security/no-format-string-injection.js +653 -0
  47. package/src/rules/security/no-format-string-injection.js.map +1 -0
  48. package/src/rules/security/no-graphql-injection.d.ts +12 -0
  49. package/src/rules/security/no-graphql-injection.js +410 -0
  50. package/src/rules/security/no-graphql-injection.js.map +1 -0
  51. package/src/rules/security/no-hardcoded-credentials.d.ts +26 -0
  52. package/src/rules/security/no-hardcoded-credentials.js +377 -0
  53. package/src/rules/security/no-hardcoded-credentials.js.map +1 -0
  54. package/src/rules/security/no-improper-sanitization.d.ts +12 -0
  55. package/src/rules/security/no-improper-sanitization.js +408 -0
  56. package/src/rules/security/no-improper-sanitization.js.map +1 -0
  57. package/src/rules/security/no-improper-type-validation.d.ts +10 -0
  58. package/src/rules/security/no-improper-type-validation.js +420 -0
  59. package/src/rules/security/no-improper-type-validation.js.map +1 -0
  60. package/src/rules/security/no-insecure-comparison.d.ts +7 -0
  61. package/src/rules/security/no-insecure-comparison.js +125 -0
  62. package/src/rules/security/no-insecure-comparison.js.map +1 -0
  63. package/src/rules/security/no-insecure-cookie-settings.d.ts +9 -0
  64. package/src/rules/security/no-insecure-cookie-settings.js +305 -0
  65. package/src/rules/security/no-insecure-cookie-settings.js.map +1 -0
  66. package/src/rules/security/no-insecure-jwt.d.ts +10 -0
  67. package/src/rules/security/no-insecure-jwt.js +338 -0
  68. package/src/rules/security/no-insecure-jwt.js.map +1 -0
  69. package/src/rules/security/no-insecure-redirects.d.ts +7 -0
  70. package/src/rules/security/no-insecure-redirects.js +215 -0
  71. package/src/rules/security/no-insecure-redirects.js.map +1 -0
  72. package/src/rules/security/no-insufficient-postmessage-validation.d.ts +14 -0
  73. package/src/rules/security/no-insufficient-postmessage-validation.js +390 -0
  74. package/src/rules/security/no-insufficient-postmessage-validation.js.map +1 -0
  75. package/src/rules/security/no-insufficient-random.d.ts +9 -0
  76. package/src/rules/security/no-insufficient-random.js +207 -0
  77. package/src/rules/security/no-insufficient-random.js.map +1 -0
  78. package/src/rules/security/no-ldap-injection.d.ts +10 -0
  79. package/src/rules/security/no-ldap-injection.js +449 -0
  80. package/src/rules/security/no-ldap-injection.js.map +1 -0
  81. package/src/rules/security/no-missing-authentication.d.ts +13 -0
  82. package/src/rules/security/no-missing-authentication.js +322 -0
  83. package/src/rules/security/no-missing-authentication.js.map +1 -0
  84. package/src/rules/security/no-missing-cors-check.d.ts +9 -0
  85. package/src/rules/security/no-missing-cors-check.js +449 -0
  86. package/src/rules/security/no-missing-cors-check.js.map +1 -0
  87. package/src/rules/security/no-missing-csrf-protection.d.ts +11 -0
  88. package/src/rules/security/no-missing-csrf-protection.js +183 -0
  89. package/src/rules/security/no-missing-csrf-protection.js.map +1 -0
  90. package/src/rules/security/no-missing-security-headers.d.ts +7 -0
  91. package/src/rules/security/no-missing-security-headers.js +217 -0
  92. package/src/rules/security/no-missing-security-headers.js.map +1 -0
  93. package/src/rules/security/no-privilege-escalation.d.ts +13 -0
  94. package/src/rules/security/no-privilege-escalation.js +321 -0
  95. package/src/rules/security/no-privilege-escalation.js.map +1 -0
  96. package/src/rules/security/no-redos-vulnerable-regex.d.ts +7 -0
  97. package/src/rules/security/no-redos-vulnerable-regex.js +307 -0
  98. package/src/rules/security/no-redos-vulnerable-regex.js.map +1 -0
  99. package/src/rules/security/no-sensitive-data-exposure.d.ts +11 -0
  100. package/src/rules/security/no-sensitive-data-exposure.js +251 -0
  101. package/src/rules/security/no-sensitive-data-exposure.js.map +1 -0
  102. package/src/rules/security/no-sql-injection.d.ts +10 -0
  103. package/src/rules/security/no-sql-injection.js +332 -0
  104. package/src/rules/security/no-sql-injection.js.map +1 -0
  105. package/src/rules/security/no-timing-attack.d.ts +10 -0
  106. package/src/rules/security/no-timing-attack.js +358 -0
  107. package/src/rules/security/no-timing-attack.js.map +1 -0
  108. package/src/rules/security/no-toctou-vulnerability.d.ts +7 -0
  109. package/src/rules/security/no-toctou-vulnerability.js +165 -0
  110. package/src/rules/security/no-toctou-vulnerability.js.map +1 -0
  111. package/src/rules/security/no-unchecked-loop-condition.d.ts +12 -0
  112. package/src/rules/security/no-unchecked-loop-condition.js +635 -0
  113. package/src/rules/security/no-unchecked-loop-condition.js.map +1 -0
  114. package/src/rules/security/no-unencrypted-transmission.d.ts +11 -0
  115. package/src/rules/security/no-unencrypted-transmission.js +237 -0
  116. package/src/rules/security/no-unencrypted-transmission.js.map +1 -0
  117. package/src/rules/security/no-unescaped-url-parameter.d.ts +9 -0
  118. package/src/rules/security/no-unescaped-url-parameter.js +266 -0
  119. package/src/rules/security/no-unescaped-url-parameter.js.map +1 -0
  120. package/src/rules/security/no-unlimited-resource-allocation.d.ts +12 -0
  121. package/src/rules/security/no-unlimited-resource-allocation.js +659 -0
  122. package/src/rules/security/no-unlimited-resource-allocation.js.map +1 -0
  123. package/src/rules/security/no-unsafe-deserialization.d.ts +10 -0
  124. package/src/rules/security/no-unsafe-deserialization.js +501 -0
  125. package/src/rules/security/no-unsafe-deserialization.js.map +1 -0
  126. package/src/rules/security/no-unsafe-dynamic-require.d.ts +5 -0
  127. package/src/rules/security/no-unsafe-dynamic-require.js +107 -0
  128. package/src/rules/security/no-unsafe-dynamic-require.js.map +1 -0
  129. package/src/rules/security/no-unsafe-regex-construction.d.ts +9 -0
  130. package/src/rules/security/no-unsafe-regex-construction.js +292 -0
  131. package/src/rules/security/no-unsafe-regex-construction.js.map +1 -0
  132. package/src/rules/security/no-unsanitized-html.d.ts +9 -0
  133. package/src/rules/security/no-unsanitized-html.js +347 -0
  134. package/src/rules/security/no-unsanitized-html.js.map +1 -0
  135. package/src/rules/security/no-unvalidated-user-input.d.ts +9 -0
  136. package/src/rules/security/no-unvalidated-user-input.js +418 -0
  137. package/src/rules/security/no-unvalidated-user-input.js.map +1 -0
  138. package/src/rules/security/no-weak-crypto.d.ts +11 -0
  139. package/src/rules/security/no-weak-crypto.js +350 -0
  140. package/src/rules/security/no-weak-crypto.js.map +1 -0
  141. package/src/rules/security/no-weak-password-recovery.d.ts +12 -0
  142. package/src/rules/security/no-weak-password-recovery.js +401 -0
  143. package/src/rules/security/no-weak-password-recovery.js.map +1 -0
  144. package/src/rules/security/no-xpath-injection.d.ts +10 -0
  145. package/src/rules/security/no-xpath-injection.js +487 -0
  146. package/src/rules/security/no-xpath-injection.js.map +1 -0
  147. package/src/rules/security/no-xxe-injection.d.ts +7 -0
  148. package/src/rules/security/no-xxe-injection.js +270 -0
  149. package/src/rules/security/no-xxe-injection.js.map +1 -0
  150. package/src/rules/security/no-zip-slip.d.ts +9 -0
  151. package/src/rules/security/no-zip-slip.js +446 -0
  152. package/src/rules/security/no-zip-slip.js.map +1 -0
  153. package/src/types/index.d.ts +131 -0
  154. package/src/types/index.js +18 -0
  155. package/src/types/index.js.map +1 -0
@@ -0,0 +1,347 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.noUnsanitizedHtml = void 0;
4
+ const eslint_devkit_1 = require("@interlace/eslint-devkit");
5
+ const eslint_devkit_2 = require("@interlace/eslint-devkit");
6
+ /**
7
+ * Check if a node is inside a sanitization function call
8
+ */
9
+ function isInsideSanitizationCall(node, sourceCode, trustedLibraries) {
10
+ let current = node;
11
+ while (current) {
12
+ if (current.type === 'CallExpression') {
13
+ const callee = current.callee;
14
+ // Check if it's a sanitization library call
15
+ if (callee.type === 'MemberExpression') {
16
+ const object = callee.object;
17
+ if (object.type === 'Identifier') {
18
+ const objectName = object.name.toLowerCase();
19
+ if (trustedLibraries.some(lib => objectName.includes(lib.toLowerCase()))) {
20
+ return true;
21
+ }
22
+ }
23
+ }
24
+ // Check if it's a direct sanitization function call
25
+ if (callee.type === 'Identifier') {
26
+ const calleeName = callee.name.toLowerCase();
27
+ if (trustedLibraries.some(lib => calleeName.includes(lib.toLowerCase()))) {
28
+ return true;
29
+ }
30
+ // Check for common sanitization function names
31
+ if (['sanitize', 'sanitizeHtml', 'purify', 'escape'].includes(calleeName)) {
32
+ return true;
33
+ }
34
+ }
35
+ }
36
+ // Traverse up the AST
37
+ if ('parent' in current && current.parent) {
38
+ current = current.parent;
39
+ }
40
+ else {
41
+ break;
42
+ }
43
+ }
44
+ return false;
45
+ }
46
+ /**
47
+ * Check if a string matches any ignore pattern
48
+ */
49
+ function matchesIgnorePattern(text, ignorePatterns) {
50
+ return ignorePatterns.some(pattern => {
51
+ try {
52
+ const regex = new RegExp(pattern, 'i');
53
+ return regex.test(text);
54
+ }
55
+ catch {
56
+ // Invalid regex - treat as literal string match
57
+ return text.toLowerCase().includes(pattern.toLowerCase());
58
+ }
59
+ });
60
+ }
61
+ exports.noUnsanitizedHtml = (0, eslint_devkit_2.createRule)({
62
+ name: 'no-unsanitized-html',
63
+ meta: {
64
+ type: 'problem',
65
+ docs: {
66
+ description: 'Detects unsanitized HTML injection (dangerouslySetInnerHTML, innerHTML)',
67
+ },
68
+ hasSuggestions: true,
69
+ messages: {
70
+ unsanitizedHtml: (0, eslint_devkit_1.formatLLMMessage)({
71
+ icon: eslint_devkit_1.MessageIcons.SECURITY,
72
+ issueName: 'Unsanitized HTML Injection',
73
+ cwe: 'CWE-79',
74
+ description: 'Unsanitized HTML detected: {{htmlSource}}',
75
+ severity: 'CRITICAL',
76
+ fix: '{{safeAlternative}}',
77
+ documentationLink: 'https://cwe.mitre.org/data/definitions/79.html',
78
+ }),
79
+ useTextContent: (0, eslint_devkit_1.formatLLMMessage)({
80
+ icon: eslint_devkit_1.MessageIcons.INFO,
81
+ issueName: 'Use textContent',
82
+ description: 'Use textContent instead of innerHTML',
83
+ severity: 'LOW',
84
+ fix: 'element.textContent = userInput;',
85
+ documentationLink: 'https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent',
86
+ }),
87
+ useSanitizeLibrary: (0, eslint_devkit_1.formatLLMMessage)({
88
+ icon: eslint_devkit_1.MessageIcons.INFO,
89
+ issueName: 'Use Sanitization',
90
+ description: 'Use sanitization library',
91
+ severity: 'LOW',
92
+ fix: 'DOMPurify.sanitize(html) or sanitize-html',
93
+ documentationLink: 'https://github.com/cure53/DOMPurify',
94
+ }),
95
+ useDangerouslySetInnerHTML: (0, eslint_devkit_1.formatLLMMessage)({
96
+ icon: eslint_devkit_1.MessageIcons.INFO,
97
+ issueName: 'Sanitize First',
98
+ description: 'Sanitize before dangerouslySetInnerHTML',
99
+ severity: 'LOW',
100
+ fix: 'dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(html) }}',
101
+ documentationLink: 'https://react.dev/reference/react-dom/components/common#dangerously-setting-the-inner-html',
102
+ }),
103
+ },
104
+ schema: [
105
+ {
106
+ type: 'object',
107
+ properties: {
108
+ allowInTests: {
109
+ type: 'boolean',
110
+ default: false,
111
+ description: 'Allow unsanitized HTML in test files',
112
+ },
113
+ trustedLibraries: {
114
+ type: 'array',
115
+ items: { type: 'string' },
116
+ default: ['dompurify', 'sanitize-html', 'xss'],
117
+ description: 'Trusted sanitization libraries',
118
+ },
119
+ ignorePatterns: {
120
+ type: 'array',
121
+ items: { type: 'string' },
122
+ default: [],
123
+ description: 'Additional safe patterns to ignore',
124
+ },
125
+ },
126
+ additionalProperties: false,
127
+ },
128
+ ],
129
+ },
130
+ defaultOptions: [
131
+ {
132
+ allowInTests: false,
133
+ trustedLibraries: ['dompurify', 'sanitize-html', 'xss'],
134
+ ignorePatterns: [],
135
+ },
136
+ ],
137
+ create(context, [options = {}]) {
138
+ const { allowInTests = false, trustedLibraries = ['dompurify', 'sanitize-html', 'xss'], ignorePatterns = [], } = options;
139
+ const filename = context.getFilename();
140
+ const isTestFile = allowInTests && /\.(test|spec)\.(ts|tsx|js|jsx)$/.test(filename);
141
+ const sourceCode = context.sourceCode || context.sourceCode;
142
+ function checkAssignmentExpression(node) {
143
+ if (isTestFile) {
144
+ return;
145
+ }
146
+ // Check if left side is innerHTML
147
+ if (node.left.type === 'MemberExpression' &&
148
+ node.left.property.type === 'Identifier' &&
149
+ node.left.property.name === 'innerHTML') {
150
+ const memberExpr = node.left;
151
+ const property = memberExpr.property;
152
+ const text = sourceCode.getText(memberExpr);
153
+ // Check if the left side (variable/object) matches any ignore pattern
154
+ // This handles cases like testElement.innerHTML where testElement should be ignored
155
+ if (memberExpr.object.type === 'Identifier') {
156
+ const objectName = memberExpr.object.name;
157
+ if (matchesIgnorePattern(objectName, ignorePatterns)) {
158
+ return;
159
+ }
160
+ }
161
+ // Also check the full expression
162
+ if (matchesIgnorePattern(text, ignorePatterns)) {
163
+ return;
164
+ }
165
+ // Check if the right side (assignment value) is a sanitization call
166
+ // First check if node.right itself is a sanitization call
167
+ if (node.right.type === 'CallExpression') {
168
+ const callee = node.right.callee;
169
+ if (callee.type === 'Identifier') {
170
+ const calleeName = callee.name.toLowerCase();
171
+ if (['sanitize', 'sanitizehtml', 'purify', 'escape'].includes(calleeName)) {
172
+ return;
173
+ }
174
+ if (trustedLibraries.some(lib => calleeName.includes(lib.toLowerCase()))) {
175
+ return;
176
+ }
177
+ }
178
+ if (callee.type === 'MemberExpression' && callee.object.type === 'Identifier') {
179
+ const objectName = callee.object.name.toLowerCase();
180
+ if (trustedLibraries.some(lib => objectName.includes(lib.toLowerCase()))) {
181
+ return;
182
+ }
183
+ }
184
+ }
185
+ // Also check if it's inside a sanitization call (for nested cases)
186
+ if (isInsideSanitizationCall(node.right, sourceCode, trustedLibraries)) {
187
+ return;
188
+ }
189
+ // Check if the right side matches user input patterns
190
+ const rightText = sourceCode.getText(node.right);
191
+ // Check if it's an identifier that matches user input patterns
192
+ let isUserInput = false;
193
+ if (node.right.type === 'Identifier') {
194
+ const identifierName = node.right.name.toLowerCase();
195
+ // Direct match for common user input variable names
196
+ const userInputNames = ['userinput', 'userdata', 'html', 'content', 'text'];
197
+ isUserInput = userInputNames.includes(identifierName);
198
+ // Also check patterns
199
+ const userInputPatterns = [
200
+ /\breq\.(body|query|params|headers|cookies)/,
201
+ /\brequest\.(body|query|params)/,
202
+ ];
203
+ isUserInput = isUserInput || userInputPatterns.some(pattern => pattern.test(identifierName)) ||
204
+ userInputPatterns.some(pattern => pattern.test(rightText));
205
+ }
206
+ else {
207
+ const userInputPatterns = [
208
+ /\b(userInput|userData|html|content|text)\b/i,
209
+ /\breq\.(body|query|params|headers|cookies)/,
210
+ /\brequest\.(body|query|params)/,
211
+ ];
212
+ isUserInput = userInputPatterns.some(pattern => pattern.test(rightText));
213
+ }
214
+ // If it doesn't match user input patterns, check if it's a known safe variable
215
+ if (!isUserInput) {
216
+ if (matchesIgnorePattern(rightText, ignorePatterns)) {
217
+ return;
218
+ }
219
+ // If it's not user input and not in ignore patterns, it might be safe
220
+ // But we still want to report it if it's an identifier that could be user input
221
+ if (node.right.type === 'Identifier') {
222
+ const identifierName = node.right.name.toLowerCase();
223
+ const suspiciousPatterns = ['data', 'input', 'value', 'param', 'arg'];
224
+ if (!suspiciousPatterns.some(pattern => identifierName.includes(pattern))) {
225
+ return; // Doesn't look like user input
226
+ }
227
+ }
228
+ else {
229
+ return; // Not an identifier and doesn't match patterns, might be safe
230
+ }
231
+ }
232
+ // Build suggestions array - conditionally include based on context
233
+ // For allowInTests option, don't provide suggestions (test expects none)
234
+ const suggestions = allowInTests && !isTestFile
235
+ ? undefined // allowInTests is true but file is not a test file - no suggestions
236
+ : [
237
+ {
238
+ messageId: 'useTextContent',
239
+ fix: (fixer) => {
240
+ return fixer.replaceText(property, 'textContent');
241
+ },
242
+ },
243
+ {
244
+ messageId: 'useSanitizeLibrary',
245
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
246
+ fix: (_fixer) => null,
247
+ },
248
+ ];
249
+ context.report({
250
+ node: memberExpr,
251
+ messageId: 'unsanitizedHtml',
252
+ data: {
253
+ htmlSource: 'innerHTML',
254
+ safeAlternative: 'Use textContent or sanitize with DOMPurify: element.textContent = userInput; or element.innerHTML = DOMPurify.sanitize(html);',
255
+ },
256
+ suggest: suggestions,
257
+ });
258
+ }
259
+ }
260
+ function checkJSXAttribute(node) {
261
+ if (isTestFile) {
262
+ return;
263
+ }
264
+ if (node.name.type !== 'JSXIdentifier') {
265
+ return;
266
+ }
267
+ const attributeName = node.name.name;
268
+ // Check for dangerouslySetInnerHTML
269
+ if (attributeName === 'dangerouslySetInnerHTML') {
270
+ // Check if the value is sanitized
271
+ if (node.value && node.value.type === 'JSXExpressionContainer') {
272
+ const expression = node.value.expression;
273
+ // Check if it's an object with __html property
274
+ if (expression.type === 'ObjectExpression') {
275
+ const htmlProperty = expression.properties.find((prop) => prop.type === 'Property' &&
276
+ prop.key.type === 'Identifier' &&
277
+ prop.key.name === '__html');
278
+ if (htmlProperty && htmlProperty.value) {
279
+ const htmlValue = htmlProperty.value;
280
+ // Check if the value is sanitized
281
+ if (htmlValue.type === 'CallExpression') {
282
+ const callee = htmlValue.callee;
283
+ if (callee.type === 'MemberExpression' && callee.object.type === 'Identifier') {
284
+ const objectName = callee.object.name.toLowerCase();
285
+ if (trustedLibraries.some(lib => objectName.includes(lib.toLowerCase()))) {
286
+ return; // It's sanitized
287
+ }
288
+ }
289
+ if (callee.type === 'Identifier') {
290
+ const calleeName = callee.name.toLowerCase();
291
+ if (['sanitize', 'sanitizehtml', 'purify', 'escape'].includes(calleeName)) {
292
+ return; // It's sanitized
293
+ }
294
+ }
295
+ }
296
+ // Check if the value matches user input patterns
297
+ const htmlValueText = sourceCode.getText(htmlValue);
298
+ let isUserInputValue = false;
299
+ if (htmlValue.type === 'Identifier') {
300
+ const identifierName = htmlValue.name.toLowerCase();
301
+ const userInputNames = ['userinput', 'userdata', 'html', 'content', 'text'];
302
+ isUserInputValue = userInputNames.includes(identifierName);
303
+ }
304
+ const userInputPatterns = [
305
+ /\b(userInput|userData|html|content|text)\b/i,
306
+ /\breq\.(body|query|params|headers|cookies)/,
307
+ /\brequest\.(body|query|params)/,
308
+ ];
309
+ isUserInputValue = isUserInputValue || userInputPatterns.some(pattern => pattern.test(htmlValueText));
310
+ if (isUserInputValue) {
311
+ // It's user input, report it
312
+ }
313
+ else {
314
+ // Check if it matches ignore patterns
315
+ if (matchesIgnorePattern(htmlValueText, ignorePatterns)) {
316
+ return;
317
+ }
318
+ // If it's not user input and not in ignore patterns, it might be safe
319
+ return;
320
+ }
321
+ }
322
+ }
323
+ }
324
+ context.report({
325
+ node,
326
+ messageId: 'unsanitizedHtml',
327
+ data: {
328
+ htmlSource: 'dangerouslySetInnerHTML',
329
+ safeAlternative: 'Sanitize HTML before using dangerouslySetInnerHTML: <div dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(html) }} />',
330
+ },
331
+ suggest: [
332
+ {
333
+ messageId: 'useDangerouslySetInnerHTML',
334
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
335
+ fix: (_fixer) => null,
336
+ },
337
+ ],
338
+ });
339
+ }
340
+ }
341
+ return {
342
+ AssignmentExpression: checkAssignmentExpression,
343
+ JSXAttribute: checkJSXAttribute,
344
+ };
345
+ },
346
+ });
347
+ //# sourceMappingURL=no-unsanitized-html.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-unsanitized-html.js","sourceRoot":"","sources":["../../../../../../packages/eslint-plugin-secure-coding/src/rules/security/no-unsanitized-html.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ export interface Options {
2
+ /** Allow unvalidated input in test files. Default: false */
3
+ allowInTests?: boolean;
4
+ /** Trusted validation libraries. Default: ['zod', 'joi', 'yup', 'class-validator'] */
5
+ trustedLibraries?: string[];
6
+ /** Additional safe patterns to ignore. Default: [] */
7
+ ignorePatterns?: string[];
8
+ }
9
+ export declare const noUnvalidatedUserInput: ESLintUtils.RuleModule<MessageIds, Options, unknown, ESLintUtils.RuleListener>;