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.
- package/AGENTS.md +196 -0
- package/CHANGELOG.md +105 -0
- package/LICENSE +23 -0
- package/README.md +377 -0
- package/package.json +80 -0
- package/src/index.d.ts +32 -0
- package/src/index.js +345 -0
- package/src/index.js.map +1 -0
- package/src/rules/security/database-injection.d.ts +13 -0
- package/src/rules/security/database-injection.js +407 -0
- package/src/rules/security/database-injection.js.map +1 -0
- package/src/rules/security/detect-child-process.d.ts +11 -0
- package/src/rules/security/detect-child-process.js +460 -0
- package/src/rules/security/detect-child-process.js.map +1 -0
- package/src/rules/security/detect-eval-with-expression.d.ts +9 -0
- package/src/rules/security/detect-eval-with-expression.js +393 -0
- package/src/rules/security/detect-eval-with-expression.js.map +1 -0
- package/src/rules/security/detect-non-literal-fs-filename.d.ts +7 -0
- package/src/rules/security/detect-non-literal-fs-filename.js +322 -0
- package/src/rules/security/detect-non-literal-fs-filename.js.map +1 -0
- package/src/rules/security/detect-non-literal-regexp.d.ts +9 -0
- package/src/rules/security/detect-non-literal-regexp.js +387 -0
- package/src/rules/security/detect-non-literal-regexp.js.map +1 -0
- package/src/rules/security/detect-object-injection.d.ts +11 -0
- package/src/rules/security/detect-object-injection.js +411 -0
- package/src/rules/security/detect-object-injection.js.map +1 -0
- package/src/rules/security/no-buffer-overread.d.ts +14 -0
- package/src/rules/security/no-buffer-overread.js +519 -0
- package/src/rules/security/no-buffer-overread.js.map +1 -0
- package/src/rules/security/no-clickjacking.d.ts +10 -0
- package/src/rules/security/no-clickjacking.js +381 -0
- package/src/rules/security/no-clickjacking.js.map +1 -0
- package/src/rules/security/no-directive-injection.d.ts +12 -0
- package/src/rules/security/no-directive-injection.js +446 -0
- package/src/rules/security/no-directive-injection.js.map +1 -0
- package/src/rules/security/no-document-cookie.d.ts +5 -0
- package/src/rules/security/no-document-cookie.js +90 -0
- package/src/rules/security/no-document-cookie.js.map +1 -0
- package/src/rules/security/no-electron-security-issues.d.ts +10 -0
- package/src/rules/security/no-electron-security-issues.js +421 -0
- package/src/rules/security/no-electron-security-issues.js.map +1 -0
- package/src/rules/security/no-exposed-sensitive-data.d.ts +11 -0
- package/src/rules/security/no-exposed-sensitive-data.js +341 -0
- package/src/rules/security/no-exposed-sensitive-data.js.map +1 -0
- package/src/rules/security/no-format-string-injection.d.ts +17 -0
- package/src/rules/security/no-format-string-injection.js +653 -0
- package/src/rules/security/no-format-string-injection.js.map +1 -0
- package/src/rules/security/no-graphql-injection.d.ts +12 -0
- package/src/rules/security/no-graphql-injection.js +410 -0
- package/src/rules/security/no-graphql-injection.js.map +1 -0
- package/src/rules/security/no-hardcoded-credentials.d.ts +26 -0
- package/src/rules/security/no-hardcoded-credentials.js +377 -0
- package/src/rules/security/no-hardcoded-credentials.js.map +1 -0
- package/src/rules/security/no-improper-sanitization.d.ts +12 -0
- package/src/rules/security/no-improper-sanitization.js +408 -0
- package/src/rules/security/no-improper-sanitization.js.map +1 -0
- package/src/rules/security/no-improper-type-validation.d.ts +10 -0
- package/src/rules/security/no-improper-type-validation.js +420 -0
- package/src/rules/security/no-improper-type-validation.js.map +1 -0
- package/src/rules/security/no-insecure-comparison.d.ts +7 -0
- package/src/rules/security/no-insecure-comparison.js +125 -0
- package/src/rules/security/no-insecure-comparison.js.map +1 -0
- package/src/rules/security/no-insecure-cookie-settings.d.ts +9 -0
- package/src/rules/security/no-insecure-cookie-settings.js +305 -0
- package/src/rules/security/no-insecure-cookie-settings.js.map +1 -0
- package/src/rules/security/no-insecure-jwt.d.ts +10 -0
- package/src/rules/security/no-insecure-jwt.js +338 -0
- package/src/rules/security/no-insecure-jwt.js.map +1 -0
- package/src/rules/security/no-insecure-redirects.d.ts +7 -0
- package/src/rules/security/no-insecure-redirects.js +215 -0
- package/src/rules/security/no-insecure-redirects.js.map +1 -0
- package/src/rules/security/no-insufficient-postmessage-validation.d.ts +14 -0
- package/src/rules/security/no-insufficient-postmessage-validation.js +390 -0
- package/src/rules/security/no-insufficient-postmessage-validation.js.map +1 -0
- package/src/rules/security/no-insufficient-random.d.ts +9 -0
- package/src/rules/security/no-insufficient-random.js +207 -0
- package/src/rules/security/no-insufficient-random.js.map +1 -0
- package/src/rules/security/no-ldap-injection.d.ts +10 -0
- package/src/rules/security/no-ldap-injection.js +449 -0
- package/src/rules/security/no-ldap-injection.js.map +1 -0
- package/src/rules/security/no-missing-authentication.d.ts +13 -0
- package/src/rules/security/no-missing-authentication.js +322 -0
- package/src/rules/security/no-missing-authentication.js.map +1 -0
- package/src/rules/security/no-missing-cors-check.d.ts +9 -0
- package/src/rules/security/no-missing-cors-check.js +449 -0
- package/src/rules/security/no-missing-cors-check.js.map +1 -0
- package/src/rules/security/no-missing-csrf-protection.d.ts +11 -0
- package/src/rules/security/no-missing-csrf-protection.js +183 -0
- package/src/rules/security/no-missing-csrf-protection.js.map +1 -0
- package/src/rules/security/no-missing-security-headers.d.ts +7 -0
- package/src/rules/security/no-missing-security-headers.js +217 -0
- package/src/rules/security/no-missing-security-headers.js.map +1 -0
- package/src/rules/security/no-privilege-escalation.d.ts +13 -0
- package/src/rules/security/no-privilege-escalation.js +321 -0
- package/src/rules/security/no-privilege-escalation.js.map +1 -0
- package/src/rules/security/no-redos-vulnerable-regex.d.ts +7 -0
- package/src/rules/security/no-redos-vulnerable-regex.js +307 -0
- package/src/rules/security/no-redos-vulnerable-regex.js.map +1 -0
- package/src/rules/security/no-sensitive-data-exposure.d.ts +11 -0
- package/src/rules/security/no-sensitive-data-exposure.js +251 -0
- package/src/rules/security/no-sensitive-data-exposure.js.map +1 -0
- package/src/rules/security/no-sql-injection.d.ts +10 -0
- package/src/rules/security/no-sql-injection.js +332 -0
- package/src/rules/security/no-sql-injection.js.map +1 -0
- package/src/rules/security/no-timing-attack.d.ts +10 -0
- package/src/rules/security/no-timing-attack.js +358 -0
- package/src/rules/security/no-timing-attack.js.map +1 -0
- package/src/rules/security/no-toctou-vulnerability.d.ts +7 -0
- package/src/rules/security/no-toctou-vulnerability.js +165 -0
- package/src/rules/security/no-toctou-vulnerability.js.map +1 -0
- package/src/rules/security/no-unchecked-loop-condition.d.ts +12 -0
- package/src/rules/security/no-unchecked-loop-condition.js +635 -0
- package/src/rules/security/no-unchecked-loop-condition.js.map +1 -0
- package/src/rules/security/no-unencrypted-transmission.d.ts +11 -0
- package/src/rules/security/no-unencrypted-transmission.js +237 -0
- package/src/rules/security/no-unencrypted-transmission.js.map +1 -0
- package/src/rules/security/no-unescaped-url-parameter.d.ts +9 -0
- package/src/rules/security/no-unescaped-url-parameter.js +266 -0
- package/src/rules/security/no-unescaped-url-parameter.js.map +1 -0
- package/src/rules/security/no-unlimited-resource-allocation.d.ts +12 -0
- package/src/rules/security/no-unlimited-resource-allocation.js +659 -0
- package/src/rules/security/no-unlimited-resource-allocation.js.map +1 -0
- package/src/rules/security/no-unsafe-deserialization.d.ts +10 -0
- package/src/rules/security/no-unsafe-deserialization.js +501 -0
- package/src/rules/security/no-unsafe-deserialization.js.map +1 -0
- package/src/rules/security/no-unsafe-dynamic-require.d.ts +5 -0
- package/src/rules/security/no-unsafe-dynamic-require.js +107 -0
- package/src/rules/security/no-unsafe-dynamic-require.js.map +1 -0
- package/src/rules/security/no-unsafe-regex-construction.d.ts +9 -0
- package/src/rules/security/no-unsafe-regex-construction.js +292 -0
- package/src/rules/security/no-unsafe-regex-construction.js.map +1 -0
- package/src/rules/security/no-unsanitized-html.d.ts +9 -0
- package/src/rules/security/no-unsanitized-html.js +347 -0
- package/src/rules/security/no-unsanitized-html.js.map +1 -0
- package/src/rules/security/no-unvalidated-user-input.d.ts +9 -0
- package/src/rules/security/no-unvalidated-user-input.js +418 -0
- package/src/rules/security/no-unvalidated-user-input.js.map +1 -0
- package/src/rules/security/no-weak-crypto.d.ts +11 -0
- package/src/rules/security/no-weak-crypto.js +350 -0
- package/src/rules/security/no-weak-crypto.js.map +1 -0
- package/src/rules/security/no-weak-password-recovery.d.ts +12 -0
- package/src/rules/security/no-weak-password-recovery.js +401 -0
- package/src/rules/security/no-weak-password-recovery.js.map +1 -0
- package/src/rules/security/no-xpath-injection.d.ts +10 -0
- package/src/rules/security/no-xpath-injection.js +487 -0
- package/src/rules/security/no-xpath-injection.js.map +1 -0
- package/src/rules/security/no-xxe-injection.d.ts +7 -0
- package/src/rules/security/no-xxe-injection.js +270 -0
- package/src/rules/security/no-xxe-injection.js.map +1 -0
- package/src/rules/security/no-zip-slip.d.ts +9 -0
- package/src/rules/security/no-zip-slip.js +446 -0
- package/src/rules/security/no-zip-slip.js.map +1 -0
- package/src/types/index.d.ts +131 -0
- package/src/types/index.js +18 -0
- package/src/types/index.js.map +1 -0
|
@@ -0,0 +1,407 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.databaseInjection = void 0;
|
|
4
|
+
const eslint_devkit_1 = require("@interlace/eslint-devkit");
|
|
5
|
+
const eslint_devkit_2 = require("@interlace/eslint-devkit");
|
|
6
|
+
exports.databaseInjection = (0, eslint_devkit_2.createRule)({
|
|
7
|
+
name: 'database-injection',
|
|
8
|
+
meta: {
|
|
9
|
+
type: 'problem',
|
|
10
|
+
docs: {
|
|
11
|
+
description: 'Detects SQL and NoSQL injection vulnerabilities with framework-specific fixes',
|
|
12
|
+
},
|
|
13
|
+
messages: (() => {
|
|
14
|
+
const databaseInjection = (0, eslint_devkit_1.formatLLMMessage)({
|
|
15
|
+
icon: eslint_devkit_1.MessageIcons.SECURITY,
|
|
16
|
+
issueName: 'SQL Injection',
|
|
17
|
+
cwe: 'CWE-89',
|
|
18
|
+
description: 'SQL Injection detected',
|
|
19
|
+
severity: 'CRITICAL',
|
|
20
|
+
fix: 'Use parameterized query: db.query("SELECT * FROM users WHERE id = ?", [userId])',
|
|
21
|
+
documentationLink: 'https://owasp.org/www-community/attacks/SQL_Injection',
|
|
22
|
+
});
|
|
23
|
+
const usePrisma = (0, eslint_devkit_1.formatLLMMessage)({
|
|
24
|
+
icon: eslint_devkit_1.MessageIcons.INFO,
|
|
25
|
+
issueName: 'Use Prisma',
|
|
26
|
+
description: 'Use Prisma ORM',
|
|
27
|
+
severity: 'LOW',
|
|
28
|
+
fix: 'await prisma.user.findMany({ where: { id } })',
|
|
29
|
+
documentationLink: 'https://www.prisma.io/docs',
|
|
30
|
+
});
|
|
31
|
+
const useTypeORM = (0, eslint_devkit_1.formatLLMMessage)({
|
|
32
|
+
icon: eslint_devkit_1.MessageIcons.INFO,
|
|
33
|
+
issueName: 'Use TypeORM',
|
|
34
|
+
description: 'Use TypeORM with QueryBuilder',
|
|
35
|
+
severity: 'LOW',
|
|
36
|
+
fix: 'userRepository.createQueryBuilder().where("id = :id", { id })',
|
|
37
|
+
documentationLink: 'https://typeorm.io/',
|
|
38
|
+
});
|
|
39
|
+
const useParameterized = (0, eslint_devkit_1.formatLLMMessage)({
|
|
40
|
+
icon: eslint_devkit_1.MessageIcons.INFO,
|
|
41
|
+
issueName: 'Use Parameterized',
|
|
42
|
+
description: 'Use parameterized query',
|
|
43
|
+
severity: 'LOW',
|
|
44
|
+
fix: 'db.query("SELECT * FROM users WHERE id = ?", [userId])',
|
|
45
|
+
documentationLink: 'https://owasp.org/www-community/attacks/SQL_Injection',
|
|
46
|
+
});
|
|
47
|
+
const useMongoSanitize = (0, eslint_devkit_1.formatLLMMessage)({
|
|
48
|
+
icon: eslint_devkit_1.MessageIcons.INFO,
|
|
49
|
+
issueName: 'Use mongo-sanitize',
|
|
50
|
+
description: 'Use mongo-sanitize for MongoDB',
|
|
51
|
+
severity: 'LOW',
|
|
52
|
+
fix: 'sanitize(req.body)',
|
|
53
|
+
documentationLink: 'https://github.com/vkarpov15/mongo-sanitize',
|
|
54
|
+
});
|
|
55
|
+
const strategyParameterize = (0, eslint_devkit_1.formatLLMMessage)({
|
|
56
|
+
icon: eslint_devkit_1.MessageIcons.STRATEGY,
|
|
57
|
+
issueName: 'Parameterize Strategy',
|
|
58
|
+
description: 'Use parameterized queries',
|
|
59
|
+
severity: 'LOW',
|
|
60
|
+
fix: 'Use ? or :name placeholders for user input',
|
|
61
|
+
documentationLink: 'https://owasp.org/www-community/attacks/SQL_Injection',
|
|
62
|
+
});
|
|
63
|
+
const strategyORM = (0, eslint_devkit_1.formatLLMMessage)({
|
|
64
|
+
icon: eslint_devkit_1.MessageIcons.STRATEGY,
|
|
65
|
+
issueName: 'ORM Strategy',
|
|
66
|
+
description: 'Migrate to ORM for automatic protection',
|
|
67
|
+
severity: 'LOW',
|
|
68
|
+
fix: 'Use Prisma, TypeORM, or Sequelize',
|
|
69
|
+
documentationLink: 'https://www.prisma.io/docs/concepts/overview/why-prisma',
|
|
70
|
+
});
|
|
71
|
+
const strategySanitize = (0, eslint_devkit_1.formatLLMMessage)({
|
|
72
|
+
icon: eslint_devkit_1.MessageIcons.STRATEGY,
|
|
73
|
+
issueName: 'Sanitize Strategy',
|
|
74
|
+
description: 'Add input sanitization',
|
|
75
|
+
severity: 'LOW',
|
|
76
|
+
fix: 'Sanitize input as last resort',
|
|
77
|
+
documentationLink: 'https://owasp.org/www-community/attacks/SQL_Injection',
|
|
78
|
+
});
|
|
79
|
+
const strategyAuto = (0, eslint_devkit_1.formatLLMMessage)({
|
|
80
|
+
icon: eslint_devkit_1.MessageIcons.STRATEGY,
|
|
81
|
+
issueName: 'Auto Strategy',
|
|
82
|
+
description: 'Apply context-aware injection prevention',
|
|
83
|
+
severity: 'LOW',
|
|
84
|
+
fix: 'Use context-appropriate protection',
|
|
85
|
+
documentationLink: 'https://owasp.org/www-community/attacks/SQL_Injection',
|
|
86
|
+
});
|
|
87
|
+
return {
|
|
88
|
+
databaseInjection,
|
|
89
|
+
usePrisma,
|
|
90
|
+
useTypeORM,
|
|
91
|
+
useParameterized,
|
|
92
|
+
useMongoSanitize,
|
|
93
|
+
strategyParameterize,
|
|
94
|
+
strategyORM,
|
|
95
|
+
strategySanitize,
|
|
96
|
+
strategyAuto,
|
|
97
|
+
};
|
|
98
|
+
})(),
|
|
99
|
+
schema: [
|
|
100
|
+
{
|
|
101
|
+
type: 'object',
|
|
102
|
+
properties: {
|
|
103
|
+
detectNoSQL: {
|
|
104
|
+
type: 'boolean',
|
|
105
|
+
default: true,
|
|
106
|
+
},
|
|
107
|
+
detectORMs: {
|
|
108
|
+
type: 'boolean',
|
|
109
|
+
default: true,
|
|
110
|
+
description: 'Detect unsafe ORM usage',
|
|
111
|
+
},
|
|
112
|
+
trustedSources: {
|
|
113
|
+
type: 'array',
|
|
114
|
+
items: { type: 'string' },
|
|
115
|
+
default: [],
|
|
116
|
+
},
|
|
117
|
+
frameworkHints: {
|
|
118
|
+
type: 'boolean',
|
|
119
|
+
default: true,
|
|
120
|
+
description: 'Provide framework-specific suggestions',
|
|
121
|
+
},
|
|
122
|
+
strategy: {
|
|
123
|
+
type: 'string',
|
|
124
|
+
enum: ['parameterize', 'orm', 'sanitize', 'auto'],
|
|
125
|
+
default: 'auto',
|
|
126
|
+
description: 'Strategy for fixing injection (auto = smart detection)'
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
additionalProperties: false,
|
|
130
|
+
},
|
|
131
|
+
],
|
|
132
|
+
},
|
|
133
|
+
defaultOptions: [
|
|
134
|
+
{
|
|
135
|
+
detectNoSQL: true,
|
|
136
|
+
detectORMs: true,
|
|
137
|
+
trustedSources: [],
|
|
138
|
+
frameworkHints: true,
|
|
139
|
+
strategy: 'auto',
|
|
140
|
+
},
|
|
141
|
+
],
|
|
142
|
+
create(context) {
|
|
143
|
+
const options = context.options[0] || {};
|
|
144
|
+
const { detectNoSQL = true, strategy = 'auto' } = options || {};
|
|
145
|
+
const sourceCode = context.sourceCode || context.sourceCode;
|
|
146
|
+
/**
|
|
147
|
+
* Select message ID based on strategy
|
|
148
|
+
* @todo Consider using this for suggestions in future versions
|
|
149
|
+
*/
|
|
150
|
+
const selectStrategyMessage = () => {
|
|
151
|
+
switch (strategy) {
|
|
152
|
+
case 'parameterize':
|
|
153
|
+
return 'strategyParameterize';
|
|
154
|
+
case 'orm':
|
|
155
|
+
return 'strategyORM';
|
|
156
|
+
case 'sanitize':
|
|
157
|
+
return 'strategySanitize';
|
|
158
|
+
case 'auto':
|
|
159
|
+
default:
|
|
160
|
+
// Auto mode: prefer parameterized queries
|
|
161
|
+
return 'useParameterized';
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
const filename = context.filename || context.getFilename();
|
|
165
|
+
/**
|
|
166
|
+
* SQL keywords for detection
|
|
167
|
+
*/
|
|
168
|
+
const SQL_KEYWORDS = [
|
|
169
|
+
'SELECT', 'INSERT', 'UPDATE', 'DELETE', 'DROP', 'CREATE', 'ALTER',
|
|
170
|
+
'EXEC', 'EXECUTE', 'TRUNCATE', 'GRANT', 'REVOKE', 'WHERE', 'FROM', 'JOIN'
|
|
171
|
+
];
|
|
172
|
+
/**
|
|
173
|
+
* NoSQL patterns
|
|
174
|
+
*/
|
|
175
|
+
const NOSQL_PATTERNS = [
|
|
176
|
+
'find', 'findOne', 'findById', 'updateOne', 'updateMany', 'deleteOne',
|
|
177
|
+
'deleteMany', 'aggregate', '$where', '$regex'
|
|
178
|
+
];
|
|
179
|
+
/**
|
|
180
|
+
* NoSQL query patterns in template literals (e.g., `this.name === "${userName}"`)
|
|
181
|
+
*/
|
|
182
|
+
const NOSQL_QUERY_PATTERNS = [
|
|
183
|
+
/this\.\w+\s*===?\s*["']/i, // this.name === "value"
|
|
184
|
+
/this\.\w+\s*!==?\s*["']/i, // this.name !== "value"
|
|
185
|
+
/\$\w+\s*===?\s*["']/i, // $where === "value"
|
|
186
|
+
];
|
|
187
|
+
/**
|
|
188
|
+
* Check if text contains SQL keywords
|
|
189
|
+
*/
|
|
190
|
+
function containsSQLKeywords(text) {
|
|
191
|
+
const upperText = text.toUpperCase();
|
|
192
|
+
return SQL_KEYWORDS.some(keyword => upperText.includes(keyword));
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Check if code is using NoSQL operations
|
|
196
|
+
*/
|
|
197
|
+
function isNoSQLOperation(node) {
|
|
198
|
+
const text = sourceCode.getText(node);
|
|
199
|
+
return NOSQL_PATTERNS.some(pattern => text.includes(pattern));
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Check if expression is tainted (contains user input)
|
|
203
|
+
*/
|
|
204
|
+
function isTainted(node) {
|
|
205
|
+
const text = sourceCode.getText(node);
|
|
206
|
+
const { trustedSources = [] } = options;
|
|
207
|
+
// High confidence taint sources
|
|
208
|
+
const highConfidenceSources = [
|
|
209
|
+
'req.body', 'req.query', 'req.params', 'request.body',
|
|
210
|
+
'params.', 'query.', 'body.', 'input.', 'userInput'
|
|
211
|
+
];
|
|
212
|
+
// Medium confidence taint sources
|
|
213
|
+
const mediumConfidenceSources = [
|
|
214
|
+
'props.', 'state.', 'context.', 'event.', 'data.'
|
|
215
|
+
];
|
|
216
|
+
for (const source of highConfidenceSources) {
|
|
217
|
+
if (text.includes(source)) {
|
|
218
|
+
return { tainted: true, source, confidence: 'high' };
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
for (const source of mediumConfidenceSources) {
|
|
222
|
+
if (text.includes(source)) {
|
|
223
|
+
return { tainted: true, source, confidence: 'medium' };
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
// Check if this source is explicitly trusted (only for low-confidence sources)
|
|
227
|
+
for (const trusted of trustedSources) {
|
|
228
|
+
if (text.includes(trusted)) {
|
|
229
|
+
return { tainted: false, confidence: 'low' };
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
// Check if it's a variable (low confidence)
|
|
233
|
+
if (node.type === 'Identifier' && !text.match(/^[A-Z_]+$/)) {
|
|
234
|
+
return { tainted: true, source: 'variable', confidence: 'low' };
|
|
235
|
+
}
|
|
236
|
+
return { tainted: false, confidence: 'low' };
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Analyze vulnerability and provide detailed report
|
|
240
|
+
*/
|
|
241
|
+
function analyzeVulnerability(node, vulnType) {
|
|
242
|
+
const taintInfo = isTainted(node);
|
|
243
|
+
return {
|
|
244
|
+
type: vulnType,
|
|
245
|
+
pattern: taintInfo.tainted
|
|
246
|
+
? `User input (${taintInfo.source}) in query`
|
|
247
|
+
: 'Dynamic query construction',
|
|
248
|
+
severity: taintInfo.confidence === 'high' ? 'critical' : taintInfo.confidence === 'medium' ? 'high' : 'medium',
|
|
249
|
+
exploitability: taintInfo.confidence === 'high'
|
|
250
|
+
? 'Easily exploitable via API parameters'
|
|
251
|
+
: 'Exploitable with access to input sources',
|
|
252
|
+
cwe: vulnType === 'SQL' ? 'CWE-89' : 'CWE-943',
|
|
253
|
+
owasp: 'A03:2021 - Injection',
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Report additional strategy-specific suggestions
|
|
258
|
+
*/
|
|
259
|
+
function reportStrategySuggestions(node) {
|
|
260
|
+
const strategyMessageId = selectStrategyMessage();
|
|
261
|
+
if (strategyMessageId !== 'useParameterized') { // Don't duplicate the main message
|
|
262
|
+
context.report({
|
|
263
|
+
node,
|
|
264
|
+
messageId: strategyMessageId,
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Check template literal for SQL or NoSQL injection
|
|
270
|
+
*/
|
|
271
|
+
function checkTemplateLiteral(node) {
|
|
272
|
+
const text = sourceCode.getText(node);
|
|
273
|
+
// Check for SQL injection
|
|
274
|
+
if (containsSQLKeywords(text) && node.expressions.length > 0) {
|
|
275
|
+
// Check if any expression is tainted
|
|
276
|
+
const taintedExprs = node.expressions.filter((expr) => isTainted(expr).tainted);
|
|
277
|
+
if (taintedExprs.length > 0) {
|
|
278
|
+
const vulnDetails = analyzeVulnerability(node, 'SQL');
|
|
279
|
+
const data = {
|
|
280
|
+
type: vulnDetails.type,
|
|
281
|
+
severity: vulnDetails.severity.toUpperCase(),
|
|
282
|
+
filePath: filename,
|
|
283
|
+
line: String(node.loc?.start.line ?? 0),
|
|
284
|
+
cwe: vulnDetails.cwe,
|
|
285
|
+
cweCode: vulnDetails.cwe.replace('CWE-', ''),
|
|
286
|
+
currentExample: `db.query(\`SELECT * FROM users WHERE id = ${'${userId}'}\`)`,
|
|
287
|
+
fixExample: `Use parameterized: db.query("SELECT * FROM users WHERE id = ?", [userId])`,
|
|
288
|
+
docLink: 'https://owasp.org/www-community/attacks/SQL_Injection',
|
|
289
|
+
};
|
|
290
|
+
context.report({
|
|
291
|
+
node,
|
|
292
|
+
messageId: 'databaseInjection',
|
|
293
|
+
data,
|
|
294
|
+
});
|
|
295
|
+
reportStrategySuggestions(node);
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
// Check for NoSQL injection patterns in template literals
|
|
300
|
+
if (detectNoSQL && node.expressions.length > 0) {
|
|
301
|
+
const hasNoSQLPattern = NOSQL_QUERY_PATTERNS.some(pattern => pattern.test(text));
|
|
302
|
+
if (hasNoSQLPattern) {
|
|
303
|
+
// Check if any expression is tainted
|
|
304
|
+
const taintedExprs = node.expressions.filter((expr) => isTainted(expr).tainted);
|
|
305
|
+
if (taintedExprs.length > 0) {
|
|
306
|
+
const vulnDetails = analyzeVulnerability(node, 'NoSQL');
|
|
307
|
+
const data = {
|
|
308
|
+
type: vulnDetails.type,
|
|
309
|
+
severity: vulnDetails.severity.toUpperCase(),
|
|
310
|
+
filePath: filename,
|
|
311
|
+
line: String(node.loc?.start.line ?? 0),
|
|
312
|
+
cwe: vulnDetails.cwe,
|
|
313
|
+
cweCode: vulnDetails.cwe.replace('CWE-', ''),
|
|
314
|
+
currentExample: `const query = \`this.name === "${'${userName}'}"\``,
|
|
315
|
+
fixExample: `Sanitize input: const query = \`this.name === "\${mongoSanitize(userName)}"\``,
|
|
316
|
+
docLink: 'https://owasp.org/www-community/attacks/NoSQL_Injection',
|
|
317
|
+
};
|
|
318
|
+
context.report({
|
|
319
|
+
node,
|
|
320
|
+
messageId: 'databaseInjection',
|
|
321
|
+
data,
|
|
322
|
+
});
|
|
323
|
+
reportStrategySuggestions(node);
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* Check NoSQL operations
|
|
331
|
+
*/
|
|
332
|
+
function checkNoSQLOperation(node) {
|
|
333
|
+
if (!detectNoSQL)
|
|
334
|
+
return;
|
|
335
|
+
if (!isNoSQLOperation(node))
|
|
336
|
+
return;
|
|
337
|
+
// Check if arguments contain user input
|
|
338
|
+
const taintedArgs = node.arguments.filter((arg) => isTainted(arg).tainted);
|
|
339
|
+
if (taintedArgs.length === 0)
|
|
340
|
+
return;
|
|
341
|
+
const vulnDetails = analyzeVulnerability(node, 'NoSQL');
|
|
342
|
+
const data = {
|
|
343
|
+
type: vulnDetails.type,
|
|
344
|
+
severity: vulnDetails.severity.toUpperCase(),
|
|
345
|
+
filePath: filename,
|
|
346
|
+
line: String(node.loc?.start.line ?? 0),
|
|
347
|
+
cwe: vulnDetails.cwe,
|
|
348
|
+
cweCode: vulnDetails.cwe.replace('CWE-', ''),
|
|
349
|
+
currentExample: `User.findOne({ email: req.body.email })`,
|
|
350
|
+
fixExample: `Sanitize input: User.findOne({ email: mongoSanitize(req.body.email) })`,
|
|
351
|
+
docLink: 'https://owasp.org/www-community/attacks/NoSQL_Injection',
|
|
352
|
+
};
|
|
353
|
+
context.report({
|
|
354
|
+
node,
|
|
355
|
+
messageId: 'databaseInjection',
|
|
356
|
+
data,
|
|
357
|
+
});
|
|
358
|
+
reportStrategySuggestions(node);
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* Check binary expression (string concatenation) for SQL injection
|
|
362
|
+
*/
|
|
363
|
+
function checkBinaryExpression(node) {
|
|
364
|
+
// Only check string concatenation with + operator
|
|
365
|
+
if (node.operator !== '+')
|
|
366
|
+
return;
|
|
367
|
+
// Get the full text of the binary expression
|
|
368
|
+
const text = sourceCode.getText(node);
|
|
369
|
+
// Check if it contains SQL keywords
|
|
370
|
+
if (!containsSQLKeywords(text))
|
|
371
|
+
return;
|
|
372
|
+
// Check if any part of the expression is tainted
|
|
373
|
+
const taintInfo = isTainted(node);
|
|
374
|
+
if (!taintInfo.tainted) {
|
|
375
|
+
// Also check left and right sides individually
|
|
376
|
+
const leftTainted = isTainted(node.left).tainted;
|
|
377
|
+
const rightTainted = isTainted(node.right).tainted;
|
|
378
|
+
if (!leftTainted && !rightTainted)
|
|
379
|
+
return;
|
|
380
|
+
}
|
|
381
|
+
const vulnDetails = analyzeVulnerability(node, 'SQL');
|
|
382
|
+
const data = {
|
|
383
|
+
type: vulnDetails.type,
|
|
384
|
+
severity: vulnDetails.severity.toUpperCase(),
|
|
385
|
+
filePath: filename,
|
|
386
|
+
line: String(node.loc?.start.line ?? 0),
|
|
387
|
+
cwe: vulnDetails.cwe,
|
|
388
|
+
cweCode: vulnDetails.cwe.replace('CWE-', ''),
|
|
389
|
+
currentExample: `const query = "SELECT * FROM users WHERE name = '" + userName + "'"`,
|
|
390
|
+
fixExample: `Use parameterized: db.query("SELECT * FROM users WHERE name = ?", [userName])`,
|
|
391
|
+
docLink: 'https://owasp.org/www-community/attacks/SQL_Injection',
|
|
392
|
+
};
|
|
393
|
+
context.report({
|
|
394
|
+
node,
|
|
395
|
+
messageId: 'databaseInjection',
|
|
396
|
+
data,
|
|
397
|
+
});
|
|
398
|
+
reportStrategySuggestions(node);
|
|
399
|
+
}
|
|
400
|
+
return {
|
|
401
|
+
TemplateLiteral: checkTemplateLiteral,
|
|
402
|
+
CallExpression: checkNoSQLOperation,
|
|
403
|
+
BinaryExpression: checkBinaryExpression,
|
|
404
|
+
};
|
|
405
|
+
},
|
|
406
|
+
});
|
|
407
|
+
//# sourceMappingURL=database-injection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database-injection.js","sourceRoot":"","sources":["../../../../../../packages/eslint-plugin-secure-coding/src/rules/security/database-injection.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface Options {
|
|
2
|
+
/** Allow exec() with literal strings. Default: false (stricter) */
|
|
3
|
+
allowLiteralStrings?: boolean;
|
|
4
|
+
/** Allow spawn() with literal arguments. Default: false (stricter) */
|
|
5
|
+
allowLiteralSpawn?: boolean;
|
|
6
|
+
/** Additional child_process methods to check */
|
|
7
|
+
additionalMethods?: string[];
|
|
8
|
+
/** Strategy for fixing command injection: 'validate', 'sanitize', 'restrict', or 'auto' */
|
|
9
|
+
strategy?: 'validate' | 'sanitize' | 'restrict' | 'auto';
|
|
10
|
+
}
|
|
11
|
+
export declare const detectChildProcess: ESLintUtils.RuleModule<MessageIds, Options, unknown, ESLintUtils.RuleListener>;
|