xypriss 3.2.0 → 3.2.2

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 (34) hide show
  1. package/dist/cjs/src/middleware/built-in/BuiltInMiddleware.js +51 -8
  2. package/dist/cjs/src/middleware/built-in/BuiltInMiddleware.js.map +1 -1
  3. package/dist/cjs/src/middleware/built-in/security/RequestSignatureProtector.js +20 -4
  4. package/dist/cjs/src/middleware/built-in/security/RequestSignatureProtector.js.map +1 -1
  5. package/dist/cjs/src/server/const/default.js +38 -5
  6. package/dist/cjs/src/server/const/default.js.map +1 -1
  7. package/dist/esm/src/middleware/built-in/BuiltInMiddleware.js +51 -8
  8. package/dist/esm/src/middleware/built-in/BuiltInMiddleware.js.map +1 -1
  9. package/dist/esm/src/middleware/built-in/security/RequestSignatureProtector.js +20 -4
  10. package/dist/esm/src/middleware/built-in/security/RequestSignatureProtector.js.map +1 -1
  11. package/dist/esm/src/server/const/default.js +38 -5
  12. package/dist/esm/src/server/const/default.js.map +1 -1
  13. package/dist/index.d.ts +16 -0
  14. package/package.json +1 -1
  15. package/dist/cjs/mods/security/src/core/crypt.js +0 -56
  16. package/dist/cjs/mods/security/src/core/crypt.js.map +0 -1
  17. package/dist/cjs/src/middleware/built-in/index.js +0 -325
  18. package/dist/cjs/src/middleware/built-in/index.js.map +0 -1
  19. package/dist/cjs/src/middleware/built-in/sqlInjection.js +0 -335
  20. package/dist/cjs/src/middleware/built-in/sqlInjection.js.map +0 -1
  21. package/dist/cjs/src/server/conf/rateLimitConfig.js +0 -35
  22. package/dist/cjs/src/server/conf/rateLimitConfig.js.map +0 -1
  23. package/dist/cjs/src/server/utils/wildcardMatcher.js +0 -92
  24. package/dist/cjs/src/server/utils/wildcardMatcher.js.map +0 -1
  25. package/dist/esm/mods/security/src/core/crypt.js +0 -54
  26. package/dist/esm/mods/security/src/core/crypt.js.map +0 -1
  27. package/dist/esm/src/middleware/built-in/index.js +0 -323
  28. package/dist/esm/src/middleware/built-in/index.js.map +0 -1
  29. package/dist/esm/src/middleware/built-in/sqlInjection.js +0 -333
  30. package/dist/esm/src/middleware/built-in/sqlInjection.js.map +0 -1
  31. package/dist/esm/src/server/conf/rateLimitConfig.js +0 -33
  32. package/dist/esm/src/server/conf/rateLimitConfig.js.map +0 -1
  33. package/dist/esm/src/server/utils/wildcardMatcher.js +0 -88
  34. package/dist/esm/src/server/utils/wildcardMatcher.js.map +0 -1
@@ -1,323 +0,0 @@
1
- import helmet from 'helmet';
2
- import cors from 'cors';
3
- import rateLimit from 'express-rate-limit';
4
- import compression from 'compression';
5
- import hpp from 'hpp';
6
- import mongoSanitize from 'express-mongo-sanitize';
7
- import xss from 'xss';
8
- import morgan from 'morgan';
9
- import slowDown from 'express-slow-down';
10
- import ExpressBrute from 'express-brute';
11
- import multer from 'multer';
12
- import { doubleCsrf } from 'csrf-csrf';
13
-
14
- /**
15
- * XyPriss Built-in Middleware
16
- * Wrappers around popular middleware libraries
17
- */
18
- class BuiltInMiddleware {
19
- /**
20
- * Get Helmet middleware for security headers
21
- */
22
- static helmet(options = {}) {
23
- const defaultOptions = {
24
- contentSecurityPolicy: {
25
- directives: {
26
- defaultSrc: ["'self'"],
27
- scriptSrc: ["'self'"],
28
- styleSrc: ["'self'", "'unsafe-inline'"],
29
- imgSrc: ["'self'", "data:"],
30
- fontSrc: ["'self'"],
31
- },
32
- },
33
- crossOriginEmbedderPolicy: true,
34
- crossOriginOpenerPolicy: true,
35
- crossOriginResourcePolicy: { policy: "same-origin" },
36
- dnsPrefetchControl: { allow: false },
37
- frameguard: { action: "deny" },
38
- hidePoweredBy: true,
39
- hsts: {
40
- maxAge: 31536000,
41
- includeSubDomains: true,
42
- preload: false,
43
- },
44
- ieNoOpen: true,
45
- noSniff: true,
46
- originAgentCluster: true,
47
- permittedCrossDomainPolicies: false,
48
- referrerPolicy: { policy: "strict-origin-when-cross-origin" },
49
- xssFilter: true,
50
- };
51
- const config = { ...defaultOptions, ...options };
52
- return helmet(config);
53
- }
54
- /**
55
- * Get CORS middleware
56
- */
57
- static cors(options = {}) {
58
- const defaultOptions = {
59
- origin: true,
60
- methods: ["GET", "HEAD", "PUT", "PATCH", "POST", "DELETE"],
61
- allowedHeaders: [
62
- "Content-Type",
63
- "Authorization",
64
- "X-Requested-With",
65
- ],
66
- credentials: false,
67
- maxAge: 86400, // 24 hours
68
- };
69
- const config = { ...defaultOptions, ...options };
70
- return cors(config);
71
- }
72
- /**
73
- * Get Rate Limiting middleware
74
- */
75
- static rateLimit(options = {}) {
76
- const defaultOptions = {
77
- windowMs: 15 * 60 * 1000, // 15 minutes
78
- max: 100, // limit each IP to 100 requests per windowMs
79
- message: {
80
- error: "Too many requests from this IP, please try again later.",
81
- retryAfter: "Please try again later.",
82
- },
83
- standardHeaders: true,
84
- legacyHeaders: false,
85
- handler: (_req, res) => {
86
- res.status(429).json({
87
- error: "Too many requests",
88
- message: "Rate limit exceeded. Please try again later.",
89
- retryAfter: Math.ceil(options.windowMs / 1000) || 900,
90
- });
91
- },
92
- };
93
- const config = { ...defaultOptions, ...options };
94
- return rateLimit(config);
95
- }
96
- /**
97
- * Get Compression middleware
98
- */
99
- static compression(options = {}) {
100
- const defaultOptions = {
101
- level: 6,
102
- threshold: 1024, // Only compress responses >= 1KB
103
- filter: (req, res) => {
104
- // Don't compress responses with this request header
105
- if (req.headers["x-no-compression"]) {
106
- return false;
107
- }
108
- // Fallback to standard filter function
109
- return compression.filter(req, res);
110
- },
111
- };
112
- const config = { ...defaultOptions, ...options };
113
- return compression(config);
114
- }
115
- /**
116
- * CSRF protection middleware using csrf-csrf library
117
- */
118
- static csrf(options = {}) {
119
- const defaultOptions = {
120
- getSecret: () => "your-secret-key", // In production, use a proper secret
121
- cookieName: "__Host-psifi.x-csrf-token",
122
- cookieOptions: {
123
- httpOnly: true,
124
- sameSite: "strict",
125
- secure: process.env.NODE_ENV === "production",
126
- maxAge: 3600000, // 1 hour
127
- },
128
- size: 64,
129
- ignoredMethods: ["GET", "HEAD", "OPTIONS"],
130
- getTokenFromRequest: (req) => {
131
- return (req.headers["x-csrf-token"] ||
132
- req.body?._csrf ||
133
- req.query?._csrf);
134
- },
135
- };
136
- const config = { ...defaultOptions, ...options };
137
- const { doubleCsrfProtection } = doubleCsrf(config);
138
- // Return the protection middleware
139
- return doubleCsrfProtection;
140
- }
141
- /**
142
- * Get Express Validator middleware for input validation
143
- * Simplified implementation - users should install express-validator separately
144
- */
145
- static validator(options = {}) {
146
- const defaultOptions = {
147
- sanitizeBody: true,
148
- checkBody: true,
149
- checkQuery: true,
150
- checkParams: true,
151
- };
152
- ({ ...defaultOptions, ...options });
153
- return (req, res, next) => {
154
- // Basic validation middleware - simplified
155
- // In production, use express-validator library directly
156
- console.log("[Validator] Basic validation middleware active");
157
- // Add basic validation helpers to request
158
- req.validation = {
159
- body: (field) => req.body?.[field],
160
- query: (field) => req.query?.[field],
161
- params: (field) => req.params?.[field],
162
- };
163
- next();
164
- };
165
- }
166
- /**
167
- * Get HPP (HTTP Parameter Pollution) protection middleware
168
- */
169
- static hpp(options = {}) {
170
- const defaultOptions = {
171
- whitelist: ["tags", "categories"], // Allow arrays for these parameters
172
- };
173
- const config = { ...defaultOptions, ...options };
174
- return hpp(config);
175
- }
176
- /**
177
- * Get MongoDB injection protection middleware
178
- */
179
- static mongoSanitize(options = {}) {
180
- const defaultOptions = {
181
- replaceWith: "_",
182
- onSanitize: (key, value) => {
183
- console.warn(`[MongoSanitize] Sanitized key: ${key}, value: ${value}`);
184
- },
185
- };
186
- const config = { ...defaultOptions, ...options };
187
- return mongoSanitize(config);
188
- }
189
- /**
190
- * Get XSS protection middleware
191
- */
192
- static xss(options = {}) {
193
- const defaultOptions = {
194
- whiteList: {
195
- a: ["href", "title"],
196
- b: [],
197
- i: [],
198
- strong: [],
199
- em: [],
200
- },
201
- };
202
- const config = { ...defaultOptions, ...options };
203
- return (req, _res, next) => {
204
- // Sanitize request body
205
- if (req.body) {
206
- req.body = this.sanitizeObject(req.body, config);
207
- }
208
- // Sanitize query parameters
209
- if (req.query) {
210
- req.query = this.sanitizeObject(req.query, config);
211
- }
212
- next();
213
- };
214
- }
215
- /**
216
- * Get Morgan logging middleware
217
- */
218
- static morgan(options = {}) {
219
- const defaultFormat = options.format || "combined";
220
- const defaultOptions = {
221
- skip: (_req, res) => res.statusCode < 400, // Only log errors by default
222
- stream: process.stdout,
223
- };
224
- const config = { ...defaultOptions, ...options };
225
- return morgan(defaultFormat, config);
226
- }
227
- /**
228
- * Get Slow Down middleware for progressive delays
229
- */
230
- static slowDown(options = {}) {
231
- const defaultOptions = {
232
- windowMs: 15 * 60 * 1000, // 15 minutes
233
- delayAfter: 2, // Allow 2 requests per windowMs without delay
234
- delayMs: 500, // Add 500ms delay per request after delayAfter
235
- maxDelayMs: 20000, // Maximum delay of 20 seconds
236
- skipFailedRequests: false,
237
- skipSuccessfulRequests: false,
238
- };
239
- const config = { ...defaultOptions, ...options };
240
- return slowDown(config);
241
- }
242
- /**
243
- * Get Express Brute middleware for brute force protection
244
- */
245
- static brute(options = {}) {
246
- const store = new ExpressBrute.MemoryStore();
247
- const defaultOptions = {
248
- freeRetries: 2,
249
- minWait: 5 * 60 * 1000, // 5 minutes
250
- maxWait: 60 * 60 * 1000, // 1 hour
251
- lifetime: 24 * 60 * 60, // 1 day (in seconds)
252
- failCallback: (_req, res, _next, nextValidRequestDate) => {
253
- res.status(429).json({
254
- error: "Too many failed attempts",
255
- message: "Account temporarily locked due to too many failed attempts",
256
- nextValidRequestDate: nextValidRequestDate,
257
- });
258
- },
259
- };
260
- const config = { ...defaultOptions, ...options };
261
- const bruteforce = new ExpressBrute(store, config);
262
- return bruteforce.prevent;
263
- }
264
- /**
265
- * Get Multer middleware for file uploads
266
- */
267
- static multer(options = {}) {
268
- const defaultOptions = {
269
- limits: {
270
- fileSize: 5 * 1024 * 1024, // 5MB limit
271
- files: 5, // Maximum 5 files
272
- },
273
- fileFilter: (_req, file, cb) => {
274
- // Allow only specific file types
275
- const allowedTypes = /jpeg|jpg|png|gif|pdf|doc|docx/;
276
- const extname = allowedTypes.test(file.originalname.toLowerCase());
277
- const mimetype = allowedTypes.test(file.mimetype);
278
- if (mimetype && extname) {
279
- return cb(null, true);
280
- }
281
- else {
282
- cb(new Error("Invalid file type. Only images and documents are allowed."));
283
- }
284
- },
285
- };
286
- const config = { ...defaultOptions, ...options };
287
- return multer(config);
288
- }
289
- /**
290
- * Get all default security middleware
291
- */
292
- static security(options = {}) {
293
- return {
294
- helmet: this.helmet(options.helmet),
295
- cors: this.cors(options.cors),
296
- rateLimit: this.rateLimit(options.rateLimit),
297
- compression: this.compression(options.compression),
298
- csrf: this.csrf(options.csrf),
299
- };
300
- }
301
- // Helper method for XSS sanitization
302
- static sanitizeObject(obj, config) {
303
- if (typeof obj === "string") {
304
- return xss(obj, config);
305
- }
306
- else if (Array.isArray(obj)) {
307
- return obj.map((item) => this.sanitizeObject(item, config));
308
- }
309
- else if (obj && typeof obj === "object") {
310
- const sanitized = {};
311
- for (const key in obj) {
312
- if (obj.hasOwnProperty(key)) {
313
- sanitized[key] = this.sanitizeObject(obj[key], config);
314
- }
315
- }
316
- return sanitized;
317
- }
318
- return obj;
319
- }
320
- }
321
-
322
- export { BuiltInMiddleware };
323
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sources":["../../../../../src/middleware/built-in/index.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
@@ -1,333 +0,0 @@
1
- class SQLInjectionDetector {
2
- constructor(config = {}) {
3
- // High-confidence SQL injection patterns (more specific to reduce false positives)
4
- this.highRiskPatterns = [
5
- // Union attacks with SELECT
6
- /(\s|^)(union|UNION)(\s)+(all\s+)?(select|SELECT)/gi,
7
- // SQL comments at end of input or before SQL keywords
8
- /(--|#|\/\*).*?(select|union|drop|delete|insert|update|create|alter)/gi,
9
- /;(\s)*--.*/gi,
10
- // Enhanced boolean injections (more comprehensive)
11
- /(\s|^)(or|OR)(\s)+('?\d+'?\s*=\s*'?\d+'?|'[^']*'\s*=\s*'[^']*'|true|false)/gi,
12
- /(\s|^)(and|AND)(\s)+('?\d+'?\s*=\s*'?\d+'?|'[^']*'\s*=\s*'[^']*'|true|false)/gi,
13
- // Quote-based boolean injections
14
- /'(\s)+(or|OR|and|AND)(\s)+'/gi,
15
- // Comment-obfuscated patterns
16
- /\/\*.*?\*\/(or|OR|and|AND)\/\*.*?\*\//gi,
17
- // Time-based with specific syntax (enhanced)
18
- /(sleep|SLEEP|waitfor|WAITFOR|delay|DELAY)\s*\(.*?\)/gi,
19
- /(waitfor|WAITFOR)\s+(delay|DELAY)\s+'/gi,
20
- // System stored procedures
21
- /(exec|EXEC|execute|EXECUTE)\s+(sp_|xp_)\w+/gi,
22
- // Information schema with specific queries
23
- /(information_schema|INFORMATION_SCHEMA)\.(tables|columns|schemata)/gi,
24
- // Dangerous DDL operations with semicolons
25
- /;(\s)*(drop|DROP|delete|DELETE|truncate|TRUNCATE)\s+(table|database)/gi,
26
- // Hex encoding of common injection strings
27
- /0x(27|22|5C|2D|2D)/gi, // ', ", \, --
28
- // Multiple quotes for quote breaking
29
- /('{3,}|"{3,})/g,
30
- // Stacked queries with dangerous operations
31
- /;(\s)*(drop|delete|insert|update|create|alter)(\s)+/gi,
32
- ];
33
- // Medium risk patterns (require context analysis)
34
- this.mediumRiskPatterns = [
35
- // Single SQL keywords (common in legitimate text)
36
- /\b(select|union|drop|delete|insert|update|create|alter)\b/gi,
37
- // Simple OR/AND conditions
38
- /\b(or|and)\s+\w+\s*=\s*\w+/gi,
39
- // Single quotes or double quotes
40
- /'/g,
41
- /"/g,
42
- // Basic SQL comments
43
- /(--|#)/g,
44
- // Wildcards
45
- /[%_]/g,
46
- ];
47
- // Characters that are suspicious in certain contexts
48
- this.contextSensitiveChars = /[';\"\\%_]/g;
49
- this.config = {
50
- strictMode: config.strictMode ?? false,
51
- allowedChars: config.allowedChars ?? /^[a-zA-Z0-9\s\-@.!?,()]+$/,
52
- maxLength: config.maxLength ?? 1000,
53
- logAttempts: config.logAttempts ?? true,
54
- contextualAnalysis: config.contextualAnalysis ?? true,
55
- falsePositiveThreshold: config.falsePositiveThreshold ?? 0.6,
56
- };
57
- }
58
- /**
59
- * Main detection method with improved false positive handling
60
- */
61
- detect(input, context) {
62
- if (!input || typeof input !== "string") {
63
- return {
64
- isMalicious: false,
65
- confidence: 0,
66
- detectedPatterns: [],
67
- riskLevel: "LOW",
68
- };
69
- }
70
- const result = {
71
- isMalicious: false,
72
- confidence: 0,
73
- detectedPatterns: [],
74
- sanitizedInput: input,
75
- riskLevel: "LOW",
76
- };
77
- // Check input length (very long inputs are suspicious)
78
- if (input.length > this.config.maxLength) {
79
- result.confidence += 0.2; // Reduced penalty for length
80
- result.detectedPatterns.push("Excessive length");
81
- }
82
- // High-risk pattern analysis (strong indicators)
83
- let highRiskScore = 0;
84
- this.highRiskPatterns.forEach((pattern, index) => {
85
- const matches = input.match(pattern);
86
- if (matches) {
87
- const patternName = this.getHighRiskPatternName(index);
88
- result.detectedPatterns.push(`${patternName}: ${matches.join(", ")}`);
89
- highRiskScore += this.getHighRiskPatternWeight(index);
90
- }
91
- });
92
- // Medium-risk pattern analysis (context-dependent)
93
- let mediumRiskScore = 0;
94
- if (this.config.contextualAnalysis) {
95
- mediumRiskScore = this.analyzeContext(input, context || "");
96
- }
97
- else {
98
- // Basic medium risk analysis without context
99
- this.mediumRiskPatterns.forEach((pattern, index) => {
100
- const matches = input.match(pattern);
101
- if (matches) {
102
- mediumRiskScore += 0.1 * matches.length; // Lower weight for medium risk
103
- }
104
- });
105
- }
106
- // Contextual analysis for legitimate use cases
107
- const legitimacyScore = this.calculateLegitimacyScore(input);
108
- // Calculate confidence with false positive mitigation
109
- const rawScore = highRiskScore + mediumRiskScore * 0.3;
110
- result.confidence = Math.max(0, rawScore - legitimacyScore);
111
- result.confidence = Math.min(result.confidence, 1.0);
112
- // Determine risk level and malicious status
113
- if (result.confidence >= 0.8) {
114
- result.riskLevel = "CRITICAL";
115
- result.isMalicious = true;
116
- }
117
- else if (result.confidence >= this.config.falsePositiveThreshold) {
118
- result.riskLevel = "HIGH";
119
- result.isMalicious = true;
120
- }
121
- else if (result.confidence >= 0.3) {
122
- result.riskLevel = "MEDIUM";
123
- result.isMalicious = false; // Don't block medium risk by default
124
- }
125
- else {
126
- result.riskLevel = "LOW";
127
- result.isMalicious = false;
128
- }
129
- // Log only high confidence attempts
130
- if (this.config.logAttempts && result.confidence >= 0.7) {
131
- this.logAttempt(input, result);
132
- }
133
- // Provide sanitized version only for high-risk inputs
134
- if (result.confidence >= 0.4) {
135
- result.sanitizedInput = this.smartSanitize(input);
136
- }
137
- return result;
138
- }
139
- /**
140
- * Analyze context to reduce false positives
141
- */
142
- analyzeContext(input, context) {
143
- let score = 0;
144
- // Check for legitimate business contexts
145
- const businessContexts = [
146
- "search",
147
- "filter",
148
- "name",
149
- "description",
150
- "comment",
151
- "review",
152
- "address",
153
- "title",
154
- "content",
155
- "message",
156
- "email",
157
- ];
158
- const isBusinessContext = businessContexts.some((ctx) => context.toLowerCase().includes(ctx));
159
- this.mediumRiskPatterns.forEach((pattern, index) => {
160
- const matches = input.match(pattern);
161
- if (matches) {
162
- let patternScore = 0.1 * matches.length;
163
- // Reduce score for legitimate contexts
164
- if (isBusinessContext) {
165
- patternScore *= 0.3; // Reduce by 70%
166
- }
167
- // Special handling for common false positives
168
- if (index === 0 && isBusinessContext) {
169
- // SQL keywords in business text
170
- patternScore *= 0.1; // Very low weight for SQL keywords in business context
171
- }
172
- if (index === 2 || index === 3) {
173
- // Single quotes in names, descriptions
174
- if (context.includes("name") ||
175
- context.includes("description")) {
176
- patternScore *= 0.2;
177
- }
178
- }
179
- score += patternScore;
180
- }
181
- });
182
- return score;
183
- }
184
- /**
185
- * Calculate legitimacy score to offset false positives
186
- */
187
- calculateLegitimacyScore(input) {
188
- let legitimacyScore = 0;
189
- // Natural language indicators
190
- const naturalWords = input.match(/\b[a-zA-Z]{3,}\b/g);
191
- if (naturalWords && naturalWords.length > 2) {
192
- legitimacyScore += 0.2; // Looks like natural text
193
- }
194
- // Check for common legitimate patterns
195
- const legitimatePatterns = [
196
- /^[A-Z][a-z]+\s[A-Z][a-z]+$/, // First Last name
197
- /^[\w\.-]+@[\w\.-]+\.\w+$/, // Email
198
- /^\d{1,5}\s\w+(\s\w+)*$/, // Address format
199
- /^[A-Za-z0-9\s\-.,!?()]+$/, // Normal text with punctuation
200
- ];
201
- legitimatePatterns.forEach((pattern) => {
202
- if (pattern.test(input)) {
203
- legitimacyScore += 0.15;
204
- }
205
- });
206
- // Length-based legitimacy (very short or very specific lengths are more suspicious)
207
- if (input.length > 10 && input.length < 200) {
208
- legitimacyScore += 0.1;
209
- }
210
- // Check for balanced quotes (legitimate text often has balanced quotes)
211
- const singleQuotes = (input.match(/'/g) || []).length;
212
- const doubleQuotes = (input.match(/"/g) || []).length;
213
- if (singleQuotes % 2 === 0 && doubleQuotes % 2 === 0) {
214
- legitimacyScore += 0.1;
215
- }
216
- return Math.min(legitimacyScore, 0.5); // Cap legitimacy score
217
- }
218
- /**
219
- * Smart sanitization that preserves legitimate content
220
- */
221
- smartSanitize(input) {
222
- if (!input)
223
- return input;
224
- let sanitized = input;
225
- // Only remove obvious SQL injection patterns, not all SQL keywords
226
- sanitized = sanitized.replace(/(--|#).*$/gm, ""); // Remove comment tails
227
- sanitized = sanitized.replace(/\/\*.*?\*\//g, ""); // Remove /* */ comments
228
- // Only escape quotes if they appear to be part of injection attempts
229
- const suspiciousQuotes = /'(\s*(or|and|union|select)\s|;|\s*--)/gi;
230
- sanitized = sanitized.replace(suspiciousQuotes, "''$1");
231
- // Remove only dangerous control characters
232
- sanitized = sanitized.replace(/[\x00\x1a]/g, "");
233
- // Only remove semicolons if followed by SQL keywords
234
- sanitized = sanitized.replace(/;(\s)*(drop|delete|insert|update|create|alter|union|select)/gi, " $2");
235
- return sanitized.trim();
236
- }
237
- /**
238
- * Validate and sanitize input, throwing error if malicious
239
- */
240
- validateAndSanitize(input, throwOnDetection = false) {
241
- const result = this.detect(input);
242
- if (result.isMalicious && throwOnDetection) {
243
- throw new Error(`SQL injection attempt detected. Confidence: ${(result.confidence * 100).toFixed(1)}%. ` +
244
- `Patterns: ${result.detectedPatterns.join(", ")}`);
245
- }
246
- return result.sanitizedInput || "";
247
- }
248
- /**
249
- * Create parameterized query helper
250
- */
251
- createParameterizedQuery(query, params) {
252
- // Simple parameterization helper
253
- let parameterizedQuery = query;
254
- const safeParams = [];
255
- params.forEach((param, index) => {
256
- if (typeof param === "string") {
257
- const result = this.detect(param);
258
- if (result.isMalicious) {
259
- throw new Error(`Parameter ${index} contains potential SQL injection`);
260
- }
261
- safeParams.push(result.sanitizedInput);
262
- }
263
- else {
264
- safeParams.push(param);
265
- }
266
- });
267
- return { query: parameterizedQuery, params: safeParams };
268
- }
269
- getHighRiskPatternName(index) {
270
- const names = [
271
- "Union-Select attack",
272
- "Commented injection",
273
- "Comment with semicolon",
274
- "Enhanced boolean OR",
275
- "Enhanced boolean AND",
276
- "Quote-based boolean",
277
- "Comment-obfuscated injection",
278
- "Time-based delay",
279
- "WAITFOR delay attack",
280
- "System procedure call",
281
- "Information schema query",
282
- "DDL with semicolon",
283
- "Hex-encoded injection",
284
- "Quote sequence attack",
285
- "Stacked query attack",
286
- ];
287
- return names[index] || `High-risk pattern ${index}`;
288
- }
289
- getHighRiskPatternWeight(index) {
290
- // Higher weights for more definitive attack patterns
291
- const weights = [
292
- 0.9, // Union-Select attack
293
- 0.8, // Commented injection
294
- 0.7, // Comment with semicolon
295
- 0.8, // Enhanced boolean OR
296
- 0.8, // Enhanced boolean AND
297
- 0.7, // Quote-based boolean
298
- 0.8, // Comment-obfuscated injection
299
- 0.9, // Time-based delay
300
- 0.8, // WAITFOR delay attack
301
- 0.8, // System procedure call
302
- 0.7, // Information schema query
303
- 0.9, // DDL with semicolon
304
- 0.6, // Hex-encoded injection
305
- 0.5, // Quote sequence attack
306
- 0.8, // Stacked query attack
307
- ];
308
- return weights[index] || 0.7;
309
- }
310
- logAttempt(input, result) {
311
- console.warn(`SQL Injection Attempt Detected:`, {
312
- timestamp: new Date().toISOString(),
313
- input: input.substring(0, 100) + (input.length > 100 ? "..." : ""),
314
- confidence: result.confidence,
315
- patterns: result.detectedPatterns,
316
- });
317
- }
318
- /**
319
- * Update configuration
320
- */
321
- updateConfig(newConfig) {
322
- this.config = { ...this.config, ...newConfig };
323
- }
324
- /**
325
- * Get current configuration
326
- */
327
- getConfig() {
328
- return { ...this.config };
329
- }
330
- }
331
-
332
- export { SQLInjectionDetector as default };
333
- //# sourceMappingURL=sqlInjection.js.map