xypriss 2.2.5 → 2.3.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/README.md +1 -3
- package/dist/cjs/mods/security/src/algorithms/hash-algorithms.js +9 -5
- package/dist/cjs/mods/security/src/algorithms/hash-algorithms.js.map +1 -1
- package/dist/cjs/mods/security/src/components/cache/cacheSys.utils.js +9 -5
- package/dist/cjs/mods/security/src/components/cache/cacheSys.utils.js.map +1 -1
- package/dist/cjs/mods/security/src/components/cache/index.js +9 -5
- package/dist/cjs/mods/security/src/components/cache/index.js.map +1 -1
- package/dist/cjs/mods/security/src/components/fortified-function/index.js +8 -4
- package/dist/cjs/mods/security/src/components/fortified-function/index.js.map +1 -1
- package/dist/cjs/mods/security/src/components/fortified-function/security/security-handler.js +9 -5
- package/dist/cjs/mods/security/src/components/fortified-function/security/security-handler.js.map +1 -1
- package/dist/cjs/mods/security/src/index.js +9 -5
- package/dist/cjs/mods/security/src/index.js.map +1 -1
- package/dist/cjs/src/cluster/modules/CrossPlatformMemory.js +31 -2
- package/dist/cjs/src/cluster/modules/CrossPlatformMemory.js.map +1 -1
- package/dist/cjs/src/middleware/XyPrissMiddlewareAPI.js +87 -30
- package/dist/cjs/src/middleware/XyPrissMiddlewareAPI.js.map +1 -1
- package/dist/cjs/src/middleware/built-in/BuiltInMiddleware.js +320 -0
- package/dist/cjs/src/middleware/built-in/BuiltInMiddleware.js.map +1 -0
- package/dist/cjs/src/middleware/built-in/security/CommandInjectionDetector.js +215 -0
- package/dist/cjs/src/middleware/built-in/security/CommandInjectionDetector.js.map +1 -0
- package/dist/cjs/src/middleware/built-in/security/LDAPInjectionDetector.js +96 -0
- package/dist/cjs/src/middleware/built-in/security/LDAPInjectionDetector.js.map +1 -0
- package/dist/cjs/src/middleware/built-in/security/PathTraversalDetector.js +212 -0
- package/dist/cjs/src/middleware/built-in/security/PathTraversalDetector.js.map +1 -0
- package/dist/cjs/src/middleware/built-in/security/SQLInjectionDetector.js +335 -0
- package/dist/cjs/src/middleware/built-in/security/SQLInjectionDetector.js.map +1 -0
- package/dist/cjs/src/middleware/built-in/security/XXEProtector.js +175 -0
- package/dist/cjs/src/middleware/built-in/security/XXEProtector.js.map +1 -0
- package/dist/cjs/src/middleware/security-middleware.js +249 -132
- package/dist/cjs/src/middleware/security-middleware.js.map +1 -1
- package/dist/cjs/src/plugins/modules/index.js +8 -4
- package/dist/cjs/src/plugins/modules/index.js.map +1 -1
- package/dist/cjs/src/server/FastServer.js +49 -32
- package/dist/cjs/src/server/FastServer.js.map +1 -1
- package/dist/cjs/src/server/ServerFactory.js +34 -1
- package/dist/cjs/src/server/ServerFactory.js.map +1 -1
- package/dist/cjs/src/server/components/multi-server/MultiServerManager.js +11 -2
- package/dist/cjs/src/server/components/multi-server/MultiServerManager.js.map +1 -1
- package/dist/cjs/src/server/const/default.js +15 -1
- package/dist/cjs/src/server/const/default.js.map +1 -1
- package/dist/esm/mods/security/src/algorithms/hash-algorithms.js +9 -5
- package/dist/esm/mods/security/src/algorithms/hash-algorithms.js.map +1 -1
- package/dist/esm/mods/security/src/components/cache/cacheSys.utils.js +9 -5
- package/dist/esm/mods/security/src/components/cache/cacheSys.utils.js.map +1 -1
- package/dist/esm/mods/security/src/components/cache/index.js +9 -5
- package/dist/esm/mods/security/src/components/cache/index.js.map +1 -1
- package/dist/esm/mods/security/src/components/fortified-function/index.js +8 -4
- package/dist/esm/mods/security/src/components/fortified-function/index.js.map +1 -1
- package/dist/esm/mods/security/src/components/fortified-function/security/security-handler.js +9 -5
- package/dist/esm/mods/security/src/components/fortified-function/security/security-handler.js.map +1 -1
- package/dist/esm/mods/security/src/index.js +9 -5
- package/dist/esm/mods/security/src/index.js.map +1 -1
- package/dist/esm/src/cluster/modules/CrossPlatformMemory.js +31 -2
- package/dist/esm/src/cluster/modules/CrossPlatformMemory.js.map +1 -1
- package/dist/esm/src/middleware/XyPrissMiddlewareAPI.js +75 -18
- package/dist/esm/src/middleware/XyPrissMiddlewareAPI.js.map +1 -1
- package/dist/esm/src/middleware/built-in/BuiltInMiddleware.js +318 -0
- package/dist/esm/src/middleware/built-in/BuiltInMiddleware.js.map +1 -0
- package/dist/esm/src/middleware/built-in/security/CommandInjectionDetector.js +213 -0
- package/dist/esm/src/middleware/built-in/security/CommandInjectionDetector.js.map +1 -0
- package/dist/esm/src/middleware/built-in/security/LDAPInjectionDetector.js +94 -0
- package/dist/esm/src/middleware/built-in/security/LDAPInjectionDetector.js.map +1 -0
- package/dist/esm/src/middleware/built-in/security/PathTraversalDetector.js +210 -0
- package/dist/esm/src/middleware/built-in/security/PathTraversalDetector.js.map +1 -0
- package/dist/esm/src/middleware/built-in/security/SQLInjectionDetector.js +333 -0
- package/dist/esm/src/middleware/built-in/security/SQLInjectionDetector.js.map +1 -0
- package/dist/esm/src/middleware/built-in/security/XXEProtector.js +173 -0
- package/dist/esm/src/middleware/built-in/security/XXEProtector.js.map +1 -0
- package/dist/esm/src/middleware/security-middleware.js +248 -131
- package/dist/esm/src/middleware/security-middleware.js.map +1 -1
- package/dist/esm/src/plugins/modules/index.js +8 -4
- package/dist/esm/src/plugins/modules/index.js.map +1 -1
- package/dist/esm/src/server/FastServer.js +50 -33
- package/dist/esm/src/server/FastServer.js.map +1 -1
- package/dist/esm/src/server/ServerFactory.js +34 -1
- package/dist/esm/src/server/ServerFactory.js.map +1 -1
- package/dist/esm/src/server/components/multi-server/MultiServerManager.js +11 -2
- package/dist/esm/src/server/components/multi-server/MultiServerManager.js.map +1 -1
- package/dist/esm/src/server/const/default.js +15 -1
- package/dist/esm/src/server/const/default.js.map +1 -1
- package/dist/index.d.ts +895 -39
- package/package.json +2 -2
|
@@ -0,0 +1,318 @@
|
|
|
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
|
+
* By default, allows all headers to be developer-friendly.
|
|
58
|
+
* Developers can restrict headers via config if needed for production.
|
|
59
|
+
*/
|
|
60
|
+
static cors(options = {}) {
|
|
61
|
+
const defaultOptions = {
|
|
62
|
+
origin: true,
|
|
63
|
+
methods: ["GET", "HEAD", "PUT", "PATCH", "POST", "DELETE"],
|
|
64
|
+
// Allow all headers by default - developers can restrict via config
|
|
65
|
+
// This prevents CORS issues during development
|
|
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, next, options) => {
|
|
86
|
+
const message = options?.message;
|
|
87
|
+
if (typeof message === 'string') {
|
|
88
|
+
res.status(429).json({
|
|
89
|
+
error: "Rate limit exceeded",
|
|
90
|
+
message: message,
|
|
91
|
+
retryAfter: Math.ceil((options?.windowMs || 60000) / 1000) || 900,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
else if (typeof message === 'object' && message !== null) {
|
|
95
|
+
res.status(429).json({
|
|
96
|
+
...message,
|
|
97
|
+
retryAfter: Math.ceil((options?.windowMs || 60000) / 1000) || 900,
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
res.status(429).json({
|
|
102
|
+
error: "Too many requests",
|
|
103
|
+
message: "Rate limit exceeded. Please try again later.",
|
|
104
|
+
retryAfter: Math.ceil((options?.windowMs || 60000) / 1000) || 900,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
};
|
|
109
|
+
const config = { ...defaultOptions, ...options };
|
|
110
|
+
return rateLimit(config);
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Get Compression middleware
|
|
114
|
+
*/
|
|
115
|
+
static compression(options = {}) {
|
|
116
|
+
const defaultOptions = {
|
|
117
|
+
level: 6,
|
|
118
|
+
threshold: 1024, // Only compress responses >= 1KB
|
|
119
|
+
filter: (req, res) => {
|
|
120
|
+
// Don't compress responses with this request header
|
|
121
|
+
if (req.headers["x-no-compression"]) {
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
// Fallback to standard filter function
|
|
125
|
+
return compression.filter(req, res);
|
|
126
|
+
},
|
|
127
|
+
};
|
|
128
|
+
const config = { ...defaultOptions, ...options };
|
|
129
|
+
return compression(config);
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* CSRF protection middleware using csrf-csrf library
|
|
133
|
+
*/
|
|
134
|
+
static csrf(options = {
|
|
135
|
+
getSecret: () => "e6ac40fffc5e9399eab10f5b84fcba2c923e7f74a73b76b56c11b722671eea5e",
|
|
136
|
+
getSessionIdentifier: (req) => req.session.id,
|
|
137
|
+
}) {
|
|
138
|
+
const defaultOptions = {
|
|
139
|
+
cookieName: "__Host-psifi.x-csrf-token",
|
|
140
|
+
cookieOptions: {
|
|
141
|
+
httpOnly: true,
|
|
142
|
+
sameSite: "strict",
|
|
143
|
+
secure: process.env.NODE_ENV === "production",
|
|
144
|
+
maxAge: 3600000, // 1 hour
|
|
145
|
+
},
|
|
146
|
+
size: 64,
|
|
147
|
+
ignoredMethods: ["GET", "HEAD", "OPTIONS"],
|
|
148
|
+
getTokenFromRequest: (req) => {
|
|
149
|
+
return (req.headers["x-csrf-token"] ||
|
|
150
|
+
req.body?._csrf ||
|
|
151
|
+
req.query?._csrf);
|
|
152
|
+
},
|
|
153
|
+
};
|
|
154
|
+
const config = { ...defaultOptions, ...options };
|
|
155
|
+
const { doubleCsrfProtection } = doubleCsrf(config);
|
|
156
|
+
// Return the protection middleware
|
|
157
|
+
return doubleCsrfProtection;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Get HPP (HTTP Parameter Pollution) protection middleware
|
|
161
|
+
*/
|
|
162
|
+
static hpp(options = {}) {
|
|
163
|
+
const defaultOptions = {
|
|
164
|
+
whitelist: ["tags", "categories"], // Allow arrays for these parameters
|
|
165
|
+
};
|
|
166
|
+
const config = { ...defaultOptions, ...options };
|
|
167
|
+
return hpp(config);
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Get MongoDB injection protection middleware
|
|
171
|
+
*/
|
|
172
|
+
static mongoSanitize(options = {}) {
|
|
173
|
+
const defaultOptions = {
|
|
174
|
+
replaceWith: "_",
|
|
175
|
+
onSanitize: (key, value) => {
|
|
176
|
+
console.warn(`[MongoSanitize] Sanitized key: ${key}, value: ${value}`);
|
|
177
|
+
},
|
|
178
|
+
};
|
|
179
|
+
const config = { ...defaultOptions, ...options };
|
|
180
|
+
return mongoSanitize(config);
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Get XSS protection middleware
|
|
184
|
+
*/
|
|
185
|
+
static xss(options = {}) {
|
|
186
|
+
const defaultOptions = {
|
|
187
|
+
whiteList: {
|
|
188
|
+
a: ["href", "title"],
|
|
189
|
+
b: [],
|
|
190
|
+
i: [],
|
|
191
|
+
strong: [],
|
|
192
|
+
em: [],
|
|
193
|
+
},
|
|
194
|
+
};
|
|
195
|
+
const config = { ...defaultOptions, ...options };
|
|
196
|
+
return (req, _res, next) => {
|
|
197
|
+
// Sanitize request body
|
|
198
|
+
if (req.body) {
|
|
199
|
+
req.body = this.sanitizeObject(req.body, config);
|
|
200
|
+
}
|
|
201
|
+
// Sanitize query parameters
|
|
202
|
+
if (req.query) {
|
|
203
|
+
req.query = this.sanitizeObject(req.query, config);
|
|
204
|
+
}
|
|
205
|
+
next();
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Get Morgan logging middleware
|
|
210
|
+
*/
|
|
211
|
+
static morgan(options = {}) {
|
|
212
|
+
const defaultFormat = options.format || "combined";
|
|
213
|
+
const defaultOptions = {
|
|
214
|
+
skip: (_req, res) => res.statusCode < 400, // Only log errors by default
|
|
215
|
+
stream: process.stdout,
|
|
216
|
+
};
|
|
217
|
+
const config = { ...defaultOptions, ...options };
|
|
218
|
+
return morgan(defaultFormat, config);
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Get Slow Down middleware for progressive delays
|
|
222
|
+
*/
|
|
223
|
+
static slowDown(options = {}) {
|
|
224
|
+
const defaultOptions = {
|
|
225
|
+
windowMs: 15 * 60 * 1000, // 15 minutes
|
|
226
|
+
delayAfter: 2, // Allow 2 requests per windowMs without delay
|
|
227
|
+
delayMs: 500, // Add 500ms delay per request after delayAfter
|
|
228
|
+
maxDelayMs: 20000, // Maximum delay of 20 seconds
|
|
229
|
+
skipFailedRequests: false,
|
|
230
|
+
skipSuccessfulRequests: false,
|
|
231
|
+
};
|
|
232
|
+
const config = { ...defaultOptions, ...options };
|
|
233
|
+
return slowDown(config);
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Get Express Brute middleware for brute force protection
|
|
237
|
+
*/
|
|
238
|
+
static brute(options = {
|
|
239
|
+
prefix: "nehonix.xypriss.brute",
|
|
240
|
+
}) {
|
|
241
|
+
const store = new ExpressBrute.MemoryStore();
|
|
242
|
+
const defaultOptions = {
|
|
243
|
+
freeRetries: 2,
|
|
244
|
+
minWait: 5 * 60 * 1000, // 5 minutes
|
|
245
|
+
maxWait: 60 * 60 * 1000, // 1 hour
|
|
246
|
+
lifetime: 24 * 60 * 60, // 1 day (in seconds)
|
|
247
|
+
failCallback: (_req, res, _next, nextValidRequestDate) => {
|
|
248
|
+
res.status(429).json({
|
|
249
|
+
error: "Too many failed attempts",
|
|
250
|
+
message: "Account temporarily locked due to too many failed attempts",
|
|
251
|
+
nextValidRequestDate: nextValidRequestDate,
|
|
252
|
+
});
|
|
253
|
+
},
|
|
254
|
+
};
|
|
255
|
+
const config = { ...defaultOptions, ...options };
|
|
256
|
+
const bruteforce = new ExpressBrute(store, config);
|
|
257
|
+
return bruteforce.prevent;
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Get Multer middleware for file uploads
|
|
261
|
+
*/
|
|
262
|
+
static multer(options = {}) {
|
|
263
|
+
const defaultOptions = {
|
|
264
|
+
limits: {
|
|
265
|
+
fileSize: 5 * 1024 * 1024, // 5MB limit
|
|
266
|
+
files: 5, // Maximum 5 files
|
|
267
|
+
},
|
|
268
|
+
fileFilter: (_req, file, cb) => {
|
|
269
|
+
// Allow only specific file types
|
|
270
|
+
const allowedTypes = /jpeg|jpg|png|gif|pdf|doc|docx/;
|
|
271
|
+
const extname = allowedTypes.test(file.originalname.toLowerCase());
|
|
272
|
+
const mimetype = allowedTypes.test(file.mimetype);
|
|
273
|
+
if (mimetype && extname) {
|
|
274
|
+
return cb(null, true);
|
|
275
|
+
}
|
|
276
|
+
else {
|
|
277
|
+
cb(new Error("Invalid file type. Only images and documents are allowed."));
|
|
278
|
+
}
|
|
279
|
+
},
|
|
280
|
+
};
|
|
281
|
+
const config = { ...defaultOptions, ...options };
|
|
282
|
+
return multer(config);
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Get all default security middleware
|
|
286
|
+
*/
|
|
287
|
+
static security(options = {}) {
|
|
288
|
+
return {
|
|
289
|
+
helmet: this.helmet(options.helmet),
|
|
290
|
+
cors: this.cors(options.cors),
|
|
291
|
+
rateLimit: this.rateLimit(options.rateLimit),
|
|
292
|
+
compression: this.compression(options.compression),
|
|
293
|
+
csrf: this.csrf(options.csrf),
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
// Helper method for XSS sanitization
|
|
297
|
+
static sanitizeObject(obj, config) {
|
|
298
|
+
if (typeof obj === "string") {
|
|
299
|
+
return xss(obj, config);
|
|
300
|
+
}
|
|
301
|
+
else if (Array.isArray(obj)) {
|
|
302
|
+
return obj.map((item) => this.sanitizeObject(item, config));
|
|
303
|
+
}
|
|
304
|
+
else if (obj && typeof obj === "object") {
|
|
305
|
+
const sanitized = {};
|
|
306
|
+
for (const key in obj) {
|
|
307
|
+
if (obj.hasOwnProperty(key)) {
|
|
308
|
+
sanitized[key] = this.sanitizeObject(obj[key], config);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
return sanitized;
|
|
312
|
+
}
|
|
313
|
+
return obj;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
export { BuiltInMiddleware };
|
|
318
|
+
//# sourceMappingURL=BuiltInMiddleware.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BuiltInMiddleware.js","sources":["../../../../../src/middleware/built-in/BuiltInMiddleware.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Command Injection Detection Module
|
|
3
|
+
*
|
|
4
|
+
* Detects and prevents OS command injection attacks with
|
|
5
|
+
* intelligent context-aware false positive reduction
|
|
6
|
+
*/
|
|
7
|
+
class CommandInjectionDetector {
|
|
8
|
+
constructor(config = {}) {
|
|
9
|
+
// High-risk command injection patterns
|
|
10
|
+
this.highRiskPatterns = [
|
|
11
|
+
// Command chaining
|
|
12
|
+
/[;&|`]\s*(ls|cat|wget|curl|nc|netcat|bash|sh|cmd|powershell|eval|exec)/gi,
|
|
13
|
+
// Command substitution
|
|
14
|
+
/\$\(.*?\)/g,
|
|
15
|
+
/`.*?`/g,
|
|
16
|
+
// Pipe to dangerous commands
|
|
17
|
+
/\|\s*(bash|sh|cmd|powershell|python|perl|ruby|node)/gi,
|
|
18
|
+
// Redirection with dangerous commands
|
|
19
|
+
/[<>]\s*(\/etc\/|\/bin\/|C:\\)/gi,
|
|
20
|
+
// Encoded command injection
|
|
21
|
+
/%0a|%0d|%09/gi, // newline, carriage return, tab
|
|
22
|
+
// Dangerous system commands
|
|
23
|
+
/(rm\s+-rf|del\s+\/|format\s+|mkfs|dd\s+if=)/gi,
|
|
24
|
+
// Network commands
|
|
25
|
+
/(wget|curl|nc|netcat|telnet|ssh|ftp)\s+/gi,
|
|
26
|
+
// Eval/exec patterns
|
|
27
|
+
/(eval|exec|system|passthru|shell_exec|popen)\s*\(/gi,
|
|
28
|
+
];
|
|
29
|
+
// Medium-risk patterns
|
|
30
|
+
this.mediumRiskPatterns = [
|
|
31
|
+
// Shell metacharacters
|
|
32
|
+
/[;&|`$()]/g,
|
|
33
|
+
// Redirection operators
|
|
34
|
+
/[<>]/g,
|
|
35
|
+
// Common command names (could be legitimate text)
|
|
36
|
+
/\b(ls|cat|echo|pwd|cd|mkdir|touch|grep|find|chmod|chown)\b/gi,
|
|
37
|
+
];
|
|
38
|
+
this.config = {
|
|
39
|
+
enabled: config.enabled ?? true,
|
|
40
|
+
strictMode: config.strictMode ?? false,
|
|
41
|
+
logAttempts: config.logAttempts ?? true,
|
|
42
|
+
blockOnDetection: config.blockOnDetection ?? true,
|
|
43
|
+
falsePositiveThreshold: config.falsePositiveThreshold ?? 0.7,
|
|
44
|
+
customPatterns: config.customPatterns ?? [],
|
|
45
|
+
allowedCommands: config.allowedCommands ?? [],
|
|
46
|
+
contextualAnalysis: config.contextualAnalysis ?? true,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Detect command injection attempts
|
|
51
|
+
*/
|
|
52
|
+
detect(input, context) {
|
|
53
|
+
if (!input || typeof input !== 'string') {
|
|
54
|
+
return {
|
|
55
|
+
isMalicious: false,
|
|
56
|
+
confidence: 0,
|
|
57
|
+
detectedPatterns: [],
|
|
58
|
+
riskLevel: 'LOW',
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
const result = {
|
|
62
|
+
isMalicious: false,
|
|
63
|
+
confidence: 0,
|
|
64
|
+
detectedPatterns: [],
|
|
65
|
+
sanitizedInput: input,
|
|
66
|
+
riskLevel: 'LOW',
|
|
67
|
+
};
|
|
68
|
+
// High-risk pattern detection
|
|
69
|
+
let highRiskScore = 0;
|
|
70
|
+
this.highRiskPatterns.forEach((pattern, index) => {
|
|
71
|
+
const matches = input.match(pattern);
|
|
72
|
+
if (matches) {
|
|
73
|
+
const patternName = this.getHighRiskPatternName(index);
|
|
74
|
+
result.detectedPatterns.push(`${patternName}: ${matches.join(', ')}`);
|
|
75
|
+
highRiskScore += this.getHighRiskWeight(index);
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
// Medium-risk pattern detection with context
|
|
79
|
+
let mediumRiskScore = 0;
|
|
80
|
+
if (this.config.contextualAnalysis && context) {
|
|
81
|
+
mediumRiskScore = this.analyzeContext(input, context);
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
this.mediumRiskPatterns.forEach((pattern) => {
|
|
85
|
+
const matches = input.match(pattern);
|
|
86
|
+
if (matches) {
|
|
87
|
+
mediumRiskScore += 0.1 * matches.length;
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
// Legitimacy checks
|
|
92
|
+
const legitimacyScore = this.calculateLegitimacyScore(input);
|
|
93
|
+
// Calculate final confidence
|
|
94
|
+
result.confidence = Math.max(0, highRiskScore + mediumRiskScore * 0.3 - legitimacyScore);
|
|
95
|
+
result.confidence = Math.min(result.confidence, 1.0);
|
|
96
|
+
// Determine risk level
|
|
97
|
+
if (result.confidence >= 0.9) {
|
|
98
|
+
result.riskLevel = 'CRITICAL';
|
|
99
|
+
result.isMalicious = true;
|
|
100
|
+
}
|
|
101
|
+
else if (result.confidence >= this.config.falsePositiveThreshold) {
|
|
102
|
+
result.riskLevel = 'HIGH';
|
|
103
|
+
result.isMalicious = true;
|
|
104
|
+
}
|
|
105
|
+
else if (result.confidence >= 0.4) {
|
|
106
|
+
result.riskLevel = 'MEDIUM';
|
|
107
|
+
result.isMalicious = false;
|
|
108
|
+
}
|
|
109
|
+
// Sanitize input
|
|
110
|
+
if (result.confidence >= 0.4) {
|
|
111
|
+
result.sanitizedInput = this.sanitizeInput(input);
|
|
112
|
+
}
|
|
113
|
+
// Log attempts
|
|
114
|
+
if (this.config.logAttempts && result.confidence >= 0.7) {
|
|
115
|
+
this.logAttempt(input, result);
|
|
116
|
+
}
|
|
117
|
+
return result;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Sanitize input by removing command injection sequences
|
|
121
|
+
*/
|
|
122
|
+
sanitizeInput(input) {
|
|
123
|
+
let sanitized = input;
|
|
124
|
+
// Remove command chaining characters
|
|
125
|
+
sanitized = sanitized.replace(/[;&|`]/g, '');
|
|
126
|
+
// Remove command substitution
|
|
127
|
+
sanitized = sanitized.replace(/\$\(.*?\)/g, '');
|
|
128
|
+
// Remove backticks
|
|
129
|
+
sanitized = sanitized.replace(/`/g, '');
|
|
130
|
+
// Remove redirection operators
|
|
131
|
+
sanitized = sanitized.replace(/[<>]/g, '');
|
|
132
|
+
// Remove encoded newlines/tabs
|
|
133
|
+
sanitized = sanitized.replace(/%0a|%0d|%09/gi, '');
|
|
134
|
+
return sanitized.trim();
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Analyze context to reduce false positives
|
|
138
|
+
*/
|
|
139
|
+
analyzeContext(input, context) {
|
|
140
|
+
let score = 0;
|
|
141
|
+
// Check if this is a code/technical field where commands might be legitimate
|
|
142
|
+
const technicalContexts = ['code', 'script', 'command', 'terminal', 'shell'];
|
|
143
|
+
const isTechnicalContext = technicalContexts.some(ctx => context.fieldName?.toLowerCase().includes(ctx) ||
|
|
144
|
+
context.fieldType?.toLowerCase().includes(ctx));
|
|
145
|
+
this.mediumRiskPatterns.forEach((pattern, index) => {
|
|
146
|
+
const matches = input.match(pattern);
|
|
147
|
+
if (matches) {
|
|
148
|
+
let patternScore = 0.1 * matches.length;
|
|
149
|
+
// Reduce score for technical contexts
|
|
150
|
+
if (isTechnicalContext && index > 1) {
|
|
151
|
+
patternScore *= 0.2; // Reduce by 80% for command names in technical fields
|
|
152
|
+
}
|
|
153
|
+
score += patternScore;
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
return score;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Calculate legitimacy score
|
|
160
|
+
*/
|
|
161
|
+
calculateLegitimacyScore(input) {
|
|
162
|
+
let score = 0;
|
|
163
|
+
// Natural language indicators
|
|
164
|
+
const words = input.split(/\s+/);
|
|
165
|
+
if (words.length > 3 && words.every(w => /^[a-zA-Z]+$/.test(w))) {
|
|
166
|
+
score += 0.3; // Looks like natural text
|
|
167
|
+
}
|
|
168
|
+
// No shell metacharacters
|
|
169
|
+
if (!/[;&|`$()<>]/.test(input)) {
|
|
170
|
+
score += 0.2;
|
|
171
|
+
}
|
|
172
|
+
// Reasonable length for user input
|
|
173
|
+
if (input.length > 10 && input.length < 200) {
|
|
174
|
+
score += 0.1;
|
|
175
|
+
}
|
|
176
|
+
return Math.min(score, 0.5);
|
|
177
|
+
}
|
|
178
|
+
getHighRiskPatternName(index) {
|
|
179
|
+
const names = [
|
|
180
|
+
'Command chaining',
|
|
181
|
+
'Command substitution ($())',
|
|
182
|
+
'Backtick substitution',
|
|
183
|
+
'Pipe to shell',
|
|
184
|
+
'Redirection to system paths',
|
|
185
|
+
'Encoded injection',
|
|
186
|
+
'Dangerous system commands',
|
|
187
|
+
'Network commands',
|
|
188
|
+
'Eval/exec functions',
|
|
189
|
+
];
|
|
190
|
+
return names[index] || `High-risk pattern ${index}`;
|
|
191
|
+
}
|
|
192
|
+
getHighRiskWeight(index) {
|
|
193
|
+
const weights = [0.9, 0.9, 0.9, 0.8, 0.7, 0.6, 0.9, 0.7, 0.9];
|
|
194
|
+
return weights[index] || 0.7;
|
|
195
|
+
}
|
|
196
|
+
logAttempt(input, result) {
|
|
197
|
+
console.warn('[CommandInjection] Attack detected:', {
|
|
198
|
+
timestamp: new Date().toISOString(),
|
|
199
|
+
input: input.substring(0, 100),
|
|
200
|
+
confidence: result.confidence,
|
|
201
|
+
patterns: result.detectedPatterns,
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
updateConfig(newConfig) {
|
|
205
|
+
this.config = { ...this.config, ...newConfig };
|
|
206
|
+
}
|
|
207
|
+
getConfig() {
|
|
208
|
+
return { ...this.config };
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
export { CommandInjectionDetector as default };
|
|
213
|
+
//# sourceMappingURL=CommandInjectionDetector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CommandInjectionDetector.js","sources":["../../../../../../src/middleware/built-in/security/CommandInjectionDetector.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LDAP Injection Detection Module
|
|
3
|
+
*
|
|
4
|
+
* Detects and prevents LDAP injection attacks
|
|
5
|
+
*/
|
|
6
|
+
class LDAPInjectionDetector {
|
|
7
|
+
constructor(config = {}) {
|
|
8
|
+
// LDAP injection patterns
|
|
9
|
+
this.injectionPatterns = [
|
|
10
|
+
// LDAP filter metacharacters
|
|
11
|
+
/[*()\\|&]/g,
|
|
12
|
+
// Null byte
|
|
13
|
+
/\x00/g,
|
|
14
|
+
// LDAP filter injection attempts
|
|
15
|
+
/\)\s*\(\s*\|/gi, // )( | pattern
|
|
16
|
+
/\)\s*\(\s*&/gi, // )( & pattern
|
|
17
|
+
// Wildcard abuse
|
|
18
|
+
/\*{2,}/g,
|
|
19
|
+
// DN injection
|
|
20
|
+
/,\s*(cn|ou|dc|o)=/gi,
|
|
21
|
+
];
|
|
22
|
+
this.config = {
|
|
23
|
+
enabled: config.enabled ?? true,
|
|
24
|
+
strictMode: config.strictMode ?? false,
|
|
25
|
+
logAttempts: config.logAttempts ?? true,
|
|
26
|
+
blockOnDetection: config.blockOnDetection ?? true,
|
|
27
|
+
falsePositiveThreshold: config.falsePositiveThreshold ?? 0.6,
|
|
28
|
+
customPatterns: config.customPatterns ?? [],
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
detect(input) {
|
|
32
|
+
if (!input || typeof input !== 'string') {
|
|
33
|
+
return {
|
|
34
|
+
isMalicious: false,
|
|
35
|
+
confidence: 0,
|
|
36
|
+
detectedPatterns: [],
|
|
37
|
+
riskLevel: 'LOW',
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
const result = {
|
|
41
|
+
isMalicious: false,
|
|
42
|
+
confidence: 0,
|
|
43
|
+
detectedPatterns: [],
|
|
44
|
+
sanitizedInput: input,
|
|
45
|
+
riskLevel: 'LOW',
|
|
46
|
+
};
|
|
47
|
+
let riskScore = 0;
|
|
48
|
+
this.injectionPatterns.forEach((pattern, index) => {
|
|
49
|
+
const matches = input.match(pattern);
|
|
50
|
+
if (matches) {
|
|
51
|
+
result.detectedPatterns.push(`LDAP metacharacter: ${matches.join(', ')}`);
|
|
52
|
+
riskScore += 0.3 * matches.length;
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
result.confidence = Math.min(riskScore, 1.0);
|
|
56
|
+
if (result.confidence >= 0.7) {
|
|
57
|
+
result.riskLevel = 'HIGH';
|
|
58
|
+
result.isMalicious = true;
|
|
59
|
+
}
|
|
60
|
+
else if (result.confidence >= this.config.falsePositiveThreshold) {
|
|
61
|
+
result.riskLevel = 'MEDIUM';
|
|
62
|
+
result.isMalicious = this.config.strictMode;
|
|
63
|
+
}
|
|
64
|
+
if (result.confidence >= 0.3) {
|
|
65
|
+
result.sanitizedInput = this.sanitize(input);
|
|
66
|
+
}
|
|
67
|
+
if (this.config.logAttempts && result.confidence >= 0.6) {
|
|
68
|
+
console.warn('[LDAP] Injection attempt detected:', {
|
|
69
|
+
timestamp: new Date().toISOString(),
|
|
70
|
+
input: input.substring(0, 100),
|
|
71
|
+
confidence: result.confidence,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
return result;
|
|
75
|
+
}
|
|
76
|
+
sanitize(input) {
|
|
77
|
+
// Escape LDAP special characters
|
|
78
|
+
return input
|
|
79
|
+
.replace(/\\/g, '\\5c')
|
|
80
|
+
.replace(/\*/g, '\\2a')
|
|
81
|
+
.replace(/\(/g, '\\28')
|
|
82
|
+
.replace(/\)/g, '\\29')
|
|
83
|
+
.replace(/\x00/g, '\\00');
|
|
84
|
+
}
|
|
85
|
+
updateConfig(newConfig) {
|
|
86
|
+
this.config = { ...this.config, ...newConfig };
|
|
87
|
+
}
|
|
88
|
+
getConfig() {
|
|
89
|
+
return { ...this.config };
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export { LDAPInjectionDetector as default };
|
|
94
|
+
//# sourceMappingURL=LDAPInjectionDetector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LDAPInjectionDetector.js","sources":["../../../../../../src/middleware/built-in/security/LDAPInjectionDetector.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
|