pentest-tool-lite 3.10.6 → 3.10.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (205) hide show
  1. package/dist/Pentest.js +46 -0
  2. package/dist/{src/Test.js → Test.js} +11 -24
  3. package/dist/commands/Sitemap.js +79 -0
  4. package/dist/dns/A.js +49 -0
  5. package/dist/dns/DMARC.js +59 -0
  6. package/dist/dns/NS.js +36 -0
  7. package/dist/dns/RegistrationDate.js +39 -0
  8. package/dist/dns/index.js +47 -0
  9. package/dist/functions/parseSitemap.js +12 -0
  10. package/dist/html/Anchor.js +56 -0
  11. package/dist/html/CSS.js +92 -0
  12. package/dist/html/DuplicateId.js +35 -0
  13. package/dist/html/Generator.js +31 -0
  14. package/dist/html/Image.js +79 -0
  15. package/dist/html/JavaScript.js +107 -0
  16. package/dist/{src/html → html}/__TESTS__/Generator.test.js +10 -19
  17. package/dist/html/index.js +51 -0
  18. package/dist/{src/index → index} +21 -20
  19. package/dist/{src/logger → logger}/Console.js +1 -3
  20. package/dist/metadata/HTML.js +26 -0
  21. package/dist/metadata/Markdown.js +28 -0
  22. package/dist/metadata/ResponseTime.js +25 -0
  23. package/dist/metadata/index.js +45 -0
  24. package/dist/request/NodeFetch.js +58 -0
  25. package/dist/{src/request → request}/cache/UnlimitedCache.js +2 -0
  26. package/dist/security/ContentEncoding.js +44 -0
  27. package/dist/security/ContentSecurityPolicy.js +32 -0
  28. package/dist/security/Cookies.js +44 -0
  29. package/dist/security/FingerPrint.js +37 -0
  30. package/dist/security/GoogleWebRisk.js +44 -0
  31. package/dist/security/HSTS.js +48 -0
  32. package/dist/security/HTTPS.js +78 -0
  33. package/dist/security/HTTPVersion.js +50 -0
  34. package/dist/security/PermissionsPolicy.js +53 -0
  35. package/dist/security/Redirect.js +37 -0
  36. package/dist/security/ReferrerPolicy.js +32 -0
  37. package/dist/security/RobotsTXT.js +28 -0
  38. package/dist/security/SSL.js +36 -0
  39. package/dist/security/XFrameOptions.js +32 -0
  40. package/dist/security/XXSSProtection.js +32 -0
  41. package/dist/{src/security → security}/__TESTS__/ContentSecurityPolicy.test.js +10 -19
  42. package/dist/{src/security → security}/__TESTS__/FingerPrint.test.js +10 -19
  43. package/dist/{src/security → security}/__TESTS__/HSTS.test.js +15 -24
  44. package/dist/{src/security → security}/__TESTS__/HTTPS.test.js +15 -24
  45. package/dist/{src/security → security}/__TESTS__/XFrameOptions.test.js +10 -19
  46. package/dist/{src/security → security}/__TESTS__/XXSSProtection.test.js +10 -19
  47. package/dist/{src/security → security}/index.js +20 -31
  48. package/dist/seo/Heading.js +51 -0
  49. package/dist/seo/Robots.js +21 -0
  50. package/dist/seo/Sitemap.js +32 -0
  51. package/dist/seo/Title.js +44 -0
  52. package/dist/seo/index.js +47 -0
  53. package/dist/wordpress/DefaultFiles.js +50 -0
  54. package/dist/wordpress/Generator.js +58 -0
  55. package/dist/wordpress/index.js +43 -0
  56. package/package.json +10 -2
  57. package/dist/package.json +0 -61
  58. package/dist/src/Pentest.js +0 -57
  59. package/dist/src/commands/Sitemap.js +0 -96
  60. package/dist/src/dns/A.js +0 -65
  61. package/dist/src/dns/DMARC.js +0 -73
  62. package/dist/src/dns/NS.js +0 -52
  63. package/dist/src/dns/RegistrationDate.js +0 -55
  64. package/dist/src/dns/index.js +0 -58
  65. package/dist/src/functions/parseSitemap.js +0 -23
  66. package/dist/src/html/Anchor.js +0 -72
  67. package/dist/src/html/CSS.js +0 -108
  68. package/dist/src/html/DuplicateId.js +0 -49
  69. package/dist/src/html/Generator.js +0 -45
  70. package/dist/src/html/Image.js +0 -95
  71. package/dist/src/html/JavaScript.js +0 -123
  72. package/dist/src/html/index.js +0 -62
  73. package/dist/src/metadata/HTML.js +0 -40
  74. package/dist/src/metadata/Markdown.js +0 -42
  75. package/dist/src/metadata/ResponseTime.js +0 -39
  76. package/dist/src/metadata/index.js +0 -56
  77. package/dist/src/request/NodeFetch.js +0 -68
  78. package/dist/src/security/ContentEncoding.js +0 -58
  79. package/dist/src/security/ContentSecurityPolicy.js +0 -46
  80. package/dist/src/security/Cookies.js +0 -58
  81. package/dist/src/security/FingerPrint.js +0 -51
  82. package/dist/src/security/GoogleWebRisk.js +0 -58
  83. package/dist/src/security/HSTS.js +0 -62
  84. package/dist/src/security/HTTPS.js +0 -92
  85. package/dist/src/security/HTTPVersion.js +0 -64
  86. package/dist/src/security/PermissionsPolicy.js +0 -67
  87. package/dist/src/security/Redirect.js +0 -51
  88. package/dist/src/security/ReferrerPolicy.js +0 -46
  89. package/dist/src/security/RobotsTXT.js +0 -42
  90. package/dist/src/security/SSL.js +0 -50
  91. package/dist/src/security/XFrameOptions.js +0 -46
  92. package/dist/src/security/XXSSProtection.js +0 -46
  93. package/dist/src/seo/Heading.js +0 -65
  94. package/dist/src/seo/Robots.js +0 -35
  95. package/dist/src/seo/Sitemap.js +0 -46
  96. package/dist/src/seo/Title.js +0 -58
  97. package/dist/src/seo/index.js +0 -58
  98. package/dist/src/wordpress/DefaultFiles.js +0 -66
  99. package/dist/src/wordpress/Generator.js +0 -76
  100. package/dist/src/wordpress/index.js +0 -54
  101. /package/dist/{src/Pentest.d.ts → Pentest.d.ts} +0 -0
  102. /package/dist/{src/Test.d.ts → Test.d.ts} +0 -0
  103. /package/dist/{src/commands → commands}/Sitemap.d.ts +0 -0
  104. /package/dist/{src/config.d.ts → config.d.ts} +0 -0
  105. /package/dist/{src/config.js → config.js} +0 -0
  106. /package/dist/{src/dns → dns}/A.d.ts +0 -0
  107. /package/dist/{src/dns → dns}/DMARC.d.ts +0 -0
  108. /package/dist/{src/dns → dns}/NS.d.ts +0 -0
  109. /package/dist/{src/dns → dns}/RegistrationDate.d.ts +0 -0
  110. /package/dist/{src/dns → dns}/index.d.ts +0 -0
  111. /package/dist/{src/functions → functions}/findEvery.d.ts +0 -0
  112. /package/dist/{src/functions → functions}/findEvery.js +0 -0
  113. /package/dist/{src/functions → functions}/getAnchors.d.ts +0 -0
  114. /package/dist/{src/functions → functions}/getAnchors.js +0 -0
  115. /package/dist/{src/functions → functions}/getDomain.d.ts +0 -0
  116. /package/dist/{src/functions → functions}/getDomain.js +0 -0
  117. /package/dist/{src/functions → functions}/getDuplicates.d.ts +0 -0
  118. /package/dist/{src/functions → functions}/getDuplicates.js +0 -0
  119. /package/dist/{src/functions → functions}/getGenerator.d.ts +0 -0
  120. /package/dist/{src/functions → functions}/getGenerator.js +0 -0
  121. /package/dist/{src/functions → functions}/getHeading.d.ts +0 -0
  122. /package/dist/{src/functions → functions}/getHeading.js +0 -0
  123. /package/dist/{src/functions → functions}/getImages.d.ts +0 -0
  124. /package/dist/{src/functions → functions}/getImages.js +0 -0
  125. /package/dist/{src/functions → functions}/getObject.d.ts +0 -0
  126. /package/dist/{src/functions → functions}/getObject.js +0 -0
  127. /package/dist/{src/functions → functions}/getScripts.d.ts +0 -0
  128. /package/dist/{src/functions → functions}/getScripts.js +0 -0
  129. /package/dist/{src/functions → functions}/getStylesheets.d.ts +0 -0
  130. /package/dist/{src/functions → functions}/getStylesheets.js +0 -0
  131. /package/dist/{src/functions → functions}/getTitle.d.ts +0 -0
  132. /package/dist/{src/functions → functions}/getTitle.js +0 -0
  133. /package/dist/{src/functions → functions}/index.d.ts +0 -0
  134. /package/dist/{src/functions → functions}/index.js +0 -0
  135. /package/dist/{src/functions → functions}/parseHtml.d.ts +0 -0
  136. /package/dist/{src/functions → functions}/parseHtml.js +0 -0
  137. /package/dist/{src/functions → functions}/parseSitemap.d.ts +0 -0
  138. /package/dist/{src/functions → functions}/parseXml.d.ts +0 -0
  139. /package/dist/{src/functions → functions}/parseXml.js +0 -0
  140. /package/dist/{src/html → html}/Anchor.d.ts +0 -0
  141. /package/dist/{src/html → html}/CSS.d.ts +0 -0
  142. /package/dist/{src/html → html}/DuplicateId.d.ts +0 -0
  143. /package/dist/{src/html → html}/Generator.d.ts +0 -0
  144. /package/dist/{src/html → html}/Image.d.ts +0 -0
  145. /package/dist/{src/html → html}/JavaScript.d.ts +0 -0
  146. /package/dist/{src/html → html}/__TESTS__/Generator.test.d.ts +0 -0
  147. /package/dist/{src/html → html}/index.d.ts +0 -0
  148. /package/dist/{src/index.d.ts → index.d.ts} +0 -0
  149. /package/dist/{src/logger → logger}/Console.d.ts +0 -0
  150. /package/dist/{src/logger → logger}/Logger.d.ts +0 -0
  151. /package/dist/{src/logger → logger}/Logger.js +0 -0
  152. /package/dist/{src/logger → logger}/index.d.ts +0 -0
  153. /package/dist/{src/logger → logger}/index.js +0 -0
  154. /package/dist/{src/metadata → metadata}/HTML.d.ts +0 -0
  155. /package/dist/{src/metadata → metadata}/Markdown.d.ts +0 -0
  156. /package/dist/{src/metadata → metadata}/ResponseTime.d.ts +0 -0
  157. /package/dist/{src/metadata → metadata}/index.d.ts +0 -0
  158. /package/dist/{src/report → report}/CommandLine.d.ts +0 -0
  159. /package/dist/{src/report → report}/CommandLine.js +0 -0
  160. /package/dist/{src/report → report}/Json.d.ts +0 -0
  161. /package/dist/{src/report → report}/Json.js +0 -0
  162. /package/dist/{src/report → report}/Report.d.ts +0 -0
  163. /package/dist/{src/report → report}/Report.js +0 -0
  164. /package/dist/{src/report → report}/Symbols.d.ts +0 -0
  165. /package/dist/{src/report → report}/Symbols.js +0 -0
  166. /package/dist/{src/report → report}/index.d.ts +0 -0
  167. /package/dist/{src/report → report}/index.js +0 -0
  168. /package/dist/{src/request → request}/NodeFetch.d.ts +0 -0
  169. /package/dist/{src/request → request}/Request.d.ts +0 -0
  170. /package/dist/{src/request → request}/Request.js +0 -0
  171. /package/dist/{src/request → request}/cache/BlackHoleCache.d.ts +0 -0
  172. /package/dist/{src/request → request}/cache/BlackHoleCache.js +0 -0
  173. /package/dist/{src/request → request}/cache/UnlimitedCache.d.ts +0 -0
  174. /package/dist/{src/request → request}/index.d.ts +0 -0
  175. /package/dist/{src/request → request}/index.js +0 -0
  176. /package/dist/{src/security → security}/ContentEncoding.d.ts +0 -0
  177. /package/dist/{src/security → security}/ContentSecurityPolicy.d.ts +0 -0
  178. /package/dist/{src/security → security}/Cookies.d.ts +0 -0
  179. /package/dist/{src/security → security}/FingerPrint.d.ts +0 -0
  180. /package/dist/{src/security → security}/GoogleWebRisk.d.ts +0 -0
  181. /package/dist/{src/security → security}/HSTS.d.ts +0 -0
  182. /package/dist/{src/security → security}/HTTPS.d.ts +0 -0
  183. /package/dist/{src/security → security}/HTTPVersion.d.ts +0 -0
  184. /package/dist/{src/security → security}/PermissionsPolicy.d.ts +0 -0
  185. /package/dist/{src/security → security}/Redirect.d.ts +0 -0
  186. /package/dist/{src/security → security}/ReferrerPolicy.d.ts +0 -0
  187. /package/dist/{src/security → security}/RobotsTXT.d.ts +0 -0
  188. /package/dist/{src/security → security}/SSL.d.ts +0 -0
  189. /package/dist/{src/security → security}/XFrameOptions.d.ts +0 -0
  190. /package/dist/{src/security → security}/XXSSProtection.d.ts +0 -0
  191. /package/dist/{src/security → security}/__TESTS__/ContentSecurityPolicy.test.d.ts +0 -0
  192. /package/dist/{src/security → security}/__TESTS__/FingerPrint.test.d.ts +0 -0
  193. /package/dist/{src/security → security}/__TESTS__/HSTS.test.d.ts +0 -0
  194. /package/dist/{src/security → security}/__TESTS__/HTTPS.test.d.ts +0 -0
  195. /package/dist/{src/security → security}/__TESTS__/XFrameOptions.test.d.ts +0 -0
  196. /package/dist/{src/security → security}/__TESTS__/XXSSProtection.test.d.ts +0 -0
  197. /package/dist/{src/security → security}/index.d.ts +0 -0
  198. /package/dist/{src/seo → seo}/Heading.d.ts +0 -0
  199. /package/dist/{src/seo → seo}/Robots.d.ts +0 -0
  200. /package/dist/{src/seo → seo}/Sitemap.d.ts +0 -0
  201. /package/dist/{src/seo → seo}/Title.d.ts +0 -0
  202. /package/dist/{src/seo → seo}/index.d.ts +0 -0
  203. /package/dist/{src/wordpress → wordpress}/DefaultFiles.d.ts +0 -0
  204. /package/dist/{src/wordpress → wordpress}/Generator.d.ts +0 -0
  205. /package/dist/{src/wordpress → wordpress}/index.d.ts +0 -0
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const Test_1 = __importDefault(require("../Test"));
7
+ const request_1 = __importDefault(require("../request"));
8
+ const logger_1 = __importDefault(require("../logger"));
9
+ class Cookies extends Test_1.default {
10
+ name = 'Cookies';
11
+ async test({ url }) {
12
+ logger_1.default.info('Starting Cookies test...');
13
+ const response = await request_1.default.get(url);
14
+ let subChecks = [];
15
+ if (Object.prototype.hasOwnProperty.call(response.headers, 'set-cookie')) {
16
+ const cookies = response.headers['set-cookie'];
17
+ subChecks = this.checkCookies(cookies);
18
+ }
19
+ return {
20
+ status: subChecks.some(check => check.status === 'WARNING') ? 'WARNING' : 'SUCCESS',
21
+ title: 'Cookies',
22
+ description: '',
23
+ results: subChecks,
24
+ };
25
+ }
26
+ checkCookies(cookies) {
27
+ const regx = new RegExp('.*(secure; HttpOnly)$', 'i');
28
+ return cookies.map((cookie) => {
29
+ if (!regx.test(cookie)) {
30
+ return {
31
+ status: 'WARNING',
32
+ title: cookie.substr(0, cookie.indexOf('=')),
33
+ description: '',
34
+ };
35
+ }
36
+ return {
37
+ status: 'SUCCESS',
38
+ title: cookie.substr(0, cookie.indexOf('=')),
39
+ description: '',
40
+ };
41
+ });
42
+ }
43
+ }
44
+ exports.default = Cookies;
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const Test_1 = __importDefault(require("../Test"));
7
+ const request_1 = __importDefault(require("../request"));
8
+ const logger_1 = __importDefault(require("../logger"));
9
+ /**
10
+ *
11
+ * @see https://www.owasp.org/index.php/Fingerprint_Web_Server_(OTG-INFO-002)
12
+ * @see https://www.owasp.org/index.php/Fingerprint_Web_Application_Framework_(OTG-INFO-008)
13
+ */
14
+ class FingerPrint extends Test_1.default {
15
+ name = 'FingerPrint';
16
+ knownHeaders = ['x-powered-by', 'x-generator', 'server'];
17
+ async test({ url }) {
18
+ logger_1.default.info('Starting FingerPrint test...');
19
+ const response = await request_1.default.get(url);
20
+ if (this.hasFingerPrintHeader(response.headers)) {
21
+ return {
22
+ status: 'ERROR',
23
+ title: 'FingerPrint',
24
+ description: 'Response headers includes at least one of finger print headers!',
25
+ };
26
+ }
27
+ return {
28
+ status: 'SUCCESS',
29
+ title: 'FingerPrint',
30
+ description: `Response headers don't inlcude any of finger print headers.`,
31
+ };
32
+ }
33
+ hasFingerPrintHeader(headers) {
34
+ return Object.keys(headers).filter((header) => this.knownHeaders.includes(header)).length > 0;
35
+ }
36
+ }
37
+ exports.default = FingerPrint;
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const web_risk_1 = require("@google-cloud/web-risk");
7
+ const Test_1 = __importDefault(require("../Test"));
8
+ const logger_1 = __importDefault(require("../logger"));
9
+ /**
10
+ *
11
+ * @see https://cloud.google.com/web-risk
12
+ * @see https://safebrowsing.google.com
13
+ * @see https://transparencyreport.google.com/safe-browsing/search
14
+ */
15
+ class GoogleWebRisk extends Test_1.default {
16
+ name = 'GoogleWebRisk';
17
+ async test({ url }) {
18
+ logger_1.default.info('Starting Google Web Risk test...');
19
+ const client = new web_risk_1.WebRiskServiceClient();
20
+ const request = {
21
+ uri: url,
22
+ threatTypes: [
23
+ web_risk_1.protos.google.cloud.webrisk.v1.ThreatType.MALWARE,
24
+ web_risk_1.protos.google.cloud.webrisk.v1.ThreatType.SOCIAL_ENGINEERING,
25
+ web_risk_1.protos.google.cloud.webrisk.v1.ThreatType.UNWANTED_SOFTWARE,
26
+ ],
27
+ };
28
+ const response = await client.searchUris(request);
29
+ const { threat } = response[0];
30
+ if (threat !== null) {
31
+ return {
32
+ status: 'ERROR',
33
+ title: this.name,
34
+ description: `This url contains ${threat.threatTypes.join(', ').toLowerCase()}!`,
35
+ };
36
+ }
37
+ return {
38
+ status: 'SUCCESS',
39
+ title: this.name,
40
+ description: 'This URL is safe.',
41
+ };
42
+ }
43
+ }
44
+ exports.default = GoogleWebRisk;
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const Test_1 = __importDefault(require("../Test"));
7
+ const request_1 = __importDefault(require("../request"));
8
+ const logger_1 = __importDefault(require("../logger"));
9
+ /**
10
+ * HTTP Strict Transport Security
11
+ *
12
+ * Recommended value is at least one year (31536000).
13
+ *
14
+ * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security
15
+ * @see https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security
16
+ */
17
+ class HSTS extends Test_1.default {
18
+ name = 'HSTS';
19
+ minValue = 31536000;
20
+ async test({ url }) {
21
+ logger_1.default.info('Starting HSTS test...');
22
+ const response = await request_1.default.get(url);
23
+ if (!Object.prototype.hasOwnProperty.call(response.headers, 'strict-transport-security')) {
24
+ return {
25
+ status: 'ERROR',
26
+ title: 'HSTS',
27
+ description: 'The strict-transport-security header is not present!',
28
+ };
29
+ }
30
+ const attributes = response.headers['strict-transport-security'].replace(' ', '').split(';');
31
+ const maxAge = attributes.filter((attribute) => {
32
+ return attribute.startsWith('max-age');
33
+ }).shift().replace('max-age=', '');
34
+ if (parseInt(maxAge, 10) < this.minValue) {
35
+ return {
36
+ status: 'ERROR',
37
+ title: 'HSTS',
38
+ description: `The value of strict-transport-security header is ${maxAge}. Minimum value is ${this.minValue}!`,
39
+ };
40
+ }
41
+ return {
42
+ status: 'SUCCESS',
43
+ title: 'HSTS',
44
+ description: `The value of strict-transport-security header is ${maxAge}.`,
45
+ };
46
+ }
47
+ }
48
+ exports.default = HSTS;
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const Test_1 = __importDefault(require("../Test"));
7
+ const request_1 = __importDefault(require("../request"));
8
+ const logger_1 = __importDefault(require("../logger"));
9
+ /**
10
+ * Hypertext Transfer Protocol Secure
11
+ *
12
+ * The script first transform the url to be unsecure
13
+ * and then make the request. The answer has to be
14
+ * redirect to secure version.
15
+ *
16
+ * Some sites requires www (or requires version without wwww)
17
+ * and if the request is not as desired, it first redirects
18
+ * to desired version (without https) and then again redirects
19
+ * to version with https. This is also wrong.
20
+ *
21
+ * @see https://en.wikipedia.org/wiki/HTTPS
22
+ */
23
+ class HTTPS extends Test_1.default {
24
+ name = 'HTTPS';
25
+ async test({ url }) {
26
+ logger_1.default.info('Starting HTTPS test...');
27
+ const unsecureUrl = this.toHttp(url);
28
+ logger_1.default.debug('Unsecure URL', unsecureUrl);
29
+ const response = await request_1.default.get(unsecureUrl, { redirect: 'manual' });
30
+ logger_1.default.debug('Response', { statusCode: response.statusCode, headers: response.headers });
31
+ if (!this.isRedirect(response)) {
32
+ return {
33
+ status: 'ERROR',
34
+ title: 'HTTPS',
35
+ metadata: {
36
+ statusCode: response.statusCode,
37
+ unsecureUrl,
38
+ finalUrl: response.finalUrl,
39
+ },
40
+ description: `Request to not secure url returned ${response.statusCode}!`,
41
+ };
42
+ }
43
+ if (!this.isRedirectSecure(response)) {
44
+ return {
45
+ status: 'ERROR',
46
+ title: 'HTTPS',
47
+ metadata: {
48
+ statusCode: response.statusCode,
49
+ unsecureUrl,
50
+ finalUrl: response.finalUrl,
51
+ },
52
+ description: `Request to not secure url returned non-secure redirect url ${response.headers.location}!`,
53
+ };
54
+ }
55
+ return {
56
+ status: 'SUCCESS',
57
+ title: 'HTTPS',
58
+ metadata: {
59
+ statusCode: response.statusCode,
60
+ unsecureUrl,
61
+ finalUrl: response.finalUrl,
62
+ },
63
+ description: `Request to not secure url responded with status code ${response.statusCode} and redirect url ${response.headers.location}.`,
64
+ };
65
+ }
66
+ /* eslint-disable-next-line @typescript-eslint/no-explicit-any */
67
+ isRedirect(response) {
68
+ return Math.floor(response.statusCode / 100) === 3 && 'location' in response.headers;
69
+ }
70
+ /* eslint-disable-next-line @typescript-eslint/no-explicit-any */
71
+ isRedirectSecure(response) {
72
+ return response.headers.location.startsWith('https');
73
+ }
74
+ toHttp(url) {
75
+ return url.replace('https://', 'http://');
76
+ }
77
+ }
78
+ exports.default = HTTPS;
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const Test_1 = __importDefault(require("../Test"));
7
+ const request_1 = __importDefault(require("../request"));
8
+ const logger_1 = __importDefault(require("../logger"));
9
+ /**
10
+ *
11
+ * @see https://en.wikipedia.org/wiki/HTTP/2
12
+ * @see https://en.wikipedia.org/wiki/HTTP/3
13
+ */
14
+ class HTTPVersion extends Test_1.default {
15
+ name = 'HTTP Version';
16
+ async test({ url }) {
17
+ logger_1.default.info('Starting HTTPVersion test...');
18
+ const response = await request_1.default.get(url);
19
+ if (Object.prototype.hasOwnProperty.call(response.headers, 'upgrade')) {
20
+ const attributes = response.headers['upgrade'].replace(' ', '').split(',');
21
+ const h2 = attributes.indexOf('h2') > -1;
22
+ if (h2) {
23
+ return {
24
+ status: 'WARNING',
25
+ title: 'HTTP/2',
26
+ description: 'The current HTTP version is 2. Can be upgraded to 3.',
27
+ };
28
+ }
29
+ }
30
+ if (Object.prototype.hasOwnProperty.call(response.headers, 'alt-svc')) {
31
+ const attributes = response.headers['alt-svc'].replace(' ', '').split(',');
32
+ const h3 = attributes.find(a => a.includes('h3'));
33
+ if (typeof h3 !== 'undefined') {
34
+ if (h3) {
35
+ return {
36
+ status: 'SUCCESS',
37
+ title: 'HTTP/3',
38
+ description: 'The value of HTTP/3 header is present.',
39
+ };
40
+ }
41
+ }
42
+ }
43
+ return {
44
+ status: 'ERROR',
45
+ title: 'HTTP/1',
46
+ description: 'The current HTTP version is 1. Should be upgraded at least to 2!',
47
+ };
48
+ }
49
+ }
50
+ exports.default = HTTPVersion;
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const Test_1 = __importDefault(require("../Test"));
7
+ const request_1 = __importDefault(require("../request"));
8
+ const logger_1 = __importDefault(require("../logger"));
9
+ /**
10
+ *
11
+ * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Feature-Policy
12
+ */
13
+ class PermissionsPolicy extends Test_1.default {
14
+ name = 'Permissions-Policy';
15
+ async test({ url }) {
16
+ logger_1.default.info('Starting PermissionsPolicy test...');
17
+ const response = await request_1.default.get(url);
18
+ if (!Object.prototype.hasOwnProperty.call(response.headers, 'permissions-policy')) {
19
+ return {
20
+ status: 'ERROR',
21
+ title: 'Permissions-Policy',
22
+ description: 'Response headers does not contain permissions-policy header!',
23
+ };
24
+ }
25
+ const permissionsArray = ['accelerometer', 'geolocation', 'midi', 'notifications', 'push', 'sync-xhr',
26
+ 'microphone', 'camera', 'magnetometer', 'gyroscope', 'speaker', 'vibrate', 'fullscreen', 'payment', 'usb'];
27
+ const attributesList = response.headers['permissions-policy'];
28
+ const subChecks = this.checkPermissions(permissionsArray, attributesList);
29
+ return {
30
+ status: subChecks.some(check => check.status === 'WARNING') ? 'WARNING' : 'SUCCESS',
31
+ title: 'Permissions-Policy',
32
+ description: '',
33
+ results: subChecks,
34
+ };
35
+ }
36
+ checkPermissions(permissions, attributes) {
37
+ return permissions.map((permission) => {
38
+ if (!attributes.includes(permission)) {
39
+ return {
40
+ status: 'WARNING',
41
+ title: permission,
42
+ description: `Permission ${permission} is missing.`,
43
+ };
44
+ }
45
+ return {
46
+ status: 'SUCCESS',
47
+ title: permission,
48
+ description: `Permission ${permission} is present.`,
49
+ };
50
+ });
51
+ }
52
+ }
53
+ exports.default = PermissionsPolicy;
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const Test_1 = __importDefault(require("../Test"));
7
+ const request_1 = __importDefault(require("../request"));
8
+ const logger_1 = __importDefault(require("../logger"));
9
+ class Redirect extends Test_1.default {
10
+ name = 'Redirect';
11
+ async test({ url }) {
12
+ logger_1.default.info('Starting Redirect test...');
13
+ const response = await request_1.default.get(url, { redirect: 'follow' });
14
+ if (response.response.redirected) {
15
+ const originalUrl = new URL(url);
16
+ const finalUrl = new URL(response.response.url);
17
+ if (originalUrl.hostname !== finalUrl.hostname) {
18
+ return {
19
+ status: 'ERROR',
20
+ title: this.name,
21
+ description: 'URL redirects to different hostname!',
22
+ };
23
+ }
24
+ return {
25
+ status: 'SUCCESS',
26
+ title: this.name,
27
+ description: 'Request was redirected but to the same hostname.',
28
+ };
29
+ }
30
+ return {
31
+ status: 'SUCCESS',
32
+ title: this.name,
33
+ description: 'Request was not redirected.',
34
+ };
35
+ }
36
+ }
37
+ exports.default = Redirect;
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const Test_1 = __importDefault(require("../Test"));
7
+ const request_1 = __importDefault(require("../request"));
8
+ const logger_1 = __importDefault(require("../logger"));
9
+ /**
10
+ *
11
+ * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy
12
+ */
13
+ class ReferrerPolicy extends Test_1.default {
14
+ name = 'Referrer-Policy';
15
+ async test({ url }) {
16
+ logger_1.default.info('Starting ReferrerPolicy test...');
17
+ const response = await request_1.default.get(url);
18
+ if (!Object.prototype.hasOwnProperty.call(response.headers, 'referrer-policy')) {
19
+ return {
20
+ status: 'WARNING',
21
+ title: 'Referrer-Policy',
22
+ description: 'Response headers does not contain referrer-policy header!',
23
+ };
24
+ }
25
+ return {
26
+ status: 'SUCCESS',
27
+ title: 'Referrer-Policy',
28
+ description: `The value of referrer-policy header is ${response.headers['referrer-policy']}.`,
29
+ };
30
+ }
31
+ }
32
+ exports.default = ReferrerPolicy;
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const Test_1 = __importDefault(require("../Test"));
7
+ const request_1 = __importDefault(require("../request"));
8
+ const logger_1 = __importDefault(require("../logger"));
9
+ class RobotsTXT extends Test_1.default {
10
+ name = 'Robots.txt';
11
+ async test({ url }) {
12
+ logger_1.default.info('Starting robotstxt test...');
13
+ const response = await request_1.default.get(url + '/robots.txt');
14
+ if (response !== null && response.statusCode === 200) {
15
+ return {
16
+ status: 'SUCCESS',
17
+ title: 'Robots.txt',
18
+ description: 'Site does contain robots.txt',
19
+ };
20
+ }
21
+ return {
22
+ status: 'ERROR',
23
+ title: 'Robots.txt',
24
+ description: 'Site does not contain robots.txt',
25
+ };
26
+ }
27
+ }
28
+ exports.default = RobotsTXT;
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const ssl_checker_1 = __importDefault(require("ssl-checker"));
7
+ const Test_1 = __importDefault(require("../Test"));
8
+ const logger_1 = __importDefault(require("../logger"));
9
+ class SSL extends Test_1.default {
10
+ name = 'SSL';
11
+ async test({ url }) {
12
+ logger_1.default.info('Starting SSL test...');
13
+ const hostname = (new URL(url)).hostname;
14
+ const sslDetails = await (0, ssl_checker_1.default)(hostname);
15
+ if (!sslDetails.valid) {
16
+ return {
17
+ status: 'ERROR',
18
+ title: this.name,
19
+ description: 'SSL certificate is not valid!',
20
+ };
21
+ }
22
+ if (sslDetails.daysRemaining <= 7) {
23
+ return {
24
+ status: 'WARNING',
25
+ title: this.name,
26
+ description: 'SSL certificate is valid for 7 or less days!',
27
+ };
28
+ }
29
+ return {
30
+ status: 'SUCCESS',
31
+ title: this.name,
32
+ description: `SSL certificate is valid until ${sslDetails.validTo}.`,
33
+ };
34
+ }
35
+ }
36
+ exports.default = SSL;
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const Test_1 = __importDefault(require("../Test"));
7
+ const request_1 = __importDefault(require("../request"));
8
+ const logger_1 = __importDefault(require("../logger"));
9
+ /**
10
+ *
11
+ * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options
12
+ */
13
+ class XFrameOptions extends Test_1.default {
14
+ name = 'X-Frame-Options';
15
+ async test({ url }) {
16
+ logger_1.default.info('Starting X-Frame-Options test...');
17
+ const response = await request_1.default.get(url);
18
+ if (!Object.prototype.hasOwnProperty.call(response.headers, 'x-frame-options')) {
19
+ return {
20
+ status: 'ERROR',
21
+ title: 'X-Frame-Options',
22
+ description: 'Response headers does not contain x-frame-options header!',
23
+ };
24
+ }
25
+ return {
26
+ status: 'SUCCESS',
27
+ title: 'X-Frame-Options',
28
+ description: `The value of x-frame-options header is ${response.headers['x-frame-options']}.`,
29
+ };
30
+ }
31
+ }
32
+ exports.default = XFrameOptions;
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const Test_1 = __importDefault(require("../Test"));
7
+ const request_1 = __importDefault(require("../request"));
8
+ const logger_1 = __importDefault(require("../logger"));
9
+ /**
10
+ *
11
+ * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection
12
+ */
13
+ class XXSSProtection extends Test_1.default {
14
+ name = 'X-XSS-Protection';
15
+ async test({ url }) {
16
+ logger_1.default.info('Starting X-XSS-Protection test...');
17
+ const response = await request_1.default.get(url);
18
+ if (!Object.prototype.hasOwnProperty.call(response.headers, 'x-xss-protection')) {
19
+ return {
20
+ status: 'ERROR',
21
+ title: 'X-XSS-Protection',
22
+ description: 'Response headers does not contain x-xss-protection header!',
23
+ };
24
+ }
25
+ return {
26
+ status: 'SUCCESS',
27
+ title: 'X-XSS-Protection',
28
+ description: `The value of x-xss-protection header is ${response.headers['x-xss-protection']}.`,
29
+ };
30
+ }
31
+ }
32
+ exports.default = XXSSProtection;
@@ -1,23 +1,14 @@
1
1
  "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
2
  var __importDefault = (this && this.__importDefault) || function (mod) {
12
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
13
4
  };
14
5
  Object.defineProperty(exports, "__esModule", { value: true });
15
6
  const ContentSecurityPolicy_1 = __importDefault(require("../ContentSecurityPolicy"));
16
7
  const request_1 = __importDefault(require("../../request"));
17
- test('Content-Security-Policy test with correct header', () => __awaiter(void 0, void 0, void 0, function* () {
8
+ test('Content-Security-Policy test with correct header', async () => {
18
9
  const pentest = new ContentSecurityPolicy_1.default();
19
10
  /* eslint-disable-next-line @typescript-eslint/no-explicit-any */
20
- const mock = jest.spyOn(request_1.default, 'get').mockImplementation(() => __awaiter(void 0, void 0, void 0, function* () {
11
+ const mock = jest.spyOn(request_1.default, 'get').mockImplementation(async () => {
21
12
  return new Promise((resolve) => {
22
13
  resolve({
23
14
  headers: {
@@ -25,22 +16,22 @@ test('Content-Security-Policy test with correct header', () => __awaiter(void 0,
25
16
  },
26
17
  });
27
18
  });
28
- }));
29
- const result = yield pentest.run({ url: 'https://juffalow.com' });
19
+ });
20
+ const result = await pentest.run({ url: 'https://juffalow.com' });
30
21
  expect(result.status).toEqual('SUCCESS');
31
22
  mock.mockRestore();
32
- }));
33
- test('Content-Security-Policy test with missing Content-Security-Policy header', () => __awaiter(void 0, void 0, void 0, function* () {
23
+ });
24
+ test('Content-Security-Policy test with missing Content-Security-Policy header', async () => {
34
25
  const pentest = new ContentSecurityPolicy_1.default();
35
26
  /* eslint-disable-next-line @typescript-eslint/no-explicit-any */
36
- const mock = jest.spyOn(request_1.default, 'get').mockImplementation(() => __awaiter(void 0, void 0, void 0, function* () {
27
+ const mock = jest.spyOn(request_1.default, 'get').mockImplementation(async () => {
37
28
  return new Promise((resolve) => {
38
29
  resolve({
39
30
  headers: {}
40
31
  });
41
32
  });
42
- }));
43
- const result = yield pentest.run({ url: 'https://juffalow.com' });
33
+ });
34
+ const result = await pentest.run({ url: 'https://juffalow.com' });
44
35
  expect(result.status).toEqual('ERROR');
45
36
  mock.mockRestore();
46
- }));
37
+ });