pentest-tool-lite 3.9.3 → 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.
- package/LICENSE +19 -0
- package/{src → dist}/Pentest.d.ts +1 -0
- package/dist/Pentest.js +46 -0
- package/{src → dist}/Test.d.ts +1 -0
- package/{src → dist}/Test.js +12 -27
- package/{src → dist}/commands/Sitemap.d.ts +4 -4
- package/dist/commands/Sitemap.js +79 -0
- package/dist/dns/A.js +49 -0
- package/dist/dns/DMARC.js +59 -0
- package/dist/dns/NS.js +36 -0
- package/dist/dns/RegistrationDate.js +39 -0
- package/dist/dns/index.js +47 -0
- package/dist/functions/findEvery.d.ts +2 -0
- package/{src → dist}/functions/getDuplicates.js +1 -0
- package/dist/functions/getGenerator.d.ts +2 -0
- package/{src → dist}/functions/getGenerator.js +3 -0
- package/{src → dist}/functions/getHeading.js +4 -0
- package/{src → dist}/functions/getImages.js +1 -0
- package/dist/functions/getObject.d.ts +2 -0
- package/{src → dist}/functions/getScripts.js +1 -0
- package/{src → dist}/functions/getStylesheets.js +1 -0
- package/{src → dist}/functions/getTitle.js +1 -0
- package/{src → dist}/functions/parseHtml.js +4 -0
- package/dist/functions/parseSitemap.js +12 -0
- package/dist/html/Anchor.js +56 -0
- package/dist/html/CSS.js +92 -0
- package/dist/html/DuplicateId.js +35 -0
- package/dist/html/Generator.js +31 -0
- package/dist/html/Image.js +79 -0
- package/dist/html/JavaScript.js +107 -0
- package/{src → dist}/html/__TESTS__/Generator.test.js +12 -19
- package/dist/html/index.js +51 -0
- package/{src → dist}/index +39 -28
- package/dist/logger/Console.d.ts +14 -0
- package/{src → dist}/logger/Console.js +13 -15
- package/dist/metadata/HTML.d.ts +6 -0
- package/dist/metadata/HTML.js +26 -0
- package/dist/metadata/Markdown.d.ts +6 -0
- package/dist/metadata/Markdown.js +28 -0
- package/dist/metadata/ResponseTime.d.ts +6 -0
- package/dist/metadata/ResponseTime.js +25 -0
- package/dist/metadata/index.d.ts +6 -0
- package/dist/metadata/index.js +45 -0
- package/{src → dist}/request/NodeFetch.d.ts +2 -0
- package/dist/request/NodeFetch.js +58 -0
- package/{src → dist}/request/Request.d.ts +2 -0
- package/dist/request/cache/BlackHoleCache.d.ts +7 -0
- package/{src → dist}/request/cache/BlackHoleCache.js +4 -3
- package/{src → dist}/request/cache/UnlimitedCache.d.ts +1 -2
- package/{src → dist}/request/cache/UnlimitedCache.js +4 -0
- package/dist/request/index.js +11 -0
- package/dist/security/ContentEncoding.js +44 -0
- package/dist/security/ContentSecurityPolicy.js +32 -0
- package/dist/security/Cookies.js +44 -0
- package/dist/security/FingerPrint.js +37 -0
- package/dist/security/GoogleWebRisk.js +44 -0
- package/dist/security/HSTS.js +48 -0
- package/dist/security/HTTPS.js +78 -0
- package/dist/security/HTTPVersion.js +50 -0
- package/dist/security/PermissionsPolicy.js +53 -0
- package/dist/security/Redirect.d.ts +6 -0
- package/dist/security/Redirect.js +37 -0
- package/dist/security/ReferrerPolicy.js +32 -0
- package/dist/security/RobotsTXT.js +28 -0
- package/dist/security/SSL.js +36 -0
- package/dist/security/XFrameOptions.js +32 -0
- package/dist/security/XXSSProtection.js +32 -0
- package/{src → dist}/security/__TESTS__/ContentSecurityPolicy.test.js +12 -19
- package/{src → dist}/security/__TESTS__/FingerPrint.test.js +12 -19
- package/{src → dist}/security/__TESTS__/HSTS.test.js +18 -24
- package/{src → dist}/security/__TESTS__/HTTPS.test.js +18 -24
- package/dist/security/__TESTS__/XFrameOptions.test.js +37 -0
- package/{src → dist}/security/__TESTS__/XXSSProtection.test.js +12 -19
- package/{src → dist}/security/index.js +22 -35
- package/dist/seo/Heading.js +51 -0
- package/dist/seo/Robots.js +21 -0
- package/dist/seo/Sitemap.js +32 -0
- package/dist/seo/Title.js +44 -0
- package/dist/seo/index.js +47 -0
- package/dist/wordpress/DefaultFiles.js +50 -0
- package/dist/wordpress/Generator.js +58 -0
- package/dist/wordpress/index.js +43 -0
- package/package.json +68 -59
- package/src/Pentest.js +0 -43
- package/src/commands/Sitemap.js +0 -94
- package/src/dns/A.js +0 -64
- package/src/dns/DMARC.js +0 -72
- package/src/dns/NS.js +0 -52
- package/src/dns/RegistrationDate.js +0 -55
- package/src/dns/index.js +0 -58
- package/src/functions/findEvery.d.ts +0 -2
- package/src/functions/getGenerator.d.ts +0 -2
- package/src/functions/getObject.d.ts +0 -2
- package/src/functions/parseSitemap.js +0 -22
- package/src/html/Anchor.js +0 -71
- package/src/html/CSS.js +0 -104
- package/src/html/DuplicateId.js +0 -49
- package/src/html/Generator.js +0 -45
- package/src/html/Image.js +0 -92
- package/src/html/JavaScript.js +0 -118
- package/src/html/index.js +0 -62
- package/src/logger/Console.d.ts +0 -14
- package/src/request/NodeFetch.js +0 -49
- package/src/request/cache/BlackHoleCache.d.ts +0 -8
- package/src/request/cache/Cache.d.ts +0 -6
- package/src/request/cache/Cache.js +0 -2
- package/src/request/index.js +0 -7
- package/src/security/ContentEncoding.js +0 -58
- package/src/security/ContentSecurityPolicy.js +0 -46
- package/src/security/Cookies.js +0 -58
- package/src/security/FingerPrint.js +0 -51
- package/src/security/GoogleWebRisk.js +0 -58
- package/src/security/HSTS.js +0 -62
- package/src/security/HTTPS.js +0 -73
- package/src/security/HTTPVersion.js +0 -64
- package/src/security/PermissionsPolicy.js +0 -67
- package/src/security/ReferrerPolicy.js +0 -46
- package/src/security/RobotsTXT.js +0 -42
- package/src/security/SSL.js +0 -50
- package/src/security/XFrameOptions.js +0 -46
- package/src/security/XXSSProtection.js +0 -46
- package/src/security/__TESTS__/XFrameOptions.test.js +0 -44
- package/src/seo/Heading.js +0 -65
- package/src/seo/Robots.js +0 -35
- package/src/seo/Sitemap.js +0 -46
- package/src/seo/Title.js +0 -58
- package/src/seo/index.js +0 -58
- package/src/types/Sitemap.d.ts +0 -9
- package/src/types/Sitemap.js +0 -0
- package/src/wordpress/DefaultFiles.js +0 -66
- package/src/wordpress/Generator.js +0 -75
- package/src/wordpress/index.js +0 -54
- /package/{README.md → dist/README.md} +0 -0
- /package/{src → dist}/config.d.ts +0 -0
- /package/{src → dist}/config.js +0 -0
- /package/{src → dist}/dns/A.d.ts +0 -0
- /package/{src → dist}/dns/DMARC.d.ts +0 -0
- /package/{src → dist}/dns/NS.d.ts +0 -0
- /package/{src → dist}/dns/RegistrationDate.d.ts +0 -0
- /package/{src → dist}/dns/index.d.ts +0 -0
- /package/{src → dist}/functions/findEvery.js +0 -0
- /package/{src → dist}/functions/getAnchors.d.ts +0 -0
- /package/{src → dist}/functions/getAnchors.js +0 -0
- /package/{src → dist}/functions/getDomain.d.ts +0 -0
- /package/{src → dist}/functions/getDomain.js +0 -0
- /package/{src → dist}/functions/getDuplicates.d.ts +0 -0
- /package/{src → dist}/functions/getHeading.d.ts +0 -0
- /package/{src → dist}/functions/getImages.d.ts +0 -0
- /package/{src → dist}/functions/getObject.js +0 -0
- /package/{src → dist}/functions/getScripts.d.ts +0 -0
- /package/{src → dist}/functions/getStylesheets.d.ts +0 -0
- /package/{src → dist}/functions/getTitle.d.ts +0 -0
- /package/{src → dist}/functions/index.d.ts +0 -0
- /package/{src → dist}/functions/index.js +0 -0
- /package/{src → dist}/functions/parseHtml.d.ts +0 -0
- /package/{src → dist}/functions/parseSitemap.d.ts +0 -0
- /package/{src → dist}/functions/parseXml.d.ts +0 -0
- /package/{src → dist}/functions/parseXml.js +0 -0
- /package/{src → dist}/html/Anchor.d.ts +0 -0
- /package/{src → dist}/html/CSS.d.ts +0 -0
- /package/{src → dist}/html/DuplicateId.d.ts +0 -0
- /package/{src → dist}/html/Generator.d.ts +0 -0
- /package/{src → dist}/html/Image.d.ts +0 -0
- /package/{src → dist}/html/JavaScript.d.ts +0 -0
- /package/{src → dist}/html/__TESTS__/Generator.test.d.ts +0 -0
- /package/{src → dist}/html/index.d.ts +0 -0
- /package/{src → dist}/index.d.ts +0 -0
- /package/{src → dist}/logger/Logger.d.ts +0 -0
- /package/{src → dist}/logger/Logger.js +0 -0
- /package/{src → dist}/logger/index.d.ts +0 -0
- /package/{src → dist}/logger/index.js +0 -0
- /package/{src → dist}/report/CommandLine.d.ts +0 -0
- /package/{src → dist}/report/CommandLine.js +0 -0
- /package/{src → dist}/report/Json.d.ts +0 -0
- /package/{src → dist}/report/Json.js +0 -0
- /package/{src → dist}/report/Report.d.ts +0 -0
- /package/{src → dist}/report/Report.js +0 -0
- /package/{src → dist}/report/Symbols.d.ts +0 -0
- /package/{src → dist}/report/Symbols.js +0 -0
- /package/{src → dist}/report/index.d.ts +0 -0
- /package/{src → dist}/report/index.js +0 -0
- /package/{src → dist}/request/Request.js +0 -0
- /package/{src → dist}/request/index.d.ts +0 -0
- /package/{src → dist}/security/ContentEncoding.d.ts +0 -0
- /package/{src → dist}/security/ContentSecurityPolicy.d.ts +0 -0
- /package/{src → dist}/security/Cookies.d.ts +0 -0
- /package/{src → dist}/security/FingerPrint.d.ts +0 -0
- /package/{src → dist}/security/GoogleWebRisk.d.ts +0 -0
- /package/{src → dist}/security/HSTS.d.ts +0 -0
- /package/{src → dist}/security/HTTPS.d.ts +0 -0
- /package/{src → dist}/security/HTTPVersion.d.ts +0 -0
- /package/{src → dist}/security/PermissionsPolicy.d.ts +0 -0
- /package/{src → dist}/security/ReferrerPolicy.d.ts +0 -0
- /package/{src → dist}/security/RobotsTXT.d.ts +0 -0
- /package/{src → dist}/security/SSL.d.ts +0 -0
- /package/{src → dist}/security/XFrameOptions.d.ts +0 -0
- /package/{src → dist}/security/XXSSProtection.d.ts +0 -0
- /package/{src → dist}/security/__TESTS__/ContentSecurityPolicy.test.d.ts +0 -0
- /package/{src → dist}/security/__TESTS__/FingerPrint.test.d.ts +0 -0
- /package/{src → dist}/security/__TESTS__/HSTS.test.d.ts +0 -0
- /package/{src → dist}/security/__TESTS__/HTTPS.test.d.ts +0 -0
- /package/{src → dist}/security/__TESTS__/XFrameOptions.test.d.ts +0 -0
- /package/{src → dist}/security/__TESTS__/XXSSProtection.test.d.ts +0 -0
- /package/{src → dist}/security/index.d.ts +0 -0
- /package/{src → dist}/seo/Heading.d.ts +0 -0
- /package/{src → dist}/seo/Robots.d.ts +0 -0
- /package/{src → dist}/seo/Sitemap.d.ts +0 -0
- /package/{src → dist}/seo/Title.d.ts +0 -0
- /package/{src → dist}/seo/index.d.ts +0 -0
- /package/{src → dist}/wordpress/DefaultFiles.d.ts +0 -0
- /package/{src → dist}/wordpress/Generator.d.ts +0 -0
- /package/{src → dist}/wordpress/index.d.ts +0 -0
package/dist/html/CSS.js
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
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 csso_1 = __importDefault(require("csso"));
|
|
7
|
+
const Test_1 = __importDefault(require("../Test"));
|
|
8
|
+
const request_1 = __importDefault(require("../request"));
|
|
9
|
+
const logger_1 = __importDefault(require("../logger"));
|
|
10
|
+
const functions_1 = require("../functions");
|
|
11
|
+
class CSS extends Test_1.default {
|
|
12
|
+
name = 'CSS';
|
|
13
|
+
async test({ url }) {
|
|
14
|
+
logger_1.default.info(`Starting ${this.constructor.name} test...`);
|
|
15
|
+
const response = await request_1.default.get(url);
|
|
16
|
+
const html = await (0, functions_1.parseHtml)(response);
|
|
17
|
+
const stylesheets = (0, functions_1.getStylesheets)(html);
|
|
18
|
+
const subTests = await this.check(stylesheets);
|
|
19
|
+
return {
|
|
20
|
+
status: this.getStatus(subTests.map(test => test.status)),
|
|
21
|
+
title: this.constructor.name,
|
|
22
|
+
description: '',
|
|
23
|
+
results: subTests,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
async check(stylesheets) {
|
|
27
|
+
const results = [];
|
|
28
|
+
for (const stylesheet of stylesheets) {
|
|
29
|
+
const filename = stylesheet.substring(stylesheet.lastIndexOf('/') + 1);
|
|
30
|
+
logger_1.default.verbose(`Checking ${filename}...`);
|
|
31
|
+
const result = await request_1.default.get(stylesheet);
|
|
32
|
+
const isFileAvailabe = {
|
|
33
|
+
status: this.isFileAvailable(result) ? 'SUCCESS' : 'ERROR',
|
|
34
|
+
title: 'Available',
|
|
35
|
+
description: '',
|
|
36
|
+
};
|
|
37
|
+
const isCached = {
|
|
38
|
+
status: this.isCached(result) ? 'SUCCESS' : 'ERROR',
|
|
39
|
+
title: 'Cached',
|
|
40
|
+
description: '',
|
|
41
|
+
};
|
|
42
|
+
const hasXContentTypeOptionsHeader = {
|
|
43
|
+
status: this.hasXContentTypeOptionsHeader(result) ? 'SUCCESS' : 'WARNING',
|
|
44
|
+
title: 'X-Content-Type-Options',
|
|
45
|
+
description: '',
|
|
46
|
+
};
|
|
47
|
+
const isMinified = {
|
|
48
|
+
status: this.isMinified(result) ? 'SUCCESS' : 'WARNING',
|
|
49
|
+
title: 'Minified',
|
|
50
|
+
description: '',
|
|
51
|
+
};
|
|
52
|
+
results.push({
|
|
53
|
+
status: this.getStatus([
|
|
54
|
+
isFileAvailabe.status,
|
|
55
|
+
isCached.status,
|
|
56
|
+
hasXContentTypeOptionsHeader.status,
|
|
57
|
+
isMinified.status,
|
|
58
|
+
]), // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
59
|
+
title: filename,
|
|
60
|
+
description: '',
|
|
61
|
+
results: [
|
|
62
|
+
isFileAvailabe,
|
|
63
|
+
isCached,
|
|
64
|
+
hasXContentTypeOptionsHeader,
|
|
65
|
+
isMinified,
|
|
66
|
+
],
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
return results;
|
|
70
|
+
}
|
|
71
|
+
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
|
72
|
+
isFileAvailable(result) {
|
|
73
|
+
if (result.response.statusCode === 404 || result.response.statusCode === 500) {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
|
79
|
+
isCached(result) {
|
|
80
|
+
return result.response.headers.has('cache-control');
|
|
81
|
+
}
|
|
82
|
+
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
|
83
|
+
hasXContentTypeOptionsHeader(result) {
|
|
84
|
+
return result.response.headers.has('x-content-type-options');
|
|
85
|
+
}
|
|
86
|
+
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
|
87
|
+
isMinified(result) {
|
|
88
|
+
const r = csso_1.default.minify(result.body, { restructure: false }).css;
|
|
89
|
+
return r.length === result.body.length;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
exports.default = CSS;
|
|
@@ -0,0 +1,35 @@
|
|
|
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
|
+
const functions_1 = require("../functions");
|
|
10
|
+
class DuplicateId extends Test_1.default {
|
|
11
|
+
name = 'Duplicate ID';
|
|
12
|
+
async test({ url }) {
|
|
13
|
+
logger_1.default.info('Starting DuplicateId test...');
|
|
14
|
+
const response = await request_1.default.get(url);
|
|
15
|
+
const duplicates = await (0, functions_1.getDuplicates)(response);
|
|
16
|
+
if (duplicates.length > 0) {
|
|
17
|
+
return {
|
|
18
|
+
status: 'WARNING',
|
|
19
|
+
title: 'Duplicate IDs',
|
|
20
|
+
description: '',
|
|
21
|
+
results: duplicates.map(duplicate => ({
|
|
22
|
+
status: 'WARNING',
|
|
23
|
+
title: `<${duplicate.name} id="${duplicate.attribs.id}" ... />`,
|
|
24
|
+
description: '',
|
|
25
|
+
}))
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
return {
|
|
29
|
+
status: 'SUCCESS',
|
|
30
|
+
title: 'Duplicate IDs',
|
|
31
|
+
description: ''
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
exports.default = DuplicateId;
|
|
@@ -0,0 +1,31 @@
|
|
|
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
|
+
const functions_1 = require("../functions");
|
|
10
|
+
class Generator extends Test_1.default {
|
|
11
|
+
name = 'Generator';
|
|
12
|
+
async test({ url }) {
|
|
13
|
+
logger_1.default.info('Starting DuplicateId test...');
|
|
14
|
+
const response = await request_1.default.get(url);
|
|
15
|
+
const html = await (0, functions_1.parseHtml)(response);
|
|
16
|
+
const generators = await (0, functions_1.getGenerator)(html);
|
|
17
|
+
if (generators.length > 0) {
|
|
18
|
+
return {
|
|
19
|
+
status: 'WARNING',
|
|
20
|
+
title: this.name,
|
|
21
|
+
description: 'Page contains inmformation about its generator!',
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
return {
|
|
25
|
+
status: 'SUCCESS',
|
|
26
|
+
title: this.name,
|
|
27
|
+
description: 'Page doesn\t contain any information about its generator.',
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
exports.default = Generator;
|
|
@@ -0,0 +1,79 @@
|
|
|
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
|
+
const functions_1 = require("../functions");
|
|
10
|
+
class Image extends Test_1.default {
|
|
11
|
+
name = 'Image';
|
|
12
|
+
async test({ url }) {
|
|
13
|
+
logger_1.default.info('Starting Image test...');
|
|
14
|
+
const response = await request_1.default.get(url);
|
|
15
|
+
const html = await (0, functions_1.parseHtml)(response);
|
|
16
|
+
const images = (0, functions_1.getImages)(html);
|
|
17
|
+
const subTests = await this.checkImages(images);
|
|
18
|
+
return {
|
|
19
|
+
status: this.getStatus(subTests.map(test => test.status)),
|
|
20
|
+
title: 'Image',
|
|
21
|
+
description: '',
|
|
22
|
+
results: subTests,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
async checkImages(images) {
|
|
26
|
+
const results = [];
|
|
27
|
+
for (const image of images) {
|
|
28
|
+
const filename = image.substring(image.lastIndexOf('/') + 1);
|
|
29
|
+
logger_1.default.verbose(`Checking ${filename}...`);
|
|
30
|
+
const result = await request_1.default.get(image);
|
|
31
|
+
const isFileAvailabe = {
|
|
32
|
+
status: this.isFileAvailable(result) ? 'SUCCESS' : 'ERROR',
|
|
33
|
+
title: 'Available',
|
|
34
|
+
description: '',
|
|
35
|
+
};
|
|
36
|
+
const isCached = {
|
|
37
|
+
status: this.isCached(result) ? 'SUCCESS' : 'ERROR',
|
|
38
|
+
title: 'Cached',
|
|
39
|
+
description: '',
|
|
40
|
+
};
|
|
41
|
+
const hasXContentTypeOptionsHeader = {
|
|
42
|
+
status: this.hasXContentTypeOptionsHeader(result) ? 'SUCCESS' : 'WARNING',
|
|
43
|
+
title: 'X-Content-Type-Options',
|
|
44
|
+
description: '',
|
|
45
|
+
};
|
|
46
|
+
results.push({
|
|
47
|
+
status: this.getStatus([
|
|
48
|
+
isFileAvailabe.status,
|
|
49
|
+
isCached.status,
|
|
50
|
+
hasXContentTypeOptionsHeader.status,
|
|
51
|
+
]), // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
52
|
+
title: filename,
|
|
53
|
+
description: '',
|
|
54
|
+
results: [
|
|
55
|
+
isFileAvailabe,
|
|
56
|
+
isCached,
|
|
57
|
+
hasXContentTypeOptionsHeader,
|
|
58
|
+
],
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
return results;
|
|
62
|
+
}
|
|
63
|
+
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
|
64
|
+
isFileAvailable(result) {
|
|
65
|
+
if (result.response.statusCode === 404 || result.response.statusCode === 500) {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
|
71
|
+
isCached(result) {
|
|
72
|
+
return result.response.headers.has('cache-control');
|
|
73
|
+
}
|
|
74
|
+
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
|
75
|
+
hasXContentTypeOptionsHeader(result) {
|
|
76
|
+
return result.response.headers.has('x-content-type-options');
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
exports.default = Image;
|
|
@@ -0,0 +1,107 @@
|
|
|
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 uglify_js_1 = __importDefault(require("uglify-js"));
|
|
7
|
+
const Test_1 = __importDefault(require("../Test"));
|
|
8
|
+
const request_1 = __importDefault(require("../request"));
|
|
9
|
+
const logger_1 = __importDefault(require("../logger"));
|
|
10
|
+
const functions_1 = require("../functions");
|
|
11
|
+
class JavaScript extends Test_1.default {
|
|
12
|
+
name = 'JavaScript';
|
|
13
|
+
async test({ url }) {
|
|
14
|
+
logger_1.default.info(`Starting ${this.constructor.name} test...`);
|
|
15
|
+
const response = await request_1.default.get(url);
|
|
16
|
+
const html = await (0, functions_1.parseHtml)(response);
|
|
17
|
+
const scripts = (0, functions_1.getScripts)(html);
|
|
18
|
+
const subTests = await this.check(scripts);
|
|
19
|
+
return {
|
|
20
|
+
status: this.getStatus(subTests.map(test => test.status)),
|
|
21
|
+
title: this.constructor.name,
|
|
22
|
+
description: '',
|
|
23
|
+
results: subTests,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
async check(scripts) {
|
|
27
|
+
const results = [];
|
|
28
|
+
for (const script of scripts) {
|
|
29
|
+
const filename = script.substr(script.lastIndexOf('/') + 1);
|
|
30
|
+
logger_1.default.verbose(`Checking ${filename}...`);
|
|
31
|
+
const result = await request_1.default.get(script);
|
|
32
|
+
const isFileAvailabe = {
|
|
33
|
+
status: this.isFileAvailable(result) ? 'SUCCESS' : 'ERROR',
|
|
34
|
+
title: 'Available',
|
|
35
|
+
description: '',
|
|
36
|
+
};
|
|
37
|
+
const isCached = {
|
|
38
|
+
status: this.isCached(result) ? 'SUCCESS' : 'ERROR',
|
|
39
|
+
title: 'Cached',
|
|
40
|
+
description: '',
|
|
41
|
+
};
|
|
42
|
+
const hasXContentTypeOptionsHeader = {
|
|
43
|
+
status: this.hasXContentTypeOptionsHeader(result) ? 'SUCCESS' : 'WARNING',
|
|
44
|
+
title: 'X-Content-Type-Options',
|
|
45
|
+
description: '',
|
|
46
|
+
};
|
|
47
|
+
const isMinified = {
|
|
48
|
+
status: this.isMinified(result) ? 'SUCCESS' : 'WARNING',
|
|
49
|
+
title: 'Minified',
|
|
50
|
+
description: '',
|
|
51
|
+
};
|
|
52
|
+
const hasConsoleLogs = {
|
|
53
|
+
status: this.hasConsoleLogs(result) ? 'SUCCESS' : 'WARNING',
|
|
54
|
+
title: 'ConsoleLogs',
|
|
55
|
+
description: '',
|
|
56
|
+
};
|
|
57
|
+
results.push({
|
|
58
|
+
status: this.getStatus([
|
|
59
|
+
isFileAvailabe.status,
|
|
60
|
+
isCached.status,
|
|
61
|
+
hasXContentTypeOptionsHeader.status,
|
|
62
|
+
isMinified.status,
|
|
63
|
+
hasConsoleLogs.status,
|
|
64
|
+
]), // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
65
|
+
title: filename,
|
|
66
|
+
description: '',
|
|
67
|
+
results: [
|
|
68
|
+
isFileAvailabe,
|
|
69
|
+
isCached,
|
|
70
|
+
hasXContentTypeOptionsHeader,
|
|
71
|
+
isMinified,
|
|
72
|
+
hasConsoleLogs,
|
|
73
|
+
],
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
return results;
|
|
77
|
+
}
|
|
78
|
+
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
|
79
|
+
isFileAvailable(result) {
|
|
80
|
+
if (result.response.statusCode === 404 || result.response.statusCode === 500) {
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
|
86
|
+
isCached(result) {
|
|
87
|
+
return result.response.headers.has('cache-control');
|
|
88
|
+
}
|
|
89
|
+
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
|
90
|
+
hasXContentTypeOptionsHeader(result) {
|
|
91
|
+
return result.response.headers.has('x-content-type-options');
|
|
92
|
+
}
|
|
93
|
+
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
|
94
|
+
isMinified(result) {
|
|
95
|
+
const r = uglify_js_1.default.minify(result.body, { mangle: false, output: { comments: true } });
|
|
96
|
+
if (Object.prototype.hasOwnProperty.call(r, 'error')) {
|
|
97
|
+
logger_1.default.error('JavaScript syntax error!');
|
|
98
|
+
throw r.error;
|
|
99
|
+
}
|
|
100
|
+
return result.body.length /* - (result.body.length * 0.05)*/ <= r.code.length;
|
|
101
|
+
}
|
|
102
|
+
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
|
103
|
+
hasConsoleLogs(result) {
|
|
104
|
+
return result.body.indexOf('console.log') !== -1 && result.body.indexOf('console.error') !== -1;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
exports.default = JavaScript;
|
|
@@ -1,42 +1,35 @@
|
|
|
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 Generator_1 = __importDefault(require("../Generator"));
|
|
16
7
|
const request_1 = __importDefault(require("../../request"));
|
|
17
|
-
test('Generator test without generator metatag', () =>
|
|
8
|
+
test('Generator test without generator metatag', async () => {
|
|
18
9
|
const generator = new Generator_1.default();
|
|
19
|
-
|
|
10
|
+
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
|
11
|
+
const mock = jest.spyOn(request_1.default, 'get').mockImplementation(async () => {
|
|
20
12
|
return new Promise((resolve) => {
|
|
21
13
|
resolve({
|
|
22
14
|
body: '<html><body><meta name="description" content="Generator is not here" /></body></html>'
|
|
23
15
|
});
|
|
24
16
|
});
|
|
25
|
-
})
|
|
26
|
-
const result =
|
|
17
|
+
});
|
|
18
|
+
const result = await generator.run({ url: 'https://juffalow.com' });
|
|
27
19
|
expect(result.status).toEqual('SUCCESS');
|
|
28
20
|
mock.mockRestore();
|
|
29
|
-
})
|
|
30
|
-
test('Generator test with generator metatag', () =>
|
|
21
|
+
});
|
|
22
|
+
test('Generator test with generator metatag', async () => {
|
|
31
23
|
const generator = new Generator_1.default();
|
|
32
|
-
|
|
24
|
+
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
|
25
|
+
const mock = jest.spyOn(request_1.default, 'get').mockImplementation(async () => {
|
|
33
26
|
return new Promise((resolve) => {
|
|
34
27
|
resolve({
|
|
35
28
|
body: '<html><body><meta name="description" content="Generator is not here" /><meta name="generator" content="Whatever" /></body></html>'
|
|
36
29
|
});
|
|
37
30
|
});
|
|
38
|
-
})
|
|
39
|
-
const result =
|
|
31
|
+
});
|
|
32
|
+
const result = await generator.run({ url: 'https://juffalow.com' });
|
|
40
33
|
expect(result.status).toEqual('WARNING');
|
|
41
34
|
mock.mockRestore();
|
|
42
|
-
})
|
|
35
|
+
});
|
|
@@ -0,0 +1,51 @@
|
|
|
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 Image_1 = __importDefault(require("./Image"));
|
|
8
|
+
const DuplicateId_1 = __importDefault(require("./DuplicateId"));
|
|
9
|
+
const CSS_1 = __importDefault(require("./CSS"));
|
|
10
|
+
const JavaScript_1 = __importDefault(require("./JavaScript"));
|
|
11
|
+
const Anchor_1 = __importDefault(require("./Anchor"));
|
|
12
|
+
const Generator_1 = __importDefault(require("./Generator"));
|
|
13
|
+
class HTML extends Test_1.default {
|
|
14
|
+
name = 'HTML';
|
|
15
|
+
constructor() {
|
|
16
|
+
super();
|
|
17
|
+
this.tests = [
|
|
18
|
+
new JavaScript_1.default(),
|
|
19
|
+
new CSS_1.default(),
|
|
20
|
+
new Image_1.default(),
|
|
21
|
+
new Anchor_1.default(),
|
|
22
|
+
new DuplicateId_1.default(),
|
|
23
|
+
new Generator_1.default(),
|
|
24
|
+
];
|
|
25
|
+
}
|
|
26
|
+
async test(params) {
|
|
27
|
+
const tests = this.getTests();
|
|
28
|
+
const results = [];
|
|
29
|
+
for (const test of tests) {
|
|
30
|
+
let result = null;
|
|
31
|
+
try {
|
|
32
|
+
result = await test.run(params);
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
result = {
|
|
36
|
+
status: 'ERROR',
|
|
37
|
+
title: test.name,
|
|
38
|
+
description: 'Test failed or cannot be run!',
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
results.push(result);
|
|
42
|
+
}
|
|
43
|
+
return {
|
|
44
|
+
status: this.getStatus(results.map(result => result.status)),
|
|
45
|
+
title: this.name,
|
|
46
|
+
description: '',
|
|
47
|
+
results,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
exports.default = HTML;
|
package/{src → dist}/index
RENAMED
|
@@ -16,22 +16,23 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
|
|
|
16
16
|
}) : function(o, v) {
|
|
17
17
|
o["default"] = v;
|
|
18
18
|
});
|
|
19
|
-
var __importStar = (this && this.__importStar) || function (
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
return
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
};
|
|
19
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
20
|
+
var ownKeys = function(o) {
|
|
21
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
22
|
+
var ar = [];
|
|
23
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
24
|
+
return ar;
|
|
25
|
+
};
|
|
26
|
+
return ownKeys(o);
|
|
27
|
+
};
|
|
28
|
+
return function (mod) {
|
|
29
|
+
if (mod && mod.__esModule) return mod;
|
|
30
|
+
var result = {};
|
|
31
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
32
|
+
__setModuleDefault(result, mod);
|
|
33
|
+
return result;
|
|
34
|
+
};
|
|
35
|
+
})();
|
|
35
36
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
37
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
38
|
};
|
|
@@ -57,32 +58,42 @@ program
|
|
|
57
58
|
.option('--logger <level>', 'DEBUG, INFO, VERBOSE, WARNING, ERROR, NONE', 'NONE')
|
|
58
59
|
.option('--reportType <type>', 'SHORT, FULL', 'SHORT')
|
|
59
60
|
.option('--reportFormat <format>', 'CMD, JSON', 'CMD')
|
|
60
|
-
.action((url, options) =>
|
|
61
|
+
.action(async (url, options) => {
|
|
61
62
|
(0, config_1.mergeConfig)({
|
|
62
63
|
exclude: options.exclude,
|
|
63
64
|
grep: options.grep,
|
|
64
|
-
logger:
|
|
65
|
-
|
|
66
|
-
|
|
65
|
+
logger: {
|
|
66
|
+
...config_1.default.logger,
|
|
67
|
+
level: options.logger,
|
|
68
|
+
},
|
|
69
|
+
report: {
|
|
70
|
+
...config_1.default.report,
|
|
71
|
+
type: options.reportType,
|
|
72
|
+
format: options.reportFormat,
|
|
73
|
+
},
|
|
74
|
+
request: {
|
|
75
|
+
...config_1.default.request,
|
|
76
|
+
cache: {
|
|
67
77
|
type: options.cache ? 'UNLIMITED' : 'BLACK_HOLE',
|
|
68
|
-
}
|
|
78
|
+
},
|
|
79
|
+
},
|
|
69
80
|
});
|
|
70
81
|
const pentest = new Pentest_1.default();
|
|
71
|
-
const results =
|
|
82
|
+
const results = await pentest.run(url);
|
|
72
83
|
const report = report_1.default.get(config_1.default.report.format);
|
|
73
|
-
report.write([results.security, results.dns, results.html, results.seo, results.wordpress]);
|
|
74
|
-
})
|
|
84
|
+
report.write([results.security, results.dns, results.html, results.seo, results.wordpress, results.metadata]);
|
|
85
|
+
});
|
|
75
86
|
program
|
|
76
87
|
.command('sitemap <URL>')
|
|
77
88
|
.description(`
|
|
78
89
|
List all URLs in sitemap.
|
|
79
90
|
`)
|
|
80
91
|
.option('--path', 'path to sitemap', 'sitemap.xml')
|
|
81
|
-
.action((url) =>
|
|
92
|
+
.action(async (url) => {
|
|
82
93
|
const sitemap = new Sitemap_1.default();
|
|
83
|
-
const urls =
|
|
94
|
+
const urls = await sitemap.run(url);
|
|
84
95
|
urls.forEach((sitemapUrl) => console.log(sitemapUrl));
|
|
85
|
-
})
|
|
96
|
+
});
|
|
86
97
|
program
|
|
87
98
|
.command('random')
|
|
88
99
|
.description(`
|
|
@@ -102,7 +113,7 @@ program
|
|
|
102
113
|
console.log(line);
|
|
103
114
|
}
|
|
104
115
|
}
|
|
105
|
-
catch
|
|
116
|
+
catch {
|
|
106
117
|
return;
|
|
107
118
|
}
|
|
108
119
|
});
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import Logger from './Logger';
|
|
2
|
+
export default class Console implements Logger {
|
|
3
|
+
protected levels: string[];
|
|
4
|
+
debug(message: string, ...args: unknown[]): void;
|
|
5
|
+
verbose(message: string, ...args: unknown[]): void;
|
|
6
|
+
info(message: string, ...args: unknown[]): void;
|
|
7
|
+
warning(message: string, ...args: unknown[]): void;
|
|
8
|
+
error(message: string, ...args: unknown[]): void;
|
|
9
|
+
/**
|
|
10
|
+
* What a terrible failure
|
|
11
|
+
* @param message
|
|
12
|
+
*/
|
|
13
|
+
wtf(message: string, ...args: unknown[]): void;
|
|
14
|
+
}
|
|
@@ -5,45 +5,43 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const config_1 = __importDefault(require("../config"));
|
|
7
7
|
class Console {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
}
|
|
11
|
-
debug(message) {
|
|
8
|
+
levels = ['ALL', 'DEBUG', 'VERBOSE', 'INFO', 'WARNING', 'ERROR', 'NONE'];
|
|
9
|
+
debug(message, ...args) {
|
|
12
10
|
if (this.levels.indexOf(config_1.default.logger.level) > 1) {
|
|
13
11
|
return;
|
|
14
12
|
}
|
|
15
|
-
console.log(message);
|
|
13
|
+
console.log(message, ...args);
|
|
16
14
|
}
|
|
17
|
-
verbose(message) {
|
|
15
|
+
verbose(message, ...args) {
|
|
18
16
|
if (this.levels.indexOf(config_1.default.logger.level) > 2) {
|
|
19
17
|
return;
|
|
20
18
|
}
|
|
21
|
-
console.log(message);
|
|
19
|
+
console.log(message, ...args);
|
|
22
20
|
}
|
|
23
|
-
info(message) {
|
|
21
|
+
info(message, ...args) {
|
|
24
22
|
if (this.levels.indexOf(config_1.default.logger.level) > 3) {
|
|
25
23
|
return;
|
|
26
24
|
}
|
|
27
|
-
console.log(message);
|
|
25
|
+
console.log(message, ...args);
|
|
28
26
|
}
|
|
29
|
-
warning(message) {
|
|
27
|
+
warning(message, ...args) {
|
|
30
28
|
if (this.levels.indexOf(config_1.default.logger.level) > 4) {
|
|
31
29
|
return;
|
|
32
30
|
}
|
|
33
|
-
console.warn(message);
|
|
31
|
+
console.warn(message, ...args);
|
|
34
32
|
}
|
|
35
|
-
error(message) {
|
|
33
|
+
error(message, ...args) {
|
|
36
34
|
if (this.levels.indexOf(config_1.default.logger.level) > 5) {
|
|
37
35
|
return;
|
|
38
36
|
}
|
|
39
|
-
console.error(message);
|
|
37
|
+
console.error(message, ...args);
|
|
40
38
|
}
|
|
41
39
|
/**
|
|
42
40
|
* What a terrible failure
|
|
43
41
|
* @param message
|
|
44
42
|
*/
|
|
45
|
-
wtf(message) {
|
|
46
|
-
console.error(message);
|
|
43
|
+
wtf(message, ...args) {
|
|
44
|
+
console.error(message, ...args);
|
|
47
45
|
}
|
|
48
46
|
}
|
|
49
47
|
exports.default = Console;
|
|
@@ -0,0 +1,26 @@
|
|
|
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 HTML extends Test_1.default {
|
|
10
|
+
name = 'HTML';
|
|
11
|
+
async test({ url }) {
|
|
12
|
+
logger_1.default.info(`Starting ${this.constructor.name} test...`);
|
|
13
|
+
const response = await request_1.default.get(url);
|
|
14
|
+
const html = response.body;
|
|
15
|
+
return {
|
|
16
|
+
status: 'SUCCESS',
|
|
17
|
+
title: this.constructor.name,
|
|
18
|
+
description: '',
|
|
19
|
+
metadata: {
|
|
20
|
+
html,
|
|
21
|
+
},
|
|
22
|
+
results: [],
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
exports.default = HTML;
|