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
|
@@ -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,22 +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', () =>
|
|
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 */
|
|
11
|
+
const mock = jest.spyOn(request_1.default, 'get').mockImplementation(async () => {
|
|
20
12
|
return new Promise((resolve) => {
|
|
21
13
|
resolve({
|
|
22
14
|
headers: {
|
|
@@ -24,21 +16,22 @@ test('Content-Security-Policy test with correct header', () => __awaiter(void 0,
|
|
|
24
16
|
},
|
|
25
17
|
});
|
|
26
18
|
});
|
|
27
|
-
})
|
|
28
|
-
const result =
|
|
19
|
+
});
|
|
20
|
+
const result = await pentest.run({ url: 'https://juffalow.com' });
|
|
29
21
|
expect(result.status).toEqual('SUCCESS');
|
|
30
22
|
mock.mockRestore();
|
|
31
|
-
})
|
|
32
|
-
test('Content-Security-Policy test with missing Content-Security-Policy header', () =>
|
|
23
|
+
});
|
|
24
|
+
test('Content-Security-Policy test with missing Content-Security-Policy header', async () => {
|
|
33
25
|
const pentest = new ContentSecurityPolicy_1.default();
|
|
34
|
-
|
|
26
|
+
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
|
27
|
+
const mock = jest.spyOn(request_1.default, 'get').mockImplementation(async () => {
|
|
35
28
|
return new Promise((resolve) => {
|
|
36
29
|
resolve({
|
|
37
30
|
headers: {}
|
|
38
31
|
});
|
|
39
32
|
});
|
|
40
|
-
})
|
|
41
|
-
const result =
|
|
33
|
+
});
|
|
34
|
+
const result = await pentest.run({ url: 'https://juffalow.com' });
|
|
42
35
|
expect(result.status).toEqual('ERROR');
|
|
43
36
|
mock.mockRestore();
|
|
44
|
-
})
|
|
37
|
+
});
|
|
@@ -1,22 +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 FingerPrint_1 = __importDefault(require("../FingerPrint"));
|
|
16
7
|
const request_1 = __importDefault(require("../../request"));
|
|
17
|
-
test('FingerPrint test without any finger print header present', () =>
|
|
8
|
+
test('FingerPrint test without any finger print header present', async () => {
|
|
18
9
|
const fingerPrint = new FingerPrint_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
|
headers: {
|
|
@@ -24,14 +16,15 @@ test('FingerPrint test without any finger print header present', () => __awaiter
|
|
|
24
16
|
},
|
|
25
17
|
});
|
|
26
18
|
});
|
|
27
|
-
})
|
|
28
|
-
const result =
|
|
19
|
+
});
|
|
20
|
+
const result = await fingerPrint.run({ url: 'https://juffalow.com' });
|
|
29
21
|
expect(result.status).toEqual('SUCCESS');
|
|
30
22
|
mock.mockRestore();
|
|
31
|
-
})
|
|
32
|
-
test('FingerPrint test with finger print header present', () =>
|
|
23
|
+
});
|
|
24
|
+
test('FingerPrint test with finger print header present', async () => {
|
|
33
25
|
const fingerPrint = new FingerPrint_1.default();
|
|
34
|
-
|
|
26
|
+
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
|
27
|
+
const mock = jest.spyOn(request_1.default, 'get').mockImplementation(async () => {
|
|
35
28
|
return new Promise((resolve) => {
|
|
36
29
|
resolve({
|
|
37
30
|
headers: {
|
|
@@ -39,8 +32,8 @@ test('FingerPrint test with finger print header present', () => __awaiter(void 0
|
|
|
39
32
|
},
|
|
40
33
|
});
|
|
41
34
|
});
|
|
42
|
-
})
|
|
43
|
-
const result =
|
|
35
|
+
});
|
|
36
|
+
const result = await fingerPrint.run({ url: 'https://juffalow.com' });
|
|
44
37
|
expect(result.status).toEqual('ERROR');
|
|
45
38
|
mock.mockRestore();
|
|
46
|
-
})
|
|
39
|
+
});
|
|
@@ -1,22 +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 HSTS_1 = __importDefault(require("../HSTS"));
|
|
16
7
|
const request_1 = __importDefault(require("../../request"));
|
|
17
|
-
test('HSTS test with correct header', () =>
|
|
8
|
+
test('HSTS test with correct header', async () => {
|
|
18
9
|
const hsts = new HSTS_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
|
headers: {
|
|
@@ -24,14 +16,15 @@ test('HSTS test with correct header', () => __awaiter(void 0, void 0, void 0, fu
|
|
|
24
16
|
},
|
|
25
17
|
});
|
|
26
18
|
});
|
|
27
|
-
})
|
|
28
|
-
const result =
|
|
19
|
+
});
|
|
20
|
+
const result = await hsts.run({ url: 'https://juffalow.com' });
|
|
29
21
|
expect(result.status).toEqual('SUCCESS');
|
|
30
22
|
mock.mockRestore();
|
|
31
|
-
})
|
|
32
|
-
test('HSTS test with low max age value', () =>
|
|
23
|
+
});
|
|
24
|
+
test('HSTS test with low max age value', async () => {
|
|
33
25
|
const hsts = new HSTS_1.default();
|
|
34
|
-
|
|
26
|
+
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
|
27
|
+
const mock = jest.spyOn(request_1.default, 'get').mockImplementation(async () => {
|
|
35
28
|
return new Promise((resolve) => {
|
|
36
29
|
resolve({
|
|
37
30
|
headers: {
|
|
@@ -39,21 +32,22 @@ test('HSTS test with low max age value', () => __awaiter(void 0, void 0, void 0,
|
|
|
39
32
|
},
|
|
40
33
|
});
|
|
41
34
|
});
|
|
42
|
-
})
|
|
43
|
-
const result =
|
|
35
|
+
});
|
|
36
|
+
const result = await hsts.run({ url: 'https://juffalow.com' });
|
|
44
37
|
expect(result.status).toEqual('ERROR');
|
|
45
38
|
mock.mockRestore();
|
|
46
|
-
})
|
|
47
|
-
test('HSTS test with missing HSTS header', () =>
|
|
39
|
+
});
|
|
40
|
+
test('HSTS test with missing HSTS header', async () => {
|
|
48
41
|
const hsts = new HSTS_1.default();
|
|
49
|
-
|
|
42
|
+
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
|
43
|
+
const mock = jest.spyOn(request_1.default, 'get').mockImplementation(async () => {
|
|
50
44
|
return new Promise((resolve) => {
|
|
51
45
|
resolve({
|
|
52
46
|
headers: {},
|
|
53
47
|
});
|
|
54
48
|
});
|
|
55
|
-
})
|
|
56
|
-
const result =
|
|
49
|
+
});
|
|
50
|
+
const result = await hsts.run({ url: 'https://juffalow.com' });
|
|
57
51
|
expect(result.status).toEqual('ERROR');
|
|
58
52
|
mock.mockRestore();
|
|
59
|
-
})
|
|
53
|
+
});
|
|
@@ -1,22 +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 HTTPS_1 = __importDefault(require("../HTTPS"));
|
|
16
7
|
const request_1 = __importDefault(require("../../request"));
|
|
17
|
-
test('HTTPS test with correct statusCode and location header', () =>
|
|
8
|
+
test('HTTPS test with correct statusCode and location header', async () => {
|
|
18
9
|
const https = new HTTPS_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
|
statusCode: 301,
|
|
@@ -25,28 +17,30 @@ test('HTTPS test with correct statusCode and location header', () => __awaiter(v
|
|
|
25
17
|
},
|
|
26
18
|
});
|
|
27
19
|
});
|
|
28
|
-
})
|
|
29
|
-
const result =
|
|
20
|
+
});
|
|
21
|
+
const result = await https.run({ url: 'https://juffalow.com' });
|
|
30
22
|
expect(result.status).toEqual('SUCCESS');
|
|
31
23
|
mock.mockRestore();
|
|
32
|
-
})
|
|
33
|
-
test('HTTPS test with wrong statusCode', () =>
|
|
24
|
+
});
|
|
25
|
+
test('HTTPS test with wrong statusCode', async () => {
|
|
34
26
|
const https = new HTTPS_1.default();
|
|
35
|
-
|
|
27
|
+
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
|
28
|
+
const mock = jest.spyOn(request_1.default, 'get').mockImplementation(async () => {
|
|
36
29
|
return new Promise((resolve) => {
|
|
37
30
|
resolve({
|
|
38
31
|
statusCode: 200,
|
|
39
32
|
headers: {}
|
|
40
33
|
});
|
|
41
34
|
});
|
|
42
|
-
})
|
|
43
|
-
const result =
|
|
35
|
+
});
|
|
36
|
+
const result = await https.run({ url: 'https://juffalow.com' });
|
|
44
37
|
expect(result.status).toEqual('ERROR');
|
|
45
38
|
mock.mockRestore();
|
|
46
|
-
})
|
|
47
|
-
test('HTTPS test with correct statusCode but wrong redirect location', () =>
|
|
39
|
+
});
|
|
40
|
+
test('HTTPS test with correct statusCode but wrong redirect location', async () => {
|
|
48
41
|
const https = new HTTPS_1.default();
|
|
49
|
-
|
|
42
|
+
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
|
43
|
+
const mock = jest.spyOn(request_1.default, 'get').mockImplementation(async () => {
|
|
50
44
|
return new Promise((resolve) => {
|
|
51
45
|
resolve({
|
|
52
46
|
statusCode: 301,
|
|
@@ -55,8 +49,8 @@ test('HTTPS test with correct statusCode but wrong redirect location', () => __a
|
|
|
55
49
|
}
|
|
56
50
|
});
|
|
57
51
|
});
|
|
58
|
-
})
|
|
59
|
-
const result =
|
|
52
|
+
});
|
|
53
|
+
const result = await https.run({ url: 'https://juffalow.com' });
|
|
60
54
|
expect(result.status).toEqual('ERROR');
|
|
61
55
|
mock.mockRestore();
|
|
62
|
-
})
|
|
56
|
+
});
|
|
@@ -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 XFrameOptions_1 = __importDefault(require("../XFrameOptions"));
|
|
7
|
+
const request_1 = __importDefault(require("../../request"));
|
|
8
|
+
test('X-Frame-Options test with correct header', async () => {
|
|
9
|
+
const pentest = new XFrameOptions_1.default();
|
|
10
|
+
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
|
11
|
+
const mock = jest.spyOn(request_1.default, 'get').mockImplementation(async () => {
|
|
12
|
+
return new Promise((resolve) => {
|
|
13
|
+
resolve({
|
|
14
|
+
headers: {
|
|
15
|
+
'x-frame-options': 'deny',
|
|
16
|
+
},
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
const result = await pentest.run({ url: 'https://juffalow.com' });
|
|
21
|
+
expect(result.status).toEqual('SUCCESS');
|
|
22
|
+
mock.mockRestore();
|
|
23
|
+
});
|
|
24
|
+
test('X-Frame-Options test with missing X-Frame-Options header', async () => {
|
|
25
|
+
const pentest = new XFrameOptions_1.default();
|
|
26
|
+
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
|
27
|
+
const mock = jest.spyOn(request_1.default, 'get').mockImplementation(async () => {
|
|
28
|
+
return new Promise((resolve) => {
|
|
29
|
+
resolve({
|
|
30
|
+
headers: {}
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
const result = await pentest.run({ url: 'https://juffalow.com' });
|
|
35
|
+
expect(result.status).toEqual('ERROR');
|
|
36
|
+
mock.mockRestore();
|
|
37
|
+
});
|
|
@@ -1,22 +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 XXSSProtection_1 = __importDefault(require("../XXSSProtection"));
|
|
16
7
|
const request_1 = __importDefault(require("../../request"));
|
|
17
|
-
test('X-XSS-Protection test with correct header', () =>
|
|
8
|
+
test('X-XSS-Protection test with correct header', async () => {
|
|
18
9
|
const pentest = new XXSSProtection_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
|
headers: {
|
|
@@ -24,21 +16,22 @@ test('X-XSS-Protection test with correct header', () => __awaiter(void 0, void 0
|
|
|
24
16
|
},
|
|
25
17
|
});
|
|
26
18
|
});
|
|
27
|
-
})
|
|
28
|
-
const result =
|
|
19
|
+
});
|
|
20
|
+
const result = await pentest.run({ url: 'https://juffalow.com' });
|
|
29
21
|
expect(result.status).toEqual('SUCCESS');
|
|
30
22
|
mock.mockRestore();
|
|
31
|
-
})
|
|
32
|
-
test('X-XSS-Protection test with missing X-XSS-Protection header', () =>
|
|
23
|
+
});
|
|
24
|
+
test('X-XSS-Protection test with missing X-XSS-Protection header', async () => {
|
|
33
25
|
const pentest = new XXSSProtection_1.default();
|
|
34
|
-
|
|
26
|
+
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
|
27
|
+
const mock = jest.spyOn(request_1.default, 'get').mockImplementation(async () => {
|
|
35
28
|
return new Promise((resolve) => {
|
|
36
29
|
resolve({
|
|
37
30
|
headers: {}
|
|
38
31
|
});
|
|
39
32
|
});
|
|
40
|
-
})
|
|
41
|
-
const result =
|
|
33
|
+
});
|
|
34
|
+
const result = await pentest.run({ url: 'https://juffalow.com' });
|
|
42
35
|
expect(result.status).toEqual('ERROR');
|
|
43
36
|
mock.mockRestore();
|
|
44
|
-
})
|
|
37
|
+
});
|