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,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 node_html_markdown_1 = require("node-html-markdown");
|
|
7
|
+
const Test_1 = __importDefault(require("../Test"));
|
|
8
|
+
const request_1 = __importDefault(require("../request"));
|
|
9
|
+
const logger_1 = __importDefault(require("../logger"));
|
|
10
|
+
class Markdown extends Test_1.default {
|
|
11
|
+
name = 'Markdown';
|
|
12
|
+
async test({ url }) {
|
|
13
|
+
logger_1.default.info(`Starting ${this.constructor.name} test...`);
|
|
14
|
+
const response = await request_1.default.get(url);
|
|
15
|
+
const html = response.body;
|
|
16
|
+
const markdown = node_html_markdown_1.NodeHtmlMarkdown.translate(html);
|
|
17
|
+
return {
|
|
18
|
+
status: 'SUCCESS',
|
|
19
|
+
title: this.constructor.name,
|
|
20
|
+
description: '',
|
|
21
|
+
metadata: {
|
|
22
|
+
markdown,
|
|
23
|
+
},
|
|
24
|
+
results: [],
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
exports.default = Markdown;
|
|
@@ -0,0 +1,25 @@
|
|
|
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 ResponseTime extends Test_1.default {
|
|
10
|
+
name = 'ResponseTime';
|
|
11
|
+
async test({ url }) {
|
|
12
|
+
logger_1.default.info(`Starting ${this.constructor.name} test...`);
|
|
13
|
+
const response = await request_1.default.get(url);
|
|
14
|
+
return {
|
|
15
|
+
status: 'SUCCESS',
|
|
16
|
+
title: this.constructor.name,
|
|
17
|
+
description: '',
|
|
18
|
+
metadata: {
|
|
19
|
+
duration: response.duration,
|
|
20
|
+
},
|
|
21
|
+
results: [],
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
exports.default = ResponseTime;
|
|
@@ -0,0 +1,45 @@
|
|
|
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 HTML_1 = __importDefault(require("./HTML"));
|
|
8
|
+
const Markdown_1 = __importDefault(require("./Markdown"));
|
|
9
|
+
const ResponseTime_1 = __importDefault(require("./ResponseTime"));
|
|
10
|
+
class Metadata extends Test_1.default {
|
|
11
|
+
name = 'Metadata';
|
|
12
|
+
constructor() {
|
|
13
|
+
super();
|
|
14
|
+
this.tests = [
|
|
15
|
+
new HTML_1.default(),
|
|
16
|
+
new Markdown_1.default(),
|
|
17
|
+
new ResponseTime_1.default(),
|
|
18
|
+
];
|
|
19
|
+
}
|
|
20
|
+
async test(params) {
|
|
21
|
+
const tests = this.getTests();
|
|
22
|
+
const results = [];
|
|
23
|
+
for (const test of tests) {
|
|
24
|
+
let result = null;
|
|
25
|
+
try {
|
|
26
|
+
result = await test.run(params);
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
result = {
|
|
30
|
+
status: 'ERROR',
|
|
31
|
+
title: test.name,
|
|
32
|
+
description: 'Test failed or cannot be run!',
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
results.push(result);
|
|
36
|
+
}
|
|
37
|
+
return {
|
|
38
|
+
status: this.getStatus(results.map(result => result.status)),
|
|
39
|
+
title: this.name,
|
|
40
|
+
description: '',
|
|
41
|
+
results,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
exports.default = Metadata;
|
|
@@ -0,0 +1,58 @@
|
|
|
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 config_1 = __importDefault(require("../config"));
|
|
7
|
+
const getHeaders = (headers) => {
|
|
8
|
+
const keyValues = {};
|
|
9
|
+
headers.forEach((value, header) => {
|
|
10
|
+
if (value.length === 1 && header !== 'set-cookie') {
|
|
11
|
+
keyValues[header] = value[0];
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
keyValues[header] = value;
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
return keyValues;
|
|
18
|
+
};
|
|
19
|
+
class NodeFetch {
|
|
20
|
+
cache;
|
|
21
|
+
constructor(cache) {
|
|
22
|
+
this.cache = cache;
|
|
23
|
+
}
|
|
24
|
+
async get(url, options) {
|
|
25
|
+
if (this.cache.has(url)) {
|
|
26
|
+
return this.cache.get(url);
|
|
27
|
+
}
|
|
28
|
+
const defaultOptions = config_1.default.request.options;
|
|
29
|
+
const startTime = Date.now();
|
|
30
|
+
const response = await fetch(url, { ...defaultOptions, ...options });
|
|
31
|
+
const endTime = Date.now();
|
|
32
|
+
const body = await response.text();
|
|
33
|
+
const statusCode = response.status;
|
|
34
|
+
const statusText = response.statusText;
|
|
35
|
+
const headers = getHeaders(response.headers);
|
|
36
|
+
this.cache.add(url, {
|
|
37
|
+
response,
|
|
38
|
+
statusCode,
|
|
39
|
+
statusText,
|
|
40
|
+
headers,
|
|
41
|
+
body,
|
|
42
|
+
url,
|
|
43
|
+
finalUrl: response.url,
|
|
44
|
+
duration: (endTime - startTime) / 1000,
|
|
45
|
+
});
|
|
46
|
+
return {
|
|
47
|
+
response,
|
|
48
|
+
statusCode,
|
|
49
|
+
statusText,
|
|
50
|
+
headers,
|
|
51
|
+
body,
|
|
52
|
+
url,
|
|
53
|
+
finalUrl: response.url,
|
|
54
|
+
duration: (endTime - startTime) / 1000,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
exports.default = NodeFetch;
|
|
@@ -5,11 +5,13 @@ export type Options = {
|
|
|
5
5
|
};
|
|
6
6
|
export type Response = {
|
|
7
7
|
url: string;
|
|
8
|
+
finalUrl: string;
|
|
8
9
|
body: string;
|
|
9
10
|
statusCode: number;
|
|
10
11
|
statusText: string;
|
|
11
12
|
headers: any;
|
|
12
13
|
response: any;
|
|
14
|
+
duration: number;
|
|
13
15
|
};
|
|
14
16
|
export default interface Request {
|
|
15
17
|
get(url: string, options?: Options): Promise<Response>;
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
class BlackHoleCache {
|
|
4
|
-
add(
|
|
4
|
+
add() {
|
|
5
5
|
return;
|
|
6
6
|
}
|
|
7
|
-
has(
|
|
7
|
+
has() {
|
|
8
8
|
return false;
|
|
9
9
|
}
|
|
10
|
-
|
|
10
|
+
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
|
11
|
+
get() {
|
|
11
12
|
return null;
|
|
12
13
|
}
|
|
13
14
|
clear() {
|
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
class UnlimitedCache {
|
|
4
|
+
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
|
5
|
+
requests;
|
|
4
6
|
constructor() {
|
|
5
7
|
this.requests = {};
|
|
6
8
|
}
|
|
9
|
+
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
|
7
10
|
add(url, response) {
|
|
8
11
|
this.requests[url] = response;
|
|
9
12
|
}
|
|
10
13
|
has(url) {
|
|
11
14
|
return Object.prototype.hasOwnProperty.call(this.requests, url);
|
|
12
15
|
}
|
|
16
|
+
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
|
13
17
|
get(url) {
|
|
14
18
|
if (!this.has(url)) {
|
|
15
19
|
return null;
|
|
@@ -0,0 +1,11 @@
|
|
|
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 NodeFetch_1 = __importDefault(require("./NodeFetch"));
|
|
7
|
+
const UnlimitedCache_1 = __importDefault(require("./cache/UnlimitedCache"));
|
|
8
|
+
const BlackHoleCache_1 = __importDefault(require("./cache/BlackHoleCache"));
|
|
9
|
+
const config_1 = __importDefault(require("../config"));
|
|
10
|
+
const cache = config_1.default.request.cache.type === 'UNLIMITED' ? new UnlimitedCache_1.default() : new BlackHoleCache_1.default();
|
|
11
|
+
exports.default = new NodeFetch_1.default(cache);
|
|
@@ -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
|
+
/**
|
|
10
|
+
*
|
|
11
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/content-encoding
|
|
12
|
+
*/
|
|
13
|
+
class ContentEncoding extends Test_1.default {
|
|
14
|
+
name = 'Content-Encoding';
|
|
15
|
+
async test({ url }) {
|
|
16
|
+
logger_1.default.info('Starting content-encoding test...');
|
|
17
|
+
const response = await request_1.default.get(url);
|
|
18
|
+
if (!Object.prototype.hasOwnProperty.call(response.headers, 'content-encoding')) {
|
|
19
|
+
return {
|
|
20
|
+
status: 'ERROR',
|
|
21
|
+
title: 'Content-Encoding',
|
|
22
|
+
description: 'Response headers does not contain content-encoding header!',
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
const attributesList = response.headers['content-encoding'];
|
|
26
|
+
const attributes = attributesList.replace(' ', '').split(',');
|
|
27
|
+
const ce1 = attributes.indexOf('gzip') > -1;
|
|
28
|
+
const ce2 = attributes.indexOf('deflate') > -1;
|
|
29
|
+
const ce3 = attributes.indexOf('br') > -1;
|
|
30
|
+
if (ce1 || ce2 || ce3) {
|
|
31
|
+
return {
|
|
32
|
+
status: 'SUCCESS',
|
|
33
|
+
title: 'Content-Encoding',
|
|
34
|
+
description: `The value of content-encoding header is ${attributesList}.`,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
return {
|
|
38
|
+
status: 'ERROR',
|
|
39
|
+
title: 'Content-Encoding',
|
|
40
|
+
description: `The value of content-encoding header is ${attributesList}.`,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
exports.default = ContentEncoding;
|
|
@@ -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/CSP
|
|
12
|
+
*/
|
|
13
|
+
class ContentSecurityPolicy extends Test_1.default {
|
|
14
|
+
name = 'Content-Security-Policy';
|
|
15
|
+
async test({ url }) {
|
|
16
|
+
logger_1.default.info('Starting ContentSecurityPolicy test...');
|
|
17
|
+
const response = await request_1.default.get(url);
|
|
18
|
+
if (!Object.prototype.hasOwnProperty.call(response.headers, 'content-security-policy')) {
|
|
19
|
+
return {
|
|
20
|
+
status: 'ERROR',
|
|
21
|
+
title: 'Content-Security-Policy',
|
|
22
|
+
description: 'Response headers does not contain content-security-policy header!',
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
return {
|
|
26
|
+
status: 'SUCCESS',
|
|
27
|
+
title: 'Content-Security-Policy',
|
|
28
|
+
description: `The value of content-security-policy header is ${response.headers['content-security-policy']}.`,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
exports.default = ContentSecurityPolicy;
|
|
@@ -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;
|