sentinel-scanner 2.4.1 → 2.5.0
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/.cspell.json +19 -51
- package/.github/ISSUE_TEMPLATE/config.yml +1 -1
- package/.github/PULL_REQUEST_TEMPLATE.md +2 -2
- package/.github/workflows/stale.yaml +20 -0
- package/.github/workflows/webapp-scanner.yml +31 -19
- package/.github/workflows/welcome.yaml +9 -55
- package/.husky/pre-commit +35 -0
- package/.vscode/extensions.json +7 -0
- package/.vscode/launch.json +20 -0
- package/.vscode/settings.json +32 -0
- package/.vscode/tasks.json +24 -0
- package/CHANGELOG.md +7 -3
- package/CODE_OF_CONDUCT.md +4 -1
- package/CONTRIBUTING.md +2 -2
- package/README.md +5 -0
- package/api-extractor.json +30 -30
- package/biome.json +6 -32
- package/build/index.d.ts +0 -147
- package/build/index.js +111 -2633
- package/package.json +69 -102
- package/scripts/build.ts +68 -78
- package/scripts/test.ts +55 -0
- package/src/__tests__/spider.test.ts +44 -0
- package/src/commands/spider.ts +61 -126
- package/src/index.ts +23 -26
- package/src/spider/index.ts +345 -0
- package/src/spider/types/index.ts +21 -0
- package/src/spider/types/schema.ts +54 -0
- package/src/utils/index.ts +199 -3
- package/tsconfig.json +19 -18
- package/.github/assets/header.png +0 -0
- package/.github/dependabot.yml +0 -11
- package/.github/workflows/pr.yaml +0 -64
- package/.nsprc +0 -3
- package/build/bin.js +0 -2679
- package/build/xhr-sync-worker.js +0 -59
- package/docs/CNAME +0 -1
- package/docs/disclaimer.md +0 -68
- package/docs/headers/details.md +0 -114
- package/docs/headers/index.md +0 -73
- package/docs/index.md +0 -82
- package/docs/ports/index.md +0 -86
- package/docs/scoring.md +0 -91
- package/docs/spider/index.md +0 -61
- package/docs/sql-injection/details.md +0 -109
- package/docs/sql-injection/index.md +0 -73
- package/docs/xss/details.md +0 -92
- package/docs/xss/index.md +0 -73
- package/scripts/extras/document-shim.js +0 -4
- package/src/bin.ts +0 -29
- package/src/commands/header.ts +0 -150
- package/src/commands/ports.ts +0 -175
- package/src/commands/sqli.ts +0 -150
- package/src/commands/xss.ts +0 -149
- package/src/modules/headers/headers.ts +0 -161
- package/src/modules/headers/index.ts +0 -179
- package/src/modules/ports/index.ts +0 -311
- package/src/modules/spider/index.ts +0 -178
- package/src/modules/sqli/index.ts +0 -486
- package/src/modules/sqli/payloads.json +0 -156
- package/src/modules/xss/index.ts +0 -401
- package/src/modules/xss/payloads.json +0 -2692
- package/src/utils/types.ts +0 -7
package/src/commands/ports.ts
DELETED
@@ -1,175 +0,0 @@
|
|
1
|
-
import fs from "node:fs/promises";
|
2
|
-
import path from "node:path";
|
3
|
-
import type { ArgumentsCamelCase, CommandModule } from "yargs";
|
4
|
-
import { PortsScanner } from "../index.js";
|
5
|
-
import { createLogger } from "../utils/index.js";
|
6
|
-
|
7
|
-
export type PortScannerCLIOpts = {
|
8
|
-
spiderResults: string;
|
9
|
-
fromPort?: number;
|
10
|
-
toPort?: number;
|
11
|
-
allowList?: Array<number>;
|
12
|
-
concurrency?: number;
|
13
|
-
timeout?: number;
|
14
|
-
output?: string;
|
15
|
-
};
|
16
|
-
|
17
|
-
const cliLogger = createLogger("CLI");
|
18
|
-
|
19
|
-
export const portsCommand: CommandModule = {
|
20
|
-
command: "ports",
|
21
|
-
describe:
|
22
|
-
"Check a website for Open Port vulnerabilities. Check the ports between the specified range for open ports",
|
23
|
-
builder: (yargs) => {
|
24
|
-
return yargs
|
25
|
-
.option("spiderResults", {
|
26
|
-
alias: "s",
|
27
|
-
type: "string",
|
28
|
-
description:
|
29
|
-
"The spider results file to use for scanning. It will use the URLs from the spider results to scan for header vulnerabilities",
|
30
|
-
demandOption: true,
|
31
|
-
coerce: (url) => {
|
32
|
-
if (!path.isAbsolute(url)) {
|
33
|
-
return path.resolve(url);
|
34
|
-
}
|
35
|
-
return url;
|
36
|
-
},
|
37
|
-
})
|
38
|
-
.option("output", {
|
39
|
-
alias: "o",
|
40
|
-
type: "string",
|
41
|
-
description:
|
42
|
-
"The output file to write the results to. Must be a JSON file",
|
43
|
-
default: () => getDefaultFilePath(),
|
44
|
-
coerce: (output) => {
|
45
|
-
const resolvedPath = path.resolve(output);
|
46
|
-
const { ext } = path.parse(resolvedPath);
|
47
|
-
|
48
|
-
if (ext !== ".json") {
|
49
|
-
throw new Error("Output file must be a JSON file");
|
50
|
-
}
|
51
|
-
return resolvedPath;
|
52
|
-
},
|
53
|
-
})
|
54
|
-
.option("concurrency", {
|
55
|
-
alias: "c",
|
56
|
-
type: "number",
|
57
|
-
description: "The number of concurrent requests to make",
|
58
|
-
default: 10,
|
59
|
-
coerce: (concurrency) => {
|
60
|
-
if (concurrency < 1 || concurrency > 20) {
|
61
|
-
throw new Error("Concurrency must be between 1 and 20");
|
62
|
-
}
|
63
|
-
return concurrency;
|
64
|
-
},
|
65
|
-
})
|
66
|
-
.option("timeout", {
|
67
|
-
alias: "t",
|
68
|
-
type: "number",
|
69
|
-
description: "The timeout for each request in milliseconds",
|
70
|
-
default: 5000,
|
71
|
-
coerce: (timeout) => {
|
72
|
-
if (timeout < 0 || timeout > 25000) {
|
73
|
-
throw new Error("Timeout must be between 0 and 25,000 ms");
|
74
|
-
}
|
75
|
-
return timeout;
|
76
|
-
},
|
77
|
-
})
|
78
|
-
.option("fromPort", {
|
79
|
-
alias: "fp",
|
80
|
-
type: "number",
|
81
|
-
description: "The starting port to scan",
|
82
|
-
default: 3,
|
83
|
-
coerce: (fromPort) => {
|
84
|
-
if (fromPort < 1 || fromPort > 65535) {
|
85
|
-
throw new Error("Port must be between 1 and 65,535");
|
86
|
-
}
|
87
|
-
},
|
88
|
-
})
|
89
|
-
.option("toPort", {
|
90
|
-
alias: "tp",
|
91
|
-
type: "number",
|
92
|
-
description: "The ending port to scan",
|
93
|
-
default: 8080,
|
94
|
-
coerce: (toPort) => {
|
95
|
-
if (toPort < 1 || toPort > 65535) {
|
96
|
-
throw new Error("Port must be between 1 and 65,535");
|
97
|
-
}
|
98
|
-
},
|
99
|
-
})
|
100
|
-
.option("allowList", {
|
101
|
-
alias: "al",
|
102
|
-
type: "array",
|
103
|
-
description: "A list of ports to allow",
|
104
|
-
default: [22, 80, 443],
|
105
|
-
coerce: (allowList) => {
|
106
|
-
if (!Array.isArray(allowList)) {
|
107
|
-
throw new Error("Allow list must be an array");
|
108
|
-
}
|
109
|
-
return allowList;
|
110
|
-
},
|
111
|
-
});
|
112
|
-
},
|
113
|
-
handler: async (args) => {
|
114
|
-
try {
|
115
|
-
const argData = args as ArgumentsCamelCase<PortScannerCLIOpts>;
|
116
|
-
const spiderResultsPath = path.resolve(argData.spiderResults);
|
117
|
-
|
118
|
-
// Check if the spider results file exists
|
119
|
-
if (!(await fileExists(spiderResultsPath))) {
|
120
|
-
throw new Error(
|
121
|
-
`Spider results file not found at ${spiderResultsPath}`,
|
122
|
-
);
|
123
|
-
}
|
124
|
-
|
125
|
-
const spiderResults = JSON.parse(
|
126
|
-
await fs.readFile(spiderResultsPath, "utf-8"),
|
127
|
-
);
|
128
|
-
|
129
|
-
cliLogger.info("Starting Port scan on website");
|
130
|
-
|
131
|
-
const scanner = new PortsScanner({
|
132
|
-
spiderResults,
|
133
|
-
fromPort: argData.fromPort ?? 1,
|
134
|
-
toPort: argData.toPort ?? 65535,
|
135
|
-
allowList: argData.allowList ?? [22, 80, 443],
|
136
|
-
concurrency: argData.concurrency ?? 30,
|
137
|
-
timeout: argData.timeout ?? 10000,
|
138
|
-
});
|
139
|
-
const results = await scanner.scan();
|
140
|
-
|
141
|
-
const outputPath = argData.output || getDefaultFilePath();
|
142
|
-
await fs.writeFile(outputPath, JSON.stringify(results, null, 2));
|
143
|
-
cliLogger.info(`Results successfully written to ${outputPath}`);
|
144
|
-
} catch (error) {
|
145
|
-
if (error instanceof Error) {
|
146
|
-
cliLogger.error(`Error: ${error.message}`);
|
147
|
-
}
|
148
|
-
cliLogger.error("Failed to run Port Scan command");
|
149
|
-
process.exit(1);
|
150
|
-
}
|
151
|
-
},
|
152
|
-
};
|
153
|
-
|
154
|
-
// Utility function to check if a file exists
|
155
|
-
const fileExists = async (filePath: string) => {
|
156
|
-
try {
|
157
|
-
await fs.access(filePath);
|
158
|
-
return true;
|
159
|
-
} catch {
|
160
|
-
return false;
|
161
|
-
}
|
162
|
-
};
|
163
|
-
|
164
|
-
// Utility function to get the default file path
|
165
|
-
const getDefaultFilePath = () => {
|
166
|
-
const resolvedDir = path.resolve("sentinel_output");
|
167
|
-
|
168
|
-
// Ensure the directory exists or create it
|
169
|
-
fs.mkdir(resolvedDir, { recursive: true }).catch((err) => {
|
170
|
-
cliLogger.error(`Failed to create directory: ${err.message}`);
|
171
|
-
process.exit(1);
|
172
|
-
});
|
173
|
-
|
174
|
-
return path.resolve(resolvedDir, `portsResults_${Date.now()}.json`);
|
175
|
-
};
|
package/src/commands/sqli.ts
DELETED
@@ -1,150 +0,0 @@
|
|
1
|
-
import fs from "node:fs/promises";
|
2
|
-
import path from "node:path";
|
3
|
-
import type { ArgumentsCamelCase, CommandModule } from "yargs";
|
4
|
-
import SqliScanner from "../modules/sqli/index.js";
|
5
|
-
import { createLogger } from "../utils/index.js";
|
6
|
-
|
7
|
-
export type SqliScannerCLIoptions = {
|
8
|
-
spiderResults: string;
|
9
|
-
retries?: number;
|
10
|
-
timeout?: number;
|
11
|
-
concurrency?: number;
|
12
|
-
output?: string;
|
13
|
-
};
|
14
|
-
|
15
|
-
const cliLogger = createLogger("CLI");
|
16
|
-
|
17
|
-
export const sqliCommand: CommandModule = {
|
18
|
-
command: "sqli",
|
19
|
-
describe:
|
20
|
-
"Check a website for SQL Injection vulnerabilities by scanning each page",
|
21
|
-
builder: (yargs) => {
|
22
|
-
return yargs
|
23
|
-
.option("spiderResults", {
|
24
|
-
alias: "s",
|
25
|
-
type: "string",
|
26
|
-
description:
|
27
|
-
"The spider results file to use for scanning. It will use the URLs from the spider results to scan for SQL Injection vulnerabilities",
|
28
|
-
demandOption: true,
|
29
|
-
coerce: (url) => {
|
30
|
-
if (!path.isAbsolute(url)) {
|
31
|
-
return path.resolve(url);
|
32
|
-
}
|
33
|
-
return url;
|
34
|
-
},
|
35
|
-
})
|
36
|
-
.option("output", {
|
37
|
-
alias: "o",
|
38
|
-
type: "string",
|
39
|
-
description:
|
40
|
-
"The output file to write the results to. Must be a JSON file",
|
41
|
-
default: () => getDefaultFilePath(),
|
42
|
-
coerce: (output) => {
|
43
|
-
const resolvedPath = path.resolve(output);
|
44
|
-
const { ext } = path.parse(resolvedPath);
|
45
|
-
|
46
|
-
if (ext !== ".json") {
|
47
|
-
throw new Error("Output file must be a JSON file");
|
48
|
-
}
|
49
|
-
return resolvedPath;
|
50
|
-
},
|
51
|
-
})
|
52
|
-
.option("concurrency", {
|
53
|
-
alias: "c",
|
54
|
-
type: "number",
|
55
|
-
description: "The number of concurrent requests to make",
|
56
|
-
default: 10,
|
57
|
-
coerce: (concurrency) => {
|
58
|
-
if (concurrency < 1 || concurrency > 20) {
|
59
|
-
throw new Error("Concurrency must be between 1 and 20");
|
60
|
-
}
|
61
|
-
return concurrency;
|
62
|
-
},
|
63
|
-
})
|
64
|
-
.option("timeout", {
|
65
|
-
alias: "t",
|
66
|
-
type: "number",
|
67
|
-
description: "The timeout for each request in milliseconds",
|
68
|
-
default: 5000,
|
69
|
-
coerce: (timeout) => {
|
70
|
-
if (timeout < 0 || timeout > 25000) {
|
71
|
-
throw new Error("Timeout must be between 0 and 25,000 ms");
|
72
|
-
}
|
73
|
-
return timeout;
|
74
|
-
},
|
75
|
-
})
|
76
|
-
.option("retries", {
|
77
|
-
alias: "r",
|
78
|
-
type: "number",
|
79
|
-
description: "The number of retries for each request",
|
80
|
-
default: 3,
|
81
|
-
coerce: (retries) => {
|
82
|
-
if (retries < 0 || retries > 10) {
|
83
|
-
throw new Error("Retries must be between 0 and 10");
|
84
|
-
}
|
85
|
-
return retries;
|
86
|
-
},
|
87
|
-
});
|
88
|
-
},
|
89
|
-
handler: async (args) => {
|
90
|
-
try {
|
91
|
-
const argData = args as ArgumentsCamelCase<SqliScannerCLIoptions>;
|
92
|
-
const spiderResultsPath = path.resolve(argData.spiderResults);
|
93
|
-
|
94
|
-
// Check if the spider results file exists
|
95
|
-
if (!(await fileExists(spiderResultsPath))) {
|
96
|
-
throw new Error(
|
97
|
-
`Spider results file not found at ${spiderResultsPath}`,
|
98
|
-
);
|
99
|
-
}
|
100
|
-
|
101
|
-
const spiderResults = JSON.parse(
|
102
|
-
await fs.readFile(spiderResultsPath, "utf-8"),
|
103
|
-
);
|
104
|
-
|
105
|
-
cliLogger.info("Starting SQLI scan on website");
|
106
|
-
|
107
|
-
const scanner = new SqliScanner({
|
108
|
-
spiderResults,
|
109
|
-
concurrency: argData.concurrency,
|
110
|
-
timeout: argData.timeout,
|
111
|
-
retries: argData.retries,
|
112
|
-
});
|
113
|
-
|
114
|
-
const results = await scanner.scan();
|
115
|
-
|
116
|
-
const outputPath = argData.output || getDefaultFilePath();
|
117
|
-
await fs.writeFile(outputPath, JSON.stringify(results, null, 2));
|
118
|
-
cliLogger.info(`Results successfully written to ${outputPath}`);
|
119
|
-
} catch (error) {
|
120
|
-
if (error instanceof Error) {
|
121
|
-
cliLogger.error(`Error: ${error.message}`);
|
122
|
-
}
|
123
|
-
cliLogger.error("Failed to run SQLI command");
|
124
|
-
process.exit(1);
|
125
|
-
}
|
126
|
-
},
|
127
|
-
};
|
128
|
-
|
129
|
-
// Utility function to check if a file exists
|
130
|
-
const fileExists = async (filePath: string) => {
|
131
|
-
try {
|
132
|
-
await fs.access(filePath);
|
133
|
-
return true;
|
134
|
-
} catch {
|
135
|
-
return false;
|
136
|
-
}
|
137
|
-
};
|
138
|
-
|
139
|
-
// Utility function to get the default file path
|
140
|
-
const getDefaultFilePath = () => {
|
141
|
-
const resolvedDir = path.resolve("sentinel_output");
|
142
|
-
|
143
|
-
// Ensure the directory exists or create it
|
144
|
-
fs.mkdir(resolvedDir, { recursive: true }).catch((err) => {
|
145
|
-
cliLogger.error(`Failed to create directory: ${err.message}`);
|
146
|
-
process.exit(1);
|
147
|
-
});
|
148
|
-
|
149
|
-
return path.resolve(resolvedDir, `sqliResult_${Date.now()}.json`);
|
150
|
-
};
|
package/src/commands/xss.ts
DELETED
@@ -1,149 +0,0 @@
|
|
1
|
-
import fs from "node:fs/promises";
|
2
|
-
import path from "node:path";
|
3
|
-
import type { ArgumentsCamelCase, CommandModule } from "yargs";
|
4
|
-
import { XSSScanner } from "../index.js";
|
5
|
-
import { createLogger } from "../utils/index.js";
|
6
|
-
|
7
|
-
export type XSSScannerCLIoptions = {
|
8
|
-
spiderResults: string;
|
9
|
-
retries?: number;
|
10
|
-
timeout?: number;
|
11
|
-
concurrency?: number;
|
12
|
-
output?: string;
|
13
|
-
};
|
14
|
-
|
15
|
-
const cliLogger = createLogger("CLI");
|
16
|
-
|
17
|
-
export const xssCommand: CommandModule = {
|
18
|
-
command: "xss",
|
19
|
-
describe: "Check a website for XSS vulnerabilities by scanning each page",
|
20
|
-
builder: (yargs) => {
|
21
|
-
return yargs
|
22
|
-
.option("spiderResults", {
|
23
|
-
alias: "s",
|
24
|
-
type: "string",
|
25
|
-
description:
|
26
|
-
"The spider results file to use for scanning. It will use the URLs from the spider results to scan for XSS vulnerabilities",
|
27
|
-
demandOption: true,
|
28
|
-
coerce: (url) => {
|
29
|
-
if (!path.isAbsolute(url)) {
|
30
|
-
return path.resolve(url);
|
31
|
-
}
|
32
|
-
return url;
|
33
|
-
},
|
34
|
-
})
|
35
|
-
.option("output", {
|
36
|
-
alias: "o",
|
37
|
-
type: "string",
|
38
|
-
description:
|
39
|
-
"The output file to write the results to. Must be a JSON file",
|
40
|
-
default: () => getDefaultFilePath(),
|
41
|
-
coerce: (output) => {
|
42
|
-
const resolvedPath = path.resolve(output);
|
43
|
-
const { ext } = path.parse(resolvedPath);
|
44
|
-
|
45
|
-
if (ext !== ".json") {
|
46
|
-
throw new Error("Output file must be a JSON file");
|
47
|
-
}
|
48
|
-
return resolvedPath;
|
49
|
-
},
|
50
|
-
})
|
51
|
-
.option("concurrency", {
|
52
|
-
alias: "c",
|
53
|
-
type: "number",
|
54
|
-
description: "The number of concurrent requests to make",
|
55
|
-
default: 10,
|
56
|
-
coerce: (concurrency) => {
|
57
|
-
if (concurrency < 1 || concurrency > 20) {
|
58
|
-
throw new Error("Concurrency must be between 1 and 20");
|
59
|
-
}
|
60
|
-
return concurrency;
|
61
|
-
},
|
62
|
-
})
|
63
|
-
.option("timeout", {
|
64
|
-
alias: "t",
|
65
|
-
type: "number",
|
66
|
-
description: "The timeout for each request in milliseconds",
|
67
|
-
default: 5000,
|
68
|
-
coerce: (timeout) => {
|
69
|
-
if (timeout < 0 || timeout > 25000) {
|
70
|
-
throw new Error("Timeout must be between 0 and 25,000 ms");
|
71
|
-
}
|
72
|
-
return timeout;
|
73
|
-
},
|
74
|
-
})
|
75
|
-
.option("retries", {
|
76
|
-
alias: "r",
|
77
|
-
type: "number",
|
78
|
-
description: "The number of retries for each request",
|
79
|
-
default: 3,
|
80
|
-
coerce: (retries) => {
|
81
|
-
if (retries < 0 || retries > 10) {
|
82
|
-
throw new Error("Retries must be between 0 and 10");
|
83
|
-
}
|
84
|
-
return retries;
|
85
|
-
},
|
86
|
-
});
|
87
|
-
},
|
88
|
-
handler: async (args) => {
|
89
|
-
try {
|
90
|
-
const argData = args as ArgumentsCamelCase<XSSScannerCLIoptions>;
|
91
|
-
const spiderResultsPath = path.resolve(argData.spiderResults);
|
92
|
-
|
93
|
-
// Check if the spider results file exists
|
94
|
-
if (!(await fileExists(spiderResultsPath))) {
|
95
|
-
throw new Error(
|
96
|
-
`Spider results file not found at ${spiderResultsPath}`,
|
97
|
-
);
|
98
|
-
}
|
99
|
-
|
100
|
-
const spiderResults = JSON.parse(
|
101
|
-
await fs.readFile(spiderResultsPath, "utf-8"),
|
102
|
-
);
|
103
|
-
|
104
|
-
cliLogger.info("Starting XSS scan on website");
|
105
|
-
|
106
|
-
const scanner = new XSSScanner({
|
107
|
-
spiderResults,
|
108
|
-
concurrency: argData.concurrency,
|
109
|
-
timeout: argData.timeout,
|
110
|
-
retries: argData.retries,
|
111
|
-
});
|
112
|
-
|
113
|
-
const results = await scanner.scan();
|
114
|
-
|
115
|
-
const outputPath = argData.output || getDefaultFilePath();
|
116
|
-
await fs.writeFile(outputPath, JSON.stringify(results, null, 2));
|
117
|
-
cliLogger.info(`Results successfully written to ${outputPath}`);
|
118
|
-
} catch (error) {
|
119
|
-
if (error instanceof Error) {
|
120
|
-
cliLogger.error(`Error: ${error.message}`);
|
121
|
-
}
|
122
|
-
cliLogger.error("Failed to run XSS command");
|
123
|
-
process.exit(1);
|
124
|
-
}
|
125
|
-
},
|
126
|
-
};
|
127
|
-
|
128
|
-
// Utility function to check if a file exists
|
129
|
-
const fileExists = async (filePath: string) => {
|
130
|
-
try {
|
131
|
-
await fs.access(filePath);
|
132
|
-
return true;
|
133
|
-
} catch {
|
134
|
-
return false;
|
135
|
-
}
|
136
|
-
};
|
137
|
-
|
138
|
-
// Utility function to get the default file path
|
139
|
-
const getDefaultFilePath = () => {
|
140
|
-
const resolvedDir = path.resolve("sentinel_output");
|
141
|
-
|
142
|
-
// Ensure the directory exists or create it
|
143
|
-
fs.mkdir(resolvedDir, { recursive: true }).catch((err) => {
|
144
|
-
cliLogger.error(`Failed to create directory: ${err.message}`);
|
145
|
-
process.exit(1);
|
146
|
-
});
|
147
|
-
|
148
|
-
return path.resolve(resolvedDir, `xssResult_${Date.now()}.json`);
|
149
|
-
};
|
@@ -1,161 +0,0 @@
|
|
1
|
-
import type { HeadersData } from "./index.js";
|
2
|
-
|
3
|
-
const securityChecks: HeadersData[] = [
|
4
|
-
{
|
5
|
-
name: "X-Content-Type-Options",
|
6
|
-
description: "Prevents MIME-type sniffing.",
|
7
|
-
recommendation: "nosniff",
|
8
|
-
check: (value: string) => value === "nosniff",
|
9
|
-
},
|
10
|
-
{
|
11
|
-
name: "X-Frame-Options",
|
12
|
-
description: "Mitigates clickjacking attacks.",
|
13
|
-
recommendation: "DENY or SAMEORIGIN",
|
14
|
-
check: (value: string) =>
|
15
|
-
value === "DENY" ||
|
16
|
-
value === "SAMEORIGIN" ||
|
17
|
-
value?.startsWith("ALLOW-FROM"),
|
18
|
-
},
|
19
|
-
{
|
20
|
-
name: "Strict-Transport-Security",
|
21
|
-
description: "Enforces HTTPS and prevents downgrade attacks.",
|
22
|
-
recommendation: "max-age=31536000; includeSubDomains; preload",
|
23
|
-
check: (value: string) =>
|
24
|
-
value?.includes("max-age=") && value.includes("includeSubDomains"),
|
25
|
-
},
|
26
|
-
{
|
27
|
-
name: "Content-Security-Policy",
|
28
|
-
description:
|
29
|
-
"Prevents cross-site scripting (XSS) and data injection attacks.",
|
30
|
-
recommendation: "script-src 'self'; object-src 'none'",
|
31
|
-
check: (value: string) => !!value,
|
32
|
-
},
|
33
|
-
{
|
34
|
-
name: "Referrer-Policy",
|
35
|
-
description:
|
36
|
-
"Controls how much referrer information is included with requests.",
|
37
|
-
recommendation: "no-referrer or strict-origin",
|
38
|
-
check: (value: string) =>
|
39
|
-
[
|
40
|
-
"no-referrer",
|
41
|
-
"strict-origin",
|
42
|
-
"strict-origin-when-cross-origin",
|
43
|
-
].includes(value ?? ""),
|
44
|
-
},
|
45
|
-
{
|
46
|
-
name: "Permissions-Policy",
|
47
|
-
description: "Manages permissions of APIs (e.g., camera, geolocation).",
|
48
|
-
recommendation: "default settings for better privacy",
|
49
|
-
check: (value: string) => !!value,
|
50
|
-
},
|
51
|
-
{
|
52
|
-
name: "Cross-Origin-Embedder-Policy",
|
53
|
-
description:
|
54
|
-
"Prevents a document from loading any cross-origin resources that don't explicitly grant permission.",
|
55
|
-
recommendation: "require-corp",
|
56
|
-
check: (value: string) => value === "require-corp",
|
57
|
-
},
|
58
|
-
{
|
59
|
-
name: "Cross-Origin-Opener-Policy",
|
60
|
-
description:
|
61
|
-
"Prevents other domains from taking control of your context via window.opener.",
|
62
|
-
recommendation: "same-origin",
|
63
|
-
check: (value: string) => value === "same-origin",
|
64
|
-
},
|
65
|
-
{
|
66
|
-
name: "Cross-Origin-Resource-Policy",
|
67
|
-
description: "Prevents your resources from being used by other sites.",
|
68
|
-
recommendation: "same-origin",
|
69
|
-
check: (value: string) => value === "same-origin" || value === "same-site",
|
70
|
-
},
|
71
|
-
];
|
72
|
-
|
73
|
-
const informationLeakChecks: HeadersData[] = [
|
74
|
-
{
|
75
|
-
name: "Server",
|
76
|
-
description: "Reveals server software information.",
|
77
|
-
recommendation: "Remove or obfuscate this header.",
|
78
|
-
check: (value: string) => !value,
|
79
|
-
},
|
80
|
-
{
|
81
|
-
name: "X-Powered-By",
|
82
|
-
description:
|
83
|
-
"Reveals information about the framework (e.g., Express, PHP).",
|
84
|
-
recommendation: "Remove or set to a generic value.",
|
85
|
-
check: (value: string) => !value,
|
86
|
-
},
|
87
|
-
{
|
88
|
-
name: "X-AspNet-Version",
|
89
|
-
description: "Reveals ASP.NET version.",
|
90
|
-
recommendation: "Remove this header.",
|
91
|
-
check: (value: string) => !value,
|
92
|
-
},
|
93
|
-
{
|
94
|
-
name: "X-AspNetMvc-Version",
|
95
|
-
description: "Reveals ASP.NET MVC version.",
|
96
|
-
recommendation: "Remove this header.",
|
97
|
-
check: (value: string) => !value,
|
98
|
-
},
|
99
|
-
{
|
100
|
-
name: "X-PHP-Version",
|
101
|
-
description: "Reveals PHP version.",
|
102
|
-
recommendation: "Disable or remove this header.",
|
103
|
-
check: (value: string) => !value,
|
104
|
-
},
|
105
|
-
{
|
106
|
-
name: "X-Generator",
|
107
|
-
description: "Reveals information about CMS (e.g., WordPress, Joomla).",
|
108
|
-
recommendation: "Remove this header.",
|
109
|
-
check: (value: string) => !value,
|
110
|
-
},
|
111
|
-
{
|
112
|
-
name: "X-Drupal-Dynamic-Cache",
|
113
|
-
description: "Reveals Drupal cache status.",
|
114
|
-
recommendation: "Remove this header.",
|
115
|
-
check: (value: string) => !value,
|
116
|
-
},
|
117
|
-
{
|
118
|
-
name: "X-Runtime",
|
119
|
-
description: "Reveals the application's runtime environment.",
|
120
|
-
recommendation: "Remove this header.",
|
121
|
-
check: (value: string) => !value,
|
122
|
-
},
|
123
|
-
{
|
124
|
-
name: "X-Backend-Server",
|
125
|
-
description: "Leaks information about backend server infrastructure.",
|
126
|
-
recommendation: "Remove or obfuscate this header.",
|
127
|
-
check: (value: string) => !value,
|
128
|
-
},
|
129
|
-
{
|
130
|
-
name: "Via",
|
131
|
-
description: "Reveals intermediate proxies and gateways.",
|
132
|
-
recommendation: "Remove or obfuscate this header.",
|
133
|
-
check: (value: string) => !value,
|
134
|
-
},
|
135
|
-
{
|
136
|
-
name: "X-Cache",
|
137
|
-
description: "Indicates if a resource was served from cache.",
|
138
|
-
recommendation: "Remove this header.",
|
139
|
-
check: (value: string) => !value,
|
140
|
-
},
|
141
|
-
{
|
142
|
-
name: "X-CF-Powered-By",
|
143
|
-
description: "Reveals that the app is behind Cloudflare.",
|
144
|
-
recommendation: "Remove this header.",
|
145
|
-
check: (value: string) => !value,
|
146
|
-
},
|
147
|
-
{
|
148
|
-
name: "X-Edge-IP",
|
149
|
-
description: "Leaks edge server IP addresses.",
|
150
|
-
recommendation: "Remove or obfuscate this header.",
|
151
|
-
check: (value: string) => !value,
|
152
|
-
},
|
153
|
-
{
|
154
|
-
name: "X-Edge-Location",
|
155
|
-
description: "Reveals the physical location of edge servers.",
|
156
|
-
recommendation: "Remove this header.",
|
157
|
-
check: (value: string) => !value,
|
158
|
-
},
|
159
|
-
];
|
160
|
-
|
161
|
-
export { securityChecks, informationLeakChecks };
|