-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathnew-index.js
More file actions
291 lines (253 loc) · 7.81 KB
/
new-index.js
File metadata and controls
291 lines (253 loc) · 7.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
/**
* Web Security Tool - Main Entry Point
* A comprehensive tool for analyzing web security
*/
// Import core modules
const { SecurityHeaderChecker } = require('./src/core/scanner');
const { HttpClient } = require('./src/core/http-client');
const config = require('./config/default');
// Import header modules
const headerChecks = {
essential: require('./src/headers/essential'),
advanced: require('./src/headers/advanced'),
cors: require('./src/headers/cors'),
cookies: require('./src/headers/cookies'),
disclosure: require('./src/headers/disclosure')
};
// Import reports
const reports = {
console: require('./src/reports/console-report'),
html: require('./src/reports/html-report'),
json: require('./src/reports/json-report')
};
// Import CLI - Comment this for now to avoid the circular dependency error
// const cli = require('./cli/index');
/**
* Creates a security header checker with all available header modules
* @param {Object} options - Configuration options
* @returns {SecurityHeaderChecker} - Configured security header checker instance
*/
function createDefaultChecker(options = {}) {
// We need to separate header definitions from analyzer functions
const allHeaders = {};
// Essential headers are core security headers
Object.keys(headerChecks.essential).forEach(key => {
allHeaders[key] = headerChecks.essential[key];
});
// Advanced headers are newer security headers
Object.keys(headerChecks.advanced).forEach(key => {
allHeaders[key] = headerChecks.advanced[key];
});
// CORS headers
Object.keys(headerChecks.cors).forEach(key => {
allHeaders[key] = headerChecks.cors[key];
});
// Add cookie headers but not the analyzer
Object.keys(headerChecks.cookies).forEach(key => {
if (key !== 'cookieAnalyzer') {
allHeaders[key] = headerChecks.cookies[key];
}
});
// Set up analyzers properly
const analyzers = {};
// Add the cookie analyzer if it exists
if (headerChecks.cookies.cookieAnalyzer) {
analyzers.cookieAnalyzer = headerChecks.cookies.cookieAnalyzer;
}
// Add the dangerous headers analyzer if it exists
if (headerChecks.disclosure.dangerousHeaders) {
analyzers.dangerousHeaders = headerChecks.disclosure.dangerousHeaders;
}
// Create HTTP client if not provided
const httpClient = options.httpClient || new HttpClient(options);
// Create and return a fully configured checker
return new SecurityHeaderChecker({
httpClient: httpClient,
securityHeaders: allHeaders,
analyzers: analyzers,
...options
});
}
/**
* Scans a URL for security headers and returns the results
* @param {string} url - The URL to scan
* @param {Object} options - Configuration options
* @returns {Promise<Object>} - Scan results
*/
async function scanUrl(url, options = {}) {
if (!url) {
throw new Error('URL is required');
}
try {
const checker = createDefaultChecker(options);
return await checker.checkUrl(url);
} catch (error) {
console.error(`Failed to scan ${url}:`, error.message);
// Return a graceful error result object
return {
url,
status: 'error',
errorMessage: error.message,
timestamp: new Date().toISOString(),
headers: {},
findings: [],
score: 0,
grade: 'F'
};
}
}
/**
* Scans a URL and outputs the results to console
* @param {string} url - The URL to scan
* @param {Object} options - Configuration options
* @returns {Promise<Object>} - Scan results
*/
async function scanAndPrintResults(url, options = {}) {
try {
const results = await scanUrl(url, options);
reports.console.printResults(results);
return results;
} catch (error) {
console.error(`Error during scan of ${url}:`, error.message);
return {
url,
status: 'error',
errorMessage: error.message,
timestamp: new Date().toISOString(),
headers: {},
findings: [],
score: 0,
grade: 'F'
};
}
}
/**
* Scans a URL and generates HTML and JSON reports
* @param {string} url - The URL to scan
* @param {Object} options - Configuration options
* @returns {Promise<Object>} - Object containing results and report paths
*/
async function scanAndGenerateReports(url, options = {}) {
try {
const results = await scanUrl(url, options);
// Generate reports
const htmlReport = reports.html.generateReport(results);
const jsonReport = reports.json.generateReport(results);
// Save reports to files
const fs = require('fs');
const timestamp = new Date().toISOString().replace(/:/g, '-');
// Extract domain for filename
let domain = url.replace(/^https?:\/\//, '').replace(/[^\w.-]/g, '_');
if (domain.length > 30) domain = domain.substring(0, 30);
const htmlFileName = `header_scan_${domain}_${timestamp}.html`;
const jsonFileName = `header_scan_${domain}_${timestamp}.json`;
try {
fs.writeFileSync(htmlFileName, htmlReport);
fs.writeFileSync(jsonFileName, jsonReport);
console.log(`\n📄 HTML report saved to ${htmlFileName}`);
console.log(`📄 JSON report saved to ${jsonFileName}`);
} catch (fileError) {
console.error('Error saving report files:', fileError.message);
}
return {
results,
reports: {
html: htmlFileName,
json: jsonFileName
}
};
} catch (error) {
console.error(`Error generating reports for ${url}:`, error.message);
return {
results: {
url,
status: 'error',
errorMessage: error.message
},
reports: null
};
}
}
/**
* Runs a comprehensive security scan on the provided URL
* @param {string} url - Target URL to scan
* @param {Object} options - Scan options
* @returns {Promise<Object>} - Scan results
*/
async function runScan(url, options = {}) {
if (!url) {
throw new Error('URL is required');
}
console.log(`Starting comprehensive security scan for ${url}`);
try {
// Start with basic security header scan
const headerResults = await scanUrl(url, options);
// Initialize result object with header findings
const results = {
url,
timestamp: new Date().toISOString(),
headerScan: headerResults,
tlsScan: null,
apiScan: null,
complianceMapping: null,
remediation: null
};
// Here you would add additional scan types as they get implemented
// For example:
// if (options.includeTLS) {
// results.tlsScan = await tlsScanner.scan(url, options);
// }
// Generate unified report if requested
if (options.generateReports) {
await scanAndGenerateReports(url, options);
}
return results;
} catch (error) {
console.error(`Error during comprehensive scan of ${url}:`, error.message);
return {
url,
status: 'error',
errorMessage: error.message,
timestamp: new Date().toISOString()
};
}
}
// CLI functionality
function runCli() {
const url = process.argv[2];
if (!url) {
console.log('Usage: node index.js <url>');
console.log('Example: node index.js https://example.com');
process.exit(1);
}
console.log(`🔍 Web Security Tool v${config.version}`);
console.log(`Starting scan for ${url}...`);
scanAndPrintResults(url, { verbose: true })
.then(results => {
if (results.status === 'error') {
console.log('Skipping report generation due to scan errors.');
return null;
}
return scanAndGenerateReports(url);
})
.catch(error => {
console.error('Error running scanner:', error);
process.exit(1);
});
}
// Export public API
module.exports = {
runScan,
scanUrl,
scanAndPrintResults,
scanAndGenerateReports,
createDefaultChecker,
SecurityHeaderChecker,
HttpClient,
headerChecks,
reports
};
// Run CLI if executed directly
if (require.main === module) {
runCli();
}