Files
copy-of-local-network-dashb…/server/server.js
2025-09-14 13:09:39 -07:00

92 lines
3.4 KiB
JavaScript

const express = require('express');
const { exec } = require('child_process');
const xml2js = require('xml2js');
const cors = require('cors');
const os = require('os');
const { promisify } = require('util');
const execAsync = promisify(exec);
const app = express();
const port = 3001;
// Use CORS to allow requests from the frontend
app.use(cors());
app.use(express.json());
// Basic validation for CIDR notation
const isValidCIDR = (cidr) => {
const cidrRegex = /^([0-9]{1,3}\.){3}[0-9]{1,3}(\/([0-9]|[1-2][0-9]|3[0-2]))$/;
return cidrRegex.test(cidr);
};
app.post('/api/scan', async (req, res) => {
const { network } = req.body;
if (!network || !isValidCIDR(network)) {
return res.status(400).json({ error: 'Invalid or missing network address in CIDR format (e.g., 192.168.1.0/24).' });
}
// Sanitize input to prevent command injection
// The regex validation is the primary defense here.
const sanitizedNetwork = network;
console.log(`[SCAN STARTED] for network: ${sanitizedNetwork}`);
// Command to find hosts with a wide range of common web ports open and output as XML.
// This is more efficient than scanning all 65535 ports.
const command = `nmap -p 80,443,3000,5000,7878,8080,8443,9000,9090,9091,9443,10000,32400,8000-8999 --open ${sanitizedNetwork} -oX -`;
try {
const { stdout, stderr } = await execAsync(command, { timeout: 300000 }); // 5 minute timeout
if (stderr) {
console.error(`[NMAP STDERR] ${stderr}`);
}
const parser = new xml2js.Parser();
const result = await parser.parseStringPromise(stdout);
const services = [];
if (result.nmaprun && result.nmaprun.host) {
result.nmaprun.host.forEach(host => {
const address = host.address[0].$.addr;
if (host.ports && host.ports[0].port) {
host.ports[0].port.forEach(portInfo => {
const port = portInfo.$.portid;
let url;
if (port === '443') {
url = `https://${address}`;
} else if (port === '80') {
url = `http://${address}`;
} else {
url = `http://${address}:${port}`;
}
const serviceName = portInfo.service && portInfo.service[0].$.name
? portInfo.service[0].$.name.replace(/-http$/, '') // Clean up names like 'http-proxy'
: `Web Service @ ${address}`;
services.push({
name: `${serviceName.charAt(0).toUpperCase() + serviceName.slice(1)} (${port})`,
url: url,
description: `Discovered service on port ${port}.`
});
});
}
});
}
console.log(`[SCAN COMPLETE] Found ${services.length} services on ${sanitizedNetwork}.`);
res.json(services);
} catch (error) {
console.error(`[SCAN FAILED] Error executing nmap:`, error);
res.status(500).json({ error: 'Failed to execute nmap scan. Is nmap installed and in your system PATH?' });
}
});
app.listen(port, () => {
console.log(`Backend server running on http://localhost:${port}`);
});