security-gateway
Version:
A plug-and-play security gateway that detects malicious traffic and redirects it to a decoy API
145 lines (125 loc) • 4.54 kB
JavaScript
// index.js
const express = require('express');
const { createProxyMiddleware } = require('http-proxy-middleware');
const helmet = require('helmet');
const rateLimit = require('express-rate-limit');
const morgan = require('morgan');
const cors = require('cors');
const { v4: uuidv4 } = require('uuid');
const config = require('./config');
const { threatDetection } = require('./middleware/threatDetection');
const { dynamicPatching } = require('./middleware/dynamicPatching');
const { adminDashboard } = require('./middleware/adminDashboard');
const fs = require('fs');
const path = require('path');
// Export a function that creates and configures the security gateway
module.exports = function createSecurityGateway(options = {}) {
// Merge default config with provided options
const mergedConfig = {
...config,
...options
};
// Initialize suspicious IP storage
const suspiciousIPs = new Set();
const suspiciousRequests = [];
// Create Express app
const app = express();
// Logging
app.use(morgan(mergedConfig.server.logFormat));
// Security headers
app.use(helmet());
// Enable CORS
app.use(cors());
// Request body and URL parsing middleware
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
// Rate limiting
if (mergedConfig.security.rateLimit.enabled) {
const limiter = rateLimit({
windowMs: mergedConfig.security.rateLimit.windowMs,
max: mergedConfig.security.rateLimit.max,
standardHeaders: mergedConfig.security.rateLimit.standardHeaders,
legacyHeaders: mergedConfig.security.rateLimit.legacyHeaders,
handler: (req, res) => {
console.log(`Rate limit exceeded for IP: ${req.ip}`);
suspiciousIPs.add(req.ip);
res.status(429).send('Too many requests');
}
});
app.use(limiter);
}
// Admin dashboard
app.get(mergedConfig.endpoints.adminDashboard, (req, res) => {
adminDashboard(req, res, suspiciousIPs, suspiciousRequests);
});
// Apply threat detection middleware
app.use((req, res, next) => {
threatDetection(req, res, next, mergedConfig.security.attackPatterns, suspiciousIPs, suspiciousRequests);
});
// Apply dynamic patching middleware
app.use((req, res, next) => {
dynamicPatching(req, res, next, mergedConfig.security.honeypot);
});
// Route to real API
app.use('/', (req, res, next) => {
// Skip this middleware if we're redirecting to decoy
if (req.useDecoy) {
return next();
}
console.log(`Proxying to REAL API: ${req.url}`);
createProxyMiddleware({
target: mergedConfig.endpoints.realApi,
changeOrigin: true,
pathRewrite: {
[`^/`]: '/',
},
onProxyRes: (proxyRes, req, res) => {
// Add honeypot headers if enabled
if (mergedConfig.security.honeypot.addHeaders) {
proxyRes.headers['x-powered-by'] = mergedConfig.security.honeypot.fakeServerInfo.poweredBy;
proxyRes.headers['server'] = mergedConfig.security.honeypot.fakeServerInfo.server;
}
}
})(req, res, next);
});
// Route to decoy API
app.use('/', (req, res, next) => {
// Only use this middleware if we're redirecting to decoy
if (!req.useDecoy) {
return next();
}
console.log(`Redirecting to DECOY API: ${req.url}`);
createProxyMiddleware({
target: mergedConfig.endpoints.decoyApi,
changeOrigin: true,
pathRewrite: {
[`^/`]: '/',
},
onProxyRes: (proxyRes, req, res) => {
console.log(`Successfully redirected suspicious request to decoy`);
}
})(req, res, next);
});
// Start the server if not being used as middleware
const start = (port = mergedConfig.server.port) => {
return new Promise((resolve) => {
const server = app.listen(port, () => {
console.log(`Security gateway started on port ${port}`);
console.log(`Routing regular traffic to: ${mergedConfig.endpoints.realApi}`);
console.log(`Routing suspicious traffic to: ${mergedConfig.endpoints.decoyApi}`);
resolve(server);
});
});
};
return {
app,
start,
suspiciousIPs,
suspiciousRequests
};
};
// Auto-start server if run directly (not imported as a module)
if (require.main === module) {
const gateway = module.exports();
gateway.start();
}