UNPKG

nehonix-uri-processor

Version:

A powerful URI processor for encoding, decoding, and analyzing URI data securely.

114 lines 4.93 kB
import { randomBytes } from "crypto"; import ipRangeCheck from "ip-range-check"; import { RuleEngine } from "./RuleEngine"; import { ncu } from "../../utils/NehonixCoreUtils"; export class NehonixShield { constructor(config) { this.setupCSP = (req, res, next) => { const nonce = randomBytes(16).toString("base64"); res.locals.cspNonce = nonce; const cspDirectives = this.ruleEngine.getCSPDirectives(nonce); res.setHeader("Content-Security-Policy", cspDirectives); next(); }; this.csrfProtection = (req, res, next) => { if (this.ruleEngine.shouldSkipCSRF(req)) { return next(); } const csrfToken = req.headers["x-csrf-token"] || req.headers["x-xsrf-token"]; const storedToken = req.cookies["csrf-token"]; if (typeof csrfToken === "string") { if (!this.ruleEngine.validateCSRFToken(csrfToken, storedToken)) { return res.status(403).json({ error: "CSRF token validation failed" }); } else { for (const crf of csrfToken) { if (!this.ruleEngine.validateCSRFToken(crf, storedToken)) { return res.status(403).json({ error: "CSRF token validation failed" }); } } } } next(); }; this.configureTrustedProxy = (req, res, next) => { const clientIp = req.ip || req.connection.remoteAddress || ""; req.trusted = this.trustedProxies.includes(clientIp); if (!req.trusted) { delete req.headers["x-forwarded-for"]; delete req.headers["x-forwarded-proto"]; delete req.headers["x-forwarded-host"]; } next(); }; this.secureCoookieSettings = (req, res, next) => { const originalCookie = res.cookie; res.cookie = (name, value, options = {}) => { const secureOptions = this.ruleEngine.getSecureCookieOptions(options); return originalCookie.call(res, name, value, secureOptions); }; next(); }; this.validateRequest = async (req, res, next) => { const url = new URL(`http://mock.nehonix.space/${req.url}`); const urlCheckResult = await ncu.asyncCheckUrl(url.toString()); if (!urlCheckResult.isValid) { return res.status(400).json({ error: "Suspicious or invalid URL pattern", provider: "nehonix.shield", result: urlCheckResult, url: url.toString() }); } const contentLength = parseInt(req.headers["content-length"], 10) || 0; if (contentLength > this.maxPayloadSize) { return res.status(413).json({ error: "Payload too large" }); } if (!await this.ruleEngine.validateRequest(req)) { return res.status(400).json({ error: "Request validation failed" }); } next(); }; this.ipFilter = (req, res, next) => { const clientIp = req.ip || req.connection.remoteAddress || ""; if (this.bannedIPs.includes(clientIp)) { return res.status(403).json({ error: "Access denied" }); } for (const range of this.bannedRanges) { if (ipRangeCheck(clientIp, range.trim())) { return res.status(403).json({ error: "Access denied" }); } } if (!this.ruleEngine.validateIP(clientIp)) { return res.status(403).json({ error: "IP validation failed" }); } next(); }; this.additionalSecurityHeaders = (req, res, next) => { const headers = this.ruleEngine.getSecurityHeaders(req); Object.entries(headers).forEach(([key, value]) => { res.setHeader(key, value); }); next(); }; this.trustedProxies = config.trustedProxies || []; this.bannedIPs = config.bannedIPs || []; this.bannedRanges = config.bannedRanges || []; this.maxPayloadSize = config.maxPayloadSize || 1000000; this.ruleEngine = new RuleEngine(config.customRules || []); } applyMiddleware(app) { app.use(this.configureTrustedProxy); app.use(this.setupCSP); app.use(this.secureCoookieSettings); app.use(this.validateRequest); app.use(this.ipFilter); app.use(this.additionalSecurityHeaders); app.use(this.csrfProtection); return app; } loadRules(rules) { this.ruleEngine.loadRules(rules); } } //# sourceMappingURL=NehonixShield.js.map