UNPKG

@aikidosec/firewall

Version:

Zen by Aikido is an embedded Application Firewall that autonomously protects Node.js apps against common and critical attacks, provides rate limiting, detects malicious traffic (including bots), and more.

102 lines (101 loc) 4.69 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.HTTPServer = void 0; const wrapExport_1 = require("../agent/hooks/wrapExport"); const colorText_1 = require("../helpers/colorText"); const warnBox_1 = require("../helpers/warnBox"); const createRequestListener_1 = require("./http-server/createRequestListener"); const createStreamListener_1 = require("./http-server/http2/createStreamListener"); class HTTPServer { constructor() { this.warnedAboutMissingSource = false; } warnIfNoSourceWrapped(agent) { if (this.warnedAboutMissingSource) { return; } this.warnedAboutMissingSource = true; if (!agent.hasWebFrameworkLoaded()) { // oxlint-disable-next-line no-console console.warn((0, colorText_1.colorText)("red", (0, warnBox_1.warnBox)("Zen detected an HTTP server but no supported web framework. If you use a framework like Express or Fastify, it might be bundled (see https://github.com/AikidoSec/firewall-node/blob/main/docs/bundler.md). For the list of supported frameworks, see https://github.com/AikidoSec/firewall-node#web-frameworks"))); } } wrapRequestListener(args, module, agent) { // Without options // http(s).createServer(listener) if (args.length > 0 && typeof args[0] === "function") { return [(0, createRequestListener_1.createRequestListener)(args[0], module, agent)]; } // With options // http(s).createServer({ ... }, listener) if (args.length > 1 && typeof args[1] === "function") { return [args[0], (0, createRequestListener_1.createRequestListener)(args[1], module, agent)]; } return args; } wrapOn(args, module, agent) { if (args.length < 2 || typeof args[0] !== "string" || typeof args[1] !== "function") { return args; } if (args[0] === "request") { return this.wrapRequestListener(args, module, agent); } if (module === "http2" && args[0] === "stream") { return [args[0], (0, createStreamListener_1.createStreamListener)(args[1], module, agent)]; } return args; } wrap(hooks) { ["http", "https", "http2"].forEach((module) => { hooks.addBuiltinModule(module).onRequire((exports, pkgInfo) => { // Server classes are not exported in the http2 module if (module !== "http2") { (0, wrapExport_1.wrapExport)(exports, "Server", pkgInfo, { kind: undefined, modifyArgs: (args, agent) => { this.warnIfNoSourceWrapped(agent); return this.wrapRequestListener(args, module, agent); }, }); } (0, wrapExport_1.wrapExport)(exports, "createServer", pkgInfo, { kind: undefined, modifyArgs: (args, agent) => { this.warnIfNoSourceWrapped(agent); return this.wrapRequestListener(args, module, agent); }, modifyReturnValue: (args, instance) => { (0, wrapExport_1.wrapExport)(instance, "on", pkgInfo, { kind: undefined, modifyArgs: (args, agent) => { return this.wrapOn(args, module, agent); }, }); return instance; }, }); if (module === "http2") { (0, wrapExport_1.wrapExport)(exports, "createSecureServer", pkgInfo, { kind: undefined, modifyArgs: (args, agent) => { this.warnIfNoSourceWrapped(agent); return this.wrapRequestListener(args, module, agent); }, modifyReturnValue: (args, instance) => { (0, wrapExport_1.wrapExport)(instance, "on", pkgInfo, { kind: undefined, modifyArgs: (args, agent) => { return this.wrapOn(args, module, agent); }, }); return instance; }, }); } }); }); } } exports.HTTPServer = HTTPServer;