@aikidosec/runtime
Advanced tools
Comparing version 1.5.27 to 1.5.28
@@ -16,2 +16,3 @@ "use strict"; | ||
const FunctionsFramework_1 = require("../sources/FunctionsFramework"); | ||
const Hono_1 = require("../sources/Hono"); | ||
const HTTPServer_1 = require("../sources/HTTPServer"); | ||
@@ -88,2 +89,3 @@ const Lambda_1 = require("../sources/Lambda"); | ||
new HTTPServer_1.HTTPServer(), | ||
new Hono_1.Hono(), | ||
]; | ||
@@ -90,0 +92,0 @@ } |
@@ -1,3 +0,4 @@ | ||
/// <reference types="node" /> | ||
import type { IncomingMessage } from "http"; | ||
export declare function getIPAddressFromRequest(req: IncomingMessage): string | undefined; | ||
export declare function getIPAddressFromRequest(req: { | ||
headers: Record<string, unknown>; | ||
remoteAddress: string | undefined; | ||
}): string | undefined; |
@@ -14,6 +14,4 @@ "use strict"; | ||
} | ||
if (req.socket && | ||
req.socket.remoteAddress && | ||
(0, net_1.isIP)(req.socket.remoteAddress)) { | ||
return req.socket.remoteAddress; | ||
if (req.remoteAddress && (0, net_1.isIP)(req.remoteAddress)) { | ||
return req.remoteAddress; | ||
} | ||
@@ -20,0 +18,0 @@ return undefined; |
{ | ||
"name": "@aikidosec/runtime", | ||
"version": "1.5.27", | ||
"version": "1.5.28", | ||
"description": "Aikido runtime protects your application against NoSQL injections and more", | ||
@@ -68,3 +68,4 @@ "repository": "https://github.com/AikidoSec/runtime-node", | ||
"typescript": "^5.3.3", | ||
"undici": "^6.12.0" | ||
"undici": "^6.12.0", | ||
"hono": "^4.4.2" | ||
}, | ||
@@ -71,0 +72,0 @@ "scripts": { |
@@ -37,2 +37,3 @@  | ||
* ✅ [Express](docs/express.md) 4.x | ||
* ✅ [Hono](docs/hono.md) 4.x | ||
@@ -39,0 +40,0 @@ ### Database drivers |
@@ -6,3 +6,3 @@ "use strict"; | ||
function contextFromRequest(req) { | ||
var _a, _b; | ||
var _a, _b, _c; | ||
let route = undefined; | ||
@@ -17,3 +17,6 @@ if (typeof ((_a = req.route) === null || _a === void 0 ? void 0 : _a.path) === "string") { | ||
method: req.method, | ||
remoteAddress: (0, getIPAddressFromRequest_1.getIPAddressFromRequest)(req), | ||
remoteAddress: (0, getIPAddressFromRequest_1.getIPAddressFromRequest)({ | ||
headers: req.headers, | ||
remoteAddress: (_c = req.socket) === null || _c === void 0 ? void 0 : _c.remoteAddress, | ||
}), | ||
body: req.body ? req.body : undefined, | ||
@@ -20,0 +23,0 @@ url: req.protocol + "://" + req.get("host") + req.originalUrl, |
@@ -7,3 +7,3 @@ "use strict"; | ||
const contextFromRequest_1 = require("./contextFromRequest"); | ||
const shouldRateLimitRequest_1 = require("./shouldRateLimitRequest"); | ||
const shouldRateLimitRequest_1 = require("../../ratelimiting/shouldRateLimitRequest"); | ||
function wrapRequestHandler(handler, agent) { | ||
@@ -10,0 +10,0 @@ return (req, res, next) => { |
@@ -7,3 +7,3 @@ "use strict"; | ||
function contextFromRequest(req, body, module) { | ||
var _a; | ||
var _a, _b; | ||
let parsedURL = undefined; | ||
@@ -43,5 +43,8 @@ if (req.url) { | ||
body: parsedBody, | ||
remoteAddress: (0, getIPAddressFromRequest_1.getIPAddressFromRequest)(req), | ||
remoteAddress: (0, getIPAddressFromRequest_1.getIPAddressFromRequest)({ | ||
headers: req.headers, | ||
remoteAddress: (_b = req.socket) === null || _b === void 0 ? void 0 : _b.remoteAddress, | ||
}), | ||
}; | ||
} | ||
exports.contextFromRequest = contextFromRequest; |
/// <reference types="node" /> | ||
import type { RequestListener } from "http"; | ||
import { Agent } from "../../agent/Agent"; | ||
export declare function createRequestListener(listener: Function, module: string, agent: Agent): RequestListener; | ||
export declare function createRequestListener(listener: Function, module: string, agent: Agent, readBody: boolean): RequestListener; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.createRequestListener = void 0; | ||
const stream_1 = require("stream"); | ||
const Context_1 = require("../../agent/Context"); | ||
const getMaxBodySize_1 = require("../../helpers/getMaxBodySize"); | ||
const replaceRequestBody_1 = require("./replaceRequestBody"); | ||
const contextFromRequest_1 = require("./contextFromRequest"); | ||
function createRequestListener(listener, module, agent) { | ||
const readBodyStream_1 = require("./readBodyStream"); | ||
function createRequestListener(listener, module, agent, readBody) { | ||
return async function requestListener(req, res) { | ||
let body = ""; | ||
let bodySize = 0; | ||
const maxBodySize = (0, getMaxBodySize_1.getMaxBodySize)(); | ||
const stream = new stream_1.PassThrough(); | ||
try { | ||
for await (const chunk of req) { | ||
if (bodySize + chunk.length > maxBodySize) { | ||
res.statusCode = 413; | ||
res.end("This request was aborted by Aikido runtime because the body size exceeded the maximum allowed size. Use AIKIDO_MAX_BODY_SIZE_MB to increase the limit."); | ||
agent.getInspectionStatistics().onAbortedRequest(); | ||
return; | ||
} | ||
bodySize += chunk.length; | ||
body += chunk.toString(); | ||
stream.push(chunk); | ||
} | ||
if (!readBody) { | ||
return callListenerWithContext(listener, req, res, module, agent, ""); | ||
} | ||
catch { | ||
res.statusCode = 500; | ||
res.end("Aikido runtime encountered an error while reading the request body."); | ||
const result = await (0, readBodyStream_1.readBodyStream)(req, res, agent); | ||
if (!result.success) { | ||
return; | ||
} | ||
// End the stream | ||
stream.push(null); | ||
// Ensure the body stream can be read again by the application | ||
(0, replaceRequestBody_1.replaceRequestBody)(req, stream); | ||
callListenerWithContext(listener, req, res, module, agent, body); | ||
return callListenerWithContext(listener, req, res, module, agent, result.body); | ||
}; | ||
@@ -43,3 +22,3 @@ } | ||
const context = (0, contextFromRequest_1.contextFromRequest)(req, body, module); | ||
(0, Context_1.runWithContext)(context, () => { | ||
return (0, Context_1.runWithContext)(context, () => { | ||
res.on("finish", () => { | ||
@@ -46,0 +25,0 @@ const context = (0, Context_1.getContext)(); |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.HTTPServer = void 0; | ||
const isPackageInstalled_1 = require("../helpers/isPackageInstalled"); | ||
const isPlainObject_1 = require("../helpers/isPlainObject"); | ||
@@ -8,6 +9,12 @@ const createRequestListener_1 = require("./http-server/createRequestListener"); | ||
wrapRequestListener(args, module, agent) { | ||
// Parse body only if next is installed | ||
// We can only read the body stream once | ||
// This is tricky, see replaceRequestBody(...) | ||
// e.g. Hono uses web requests and web streams | ||
// (uses Readable.toWeb(req) to convert to a web stream) | ||
const parseBody = (0, isPackageInstalled_1.isPackageInstalled)("next"); | ||
// Without options | ||
// http(s).createServer(listener) | ||
if (args.length > 0 && typeof args[0] === "function") { | ||
return [(0, createRequestListener_1.createRequestListener)(args[0], module, agent)]; | ||
return [(0, createRequestListener_1.createRequestListener)(args[0], module, agent, parseBody)]; | ||
} | ||
@@ -19,3 +26,6 @@ // With options | ||
typeof args[1] === "function") { | ||
return [args[0], (0, createRequestListener_1.createRequestListener)(args[1], module, agent)]; | ||
return [ | ||
args[0], | ||
(0, createRequestListener_1.createRequestListener)(args[1], module, agent, parseBody), | ||
]; | ||
} | ||
@@ -22,0 +32,0 @@ return args; |
@@ -6,2 +6,3 @@ "use strict"; | ||
const Context_1 = require("../agent/Context"); | ||
const isJsonContentType_1 = require("../helpers/isJsonContentType"); | ||
const isPlainObject_1 = require("../helpers/isPlainObject"); | ||
@@ -51,3 +52,3 @@ const parseCookies_1 = require("../helpers/parseCookies"); | ||
const headers = event.headers ? normalizeHeaders(event.headers) : {}; | ||
if (!event.body || !isJsonContentType(headers["content-type"] || "")) { | ||
if (!event.body || !(0, isJsonContentType_1.isJsonContentType)(headers["content-type"] || "")) { | ||
return undefined; | ||
@@ -57,11 +58,2 @@ } | ||
} | ||
const jsonContentTypes = [ | ||
"application/json", | ||
"application/vnd.api+json", | ||
"application/csp-report", | ||
"application/x-json", | ||
]; | ||
function isJsonContentType(contentType) { | ||
return jsonContentTypes.some((type) => contentType.includes(type)); | ||
} | ||
function isGatewayEvent(event) { | ||
@@ -68,0 +60,0 @@ return (0, isPlainObject_1.isPlainObject)(event) && "httpMethod" in event && "headers" in event; |
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
255714
249
6010
143
36
18