mirror of
https://github.com/moltbot/moltbot.git
synced 2026-03-07 22:44:16 +00:00
fix(gateway): harden hooks URL parsing (#26864)
This commit is contained in:
@@ -41,10 +41,11 @@ function createHooksConfig(): HooksConfigResolved {
|
||||
function createRequest(params?: {
|
||||
authorization?: string;
|
||||
remoteAddress?: string;
|
||||
url?: string;
|
||||
}): IncomingMessage {
|
||||
return {
|
||||
method: "POST",
|
||||
url: "/hooks/wake",
|
||||
url: params?.url ?? "/hooks/wake",
|
||||
headers: {
|
||||
host: "127.0.0.1:18789",
|
||||
authorization: params?.authorization ?? "Bearer hook-secret",
|
||||
@@ -71,10 +72,11 @@ function createResponse(): {
|
||||
function createHandler(params?: {
|
||||
dispatchWakeHook?: HooksHandlerDeps["dispatchWakeHook"];
|
||||
dispatchAgentHook?: HooksHandlerDeps["dispatchAgentHook"];
|
||||
bindHost?: string;
|
||||
}) {
|
||||
return createHooksRequestHandler({
|
||||
getHooksConfig: () => createHooksConfig(),
|
||||
bindHost: "127.0.0.1",
|
||||
bindHost: params?.bindHost ?? "127.0.0.1",
|
||||
port: 18789,
|
||||
logHooks: {
|
||||
warn: vi.fn(),
|
||||
@@ -139,4 +141,18 @@ describe("createHooksRequestHandler timeout status mapping", () => {
|
||||
expect(mappedRes.statusCode).toBe(429);
|
||||
expect(setHeader).toHaveBeenCalledWith("Retry-After", expect.any(String));
|
||||
});
|
||||
|
||||
test.each(["0.0.0.0", "::"])(
|
||||
"does not throw when bindHost=%s while parsing non-hook request URL",
|
||||
async (bindHost) => {
|
||||
const handler = createHandler({ bindHost });
|
||||
const req = createRequest({ url: "/" });
|
||||
const { res, end } = createResponse();
|
||||
|
||||
const handled = await handler(req, res);
|
||||
|
||||
expect(handled).toBe(false);
|
||||
expect(end).not.toHaveBeenCalled();
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
@@ -208,7 +208,7 @@ export function createHooksRequestHandler(
|
||||
logHooks: SubsystemLogger;
|
||||
} & HookDispatchers,
|
||||
): HooksRequestHandler {
|
||||
const { getHooksConfig, bindHost, port, logHooks, dispatchAgentHook, dispatchWakeHook } = opts;
|
||||
const { getHooksConfig, logHooks, dispatchAgentHook, dispatchWakeHook } = opts;
|
||||
const hookAuthLimiter = createAuthRateLimiter({
|
||||
maxAttempts: HOOK_AUTH_FAILURE_LIMIT,
|
||||
windowMs: HOOK_AUTH_FAILURE_WINDOW_MS,
|
||||
@@ -227,7 +227,9 @@ export function createHooksRequestHandler(
|
||||
if (!hooksConfig) {
|
||||
return false;
|
||||
}
|
||||
const url = new URL(req.url ?? "/", `http://${bindHost}:${port}`);
|
||||
// Only pathname/search are used here; keep the base host fixed so bind-host
|
||||
// representation (e.g. IPv6 wildcards) cannot break request parsing.
|
||||
const url = new URL(req.url ?? "/", "http://localhost");
|
||||
const basePath = hooksConfig.basePath;
|
||||
if (url.pathname !== basePath && !url.pathname.startsWith(`${basePath}/`)) {
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user