fix(security): enforce bounded webhook body handling
This commit is contained in:
@@ -1,6 +1,11 @@
|
||||
import type { ClawdbotConfig, RuntimeEnv, HistoryEntry } from "openclaw/plugin-sdk";
|
||||
import * as Lark from "@larksuiteoapi/node-sdk";
|
||||
import * as http from "http";
|
||||
import {
|
||||
type ClawdbotConfig,
|
||||
type RuntimeEnv,
|
||||
type HistoryEntry,
|
||||
installRequestBodyLimitGuard,
|
||||
} from "openclaw/plugin-sdk";
|
||||
import type { ResolvedFeishuAccount } from "./types.js";
|
||||
import { resolveFeishuAccount, listEnabledFeishuAccounts } from "./accounts.js";
|
||||
import { handleFeishuMessage, type FeishuMessageEvent, type FeishuBotAddedEvent } from "./bot.js";
|
||||
@@ -18,6 +23,8 @@ export type MonitorFeishuOpts = {
|
||||
const wsClients = new Map<string, Lark.WSClient>();
|
||||
const httpServers = new Map<string, http.Server>();
|
||||
const botOpenIds = new Map<string, string>();
|
||||
const FEISHU_WEBHOOK_MAX_BODY_BYTES = 1024 * 1024;
|
||||
const FEISHU_WEBHOOK_BODY_TIMEOUT_MS = 30_000;
|
||||
|
||||
async function fetchBotOpenId(account: ResolvedFeishuAccount): Promise<string | undefined> {
|
||||
try {
|
||||
@@ -197,7 +204,26 @@ async function monitorWebhook({
|
||||
log(`feishu[${accountId}]: starting Webhook server on port ${port}, path ${path}...`);
|
||||
|
||||
const server = http.createServer();
|
||||
server.on("request", Lark.adaptDefault(path, eventDispatcher, { autoChallenge: true }));
|
||||
const webhookHandler = Lark.adaptDefault(path, eventDispatcher, { autoChallenge: true });
|
||||
server.on("request", (req, res) => {
|
||||
const guard = installRequestBodyLimitGuard(req, res, {
|
||||
maxBytes: FEISHU_WEBHOOK_MAX_BODY_BYTES,
|
||||
timeoutMs: FEISHU_WEBHOOK_BODY_TIMEOUT_MS,
|
||||
responseFormat: "text",
|
||||
});
|
||||
if (guard.isTripped()) {
|
||||
return;
|
||||
}
|
||||
void Promise.resolve(webhookHandler(req, res))
|
||||
.catch((err) => {
|
||||
if (!guard.isTripped()) {
|
||||
error(`feishu[${accountId}]: webhook handler error: ${String(err)}`);
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
guard.dispose();
|
||||
});
|
||||
});
|
||||
httpServers.set(accountId, server);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
Reference in New Issue
Block a user