fix(msteams): validate bot attachment content length

This commit is contained in:
Peter Steinberger
2026-05-29 09:18:40 -04:00
parent 7fb91317ba
commit 8f22632a29
2 changed files with 55 additions and 2 deletions

View File

@@ -185,6 +185,49 @@ describe("downloadMSTeamsBotFrameworkAttachment", () => {
expect(runtime.saveCalls[0].buffer.toString("utf-8")).toBe("PDFBYTES");
});
it("skips malformed attachment view content-length before saving media", async () => {
const info = {
name: "report.pdf",
type: "application/pdf",
views: [{ viewId: "original", size: 3 }],
};
const warn = vi.fn();
const fetchFn = createMockFetch([
{
match: /\/v3\/attachments\/att-1$/,
response: new Response(JSON.stringify(info), {
status: 200,
headers: { "content-type": "application/json" },
}),
},
{
match: /\/v3\/attachments\/att-1\/views\/original$/,
response: new Response("PDFBYTES", {
status: 200,
headers: { "content-length": "0x3" },
}),
},
]);
const media = await downloadMSTeamsBotFrameworkAttachment({
serviceUrl: "https://smba.trafficmanager.net/amer/",
attachmentId: "att-1",
tokenProvider: buildTokenProvider(),
maxBytes: 10_000_000,
fetchFn,
fetchFnSupportsDispatcher: true,
resolveFn: resolvePublicHost,
logger: { warn },
});
expect(media).toBeUndefined();
expect(runtime.saveCalls).toHaveLength(0);
expect(warn).toHaveBeenCalledWith(
"msteams botFramework attachmentView invalid content-length",
{ error: "invalid content-length header: 0x3" },
);
});
it("returns undefined when attachment info fetch fails", async () => {
const fetchFn = createMockFetch([
{

View File

@@ -1,3 +1,4 @@
import { parseMediaContentLength } from "openclaw/plugin-sdk/media-runtime";
import { getMSTeamsRuntime } from "../runtime.js";
import { ensureUserAgentHeader } from "../user-agent.js";
import {
@@ -164,8 +165,17 @@ async function saveBotFrameworkAttachmentView(params: {
});
return undefined;
}
const contentLength = response.headers.get("content-length");
if (contentLength && Number(contentLength) > params.maxBytes) {
let contentLength: number | null;
try {
contentLength = parseMediaContentLength(response.headers.get("content-length"));
} catch (err) {
await response.body?.cancel();
params.logger?.warn?.("msteams botFramework attachmentView invalid content-length", {
error: err instanceof Error ? err.message : String(err),
});
return undefined;
}
if (contentLength !== null && contentLength > params.maxBytes) {
await response.body?.cancel();
return undefined;
}