mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-11 18:03:44 +00:00
fix(security): harden ACP prompt size guardrails
This commit is contained in:
@@ -2,6 +2,7 @@ import type {
|
||||
AgentSideConnection,
|
||||
LoadSessionRequest,
|
||||
NewSessionRequest,
|
||||
PromptRequest,
|
||||
} from "@agentclientprotocol/sdk";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import type { GatewayClient } from "../gateway/client.js";
|
||||
@@ -14,9 +15,11 @@ function createConnection(): AgentSideConnection {
|
||||
} as unknown as AgentSideConnection;
|
||||
}
|
||||
|
||||
function createGateway(): GatewayClient {
|
||||
function createGateway(
|
||||
request: GatewayClient["request"] = vi.fn(async () => ({ ok: true })) as GatewayClient["request"],
|
||||
): GatewayClient {
|
||||
return {
|
||||
request: vi.fn(async () => ({ ok: true })),
|
||||
request,
|
||||
} as unknown as GatewayClient;
|
||||
}
|
||||
|
||||
@@ -37,6 +40,18 @@ function createLoadSessionRequest(sessionId: string, cwd = "/tmp"): LoadSessionR
|
||||
} as unknown as LoadSessionRequest;
|
||||
}
|
||||
|
||||
function createPromptRequest(
|
||||
sessionId: string,
|
||||
text: string,
|
||||
meta: Record<string, unknown> = {},
|
||||
): PromptRequest {
|
||||
return {
|
||||
sessionId,
|
||||
prompt: [{ type: "text", text }],
|
||||
_meta: meta,
|
||||
} as unknown as PromptRequest;
|
||||
}
|
||||
|
||||
describe("acp session creation rate limit", () => {
|
||||
it("rate limits excessive newSession bursts", async () => {
|
||||
const sessionStore = createInMemorySessionStore();
|
||||
@@ -76,3 +91,45 @@ describe("acp session creation rate limit", () => {
|
||||
sessionStore.clearAllSessionsForTest();
|
||||
});
|
||||
});
|
||||
|
||||
describe("acp prompt size hardening", () => {
|
||||
it("rejects oversized prompt blocks without leaking active runs", async () => {
|
||||
const request = vi.fn(async () => ({ ok: true }));
|
||||
const sessionStore = createInMemorySessionStore();
|
||||
const agent = new AcpGatewayAgent(createConnection(), createGateway(request), {
|
||||
sessionStore,
|
||||
});
|
||||
const sessionId = "prompt-limit-oversize";
|
||||
await agent.loadSession(createLoadSessionRequest(sessionId));
|
||||
|
||||
await expect(
|
||||
agent.prompt(createPromptRequest(sessionId, "a".repeat(2 * 1024 * 1024 + 1))),
|
||||
).rejects.toThrow(/maximum allowed size/i);
|
||||
expect(request).not.toHaveBeenCalledWith("chat.send", expect.anything(), expect.anything());
|
||||
const session = sessionStore.getSession(sessionId);
|
||||
expect(session?.activeRunId).toBeNull();
|
||||
expect(session?.abortController).toBeNull();
|
||||
|
||||
sessionStore.clearAllSessionsForTest();
|
||||
});
|
||||
|
||||
it("rejects oversize final messages from cwd prefix without leaking active runs", async () => {
|
||||
const request = vi.fn(async () => ({ ok: true }));
|
||||
const sessionStore = createInMemorySessionStore();
|
||||
const agent = new AcpGatewayAgent(createConnection(), createGateway(request), {
|
||||
sessionStore,
|
||||
});
|
||||
const sessionId = "prompt-limit-prefix";
|
||||
await agent.loadSession(createLoadSessionRequest(sessionId));
|
||||
|
||||
await expect(
|
||||
agent.prompt(createPromptRequest(sessionId, "a".repeat(2 * 1024 * 1024))),
|
||||
).rejects.toThrow(/maximum allowed size/i);
|
||||
expect(request).not.toHaveBeenCalledWith("chat.send", expect.anything(), expect.anything());
|
||||
const session = sessionStore.getSession(sessionId);
|
||||
expect(session?.activeRunId).toBeNull();
|
||||
expect(session?.abortController).toBeNull();
|
||||
|
||||
sessionStore.clearAllSessionsForTest();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user