fix: land LINE timing-safe signature validation (#55663) (thanks @gavyngong)

This commit is contained in:
Peter Steinberger
2026-03-29 00:42:33 +00:00
parent 7626d18c64
commit fcc9fd1623
2 changed files with 35 additions and 0 deletions

View File

@@ -8,6 +8,7 @@ Docs: https://docs.openclaw.ai
- macOS/local gateway: stop OpenClaw.app from killing healthy local gateway listeners after startup by recognizing the current `openclaw-gateway` process title and using the current `openclaw gateway` launch shape.
- Memory/QMD: resolve slugified `memory_search` file hints back to the indexed filesystem path before returning search hits, so `memory_get` works again for mixed-case and spaced paths. (#50313) Thanks @erra9x.
- Security/LINE: make webhook signature validation run the timing-safe compare even when the supplied signature length is wrong, closing a small timing side-channel. (#55663) Thanks @gavyngong.
## 2026.3.28-beta.1

View File

@@ -0,0 +1,34 @@
import crypto from "node:crypto";
import { afterEach, describe, expect, it, vi } from "vitest";
import { validateLineSignature } from "./signature.js";
function sign(body: string, secret: string): string {
return crypto.createHmac("SHA256", secret).update(body).digest("base64");
}
describe("validateLineSignature", () => {
afterEach(() => {
vi.restoreAllMocks();
});
it("accepts a valid signature", () => {
const body = JSON.stringify({ events: [{ type: "message" }] });
const secret = "top-secret";
expect(validateLineSignature(body, sign(body, secret), secret)).toBe(true);
});
it("still performs timing-safe comparison when signature length mismatches", () => {
const body = JSON.stringify({ events: [{ type: "message" }] });
const secret = "top-secret";
const spy = vi.spyOn(crypto, "timingSafeEqual");
expect(validateLineSignature(body, "short", secret)).toBe(false);
expect(spy).toHaveBeenCalledTimes(1);
const [left, right] = spy.mock.calls[0] ?? [];
expect(left).toBeInstanceOf(Buffer);
expect(right).toBeInstanceOf(Buffer);
expect(left?.byteLength).toBe(right?.byteLength);
});
});