mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-30 19:32:27 +00:00
fix: land LINE timing-safe signature validation (#55663) (thanks @gavyngong)
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
34
extensions/line/src/signature.test.ts
Normal file
34
extensions/line/src/signature.test.ts
Normal 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);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user