mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-08 05:31:23 +00:00
fix(security): harden hooks module loading
This commit is contained in:
@@ -217,7 +217,6 @@ describe("hooks mapping", () => {
|
||||
expect("skipped" in result).toBe(true);
|
||||
}
|
||||
});
|
||||
|
||||
it("treats null transform as a handled skip", async () => {
|
||||
const configDir = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-config-skip-"));
|
||||
const transformsRoot = path.join(configDir, "hooks", "transforms");
|
||||
|
||||
@@ -144,6 +144,18 @@ describe("gateway server auth/connect", () => {
|
||||
signedAtMs,
|
||||
token: token ?? null,
|
||||
});
|
||||
|
||||
test("ignores requested scopes when device identity is omitted", async () => {
|
||||
const ws = await openWs(port);
|
||||
const res = await connectReq(ws, { device: null });
|
||||
expect(res.ok).toBe(true);
|
||||
|
||||
const health = await rpcReq(ws, "health");
|
||||
expect(health.ok).toBe(false);
|
||||
expect(health.error?.message).toContain("missing scope");
|
||||
|
||||
ws.close();
|
||||
});
|
||||
const device = {
|
||||
id: identity.deviceId,
|
||||
publicKey: publicKeyRawBase64UrlFromPem(identity.publicKeyPem),
|
||||
@@ -493,6 +505,9 @@ describe("gateway server auth/connect", () => {
|
||||
const ws = await openTailscaleWs(port);
|
||||
const res = await connectReq(ws, { token: "secret", device: null });
|
||||
expect(res.ok).toBe(true);
|
||||
const health = await rpcReq(ws, "health");
|
||||
expect(health.ok).toBe(false);
|
||||
expect(health.error?.message).toContain("missing scope");
|
||||
ws.close();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -298,7 +298,9 @@ export function attachGatewayWsMessageHandler(params: {
|
||||
return;
|
||||
}
|
||||
// Default-deny: scopes must be explicit. Empty/missing scopes means no permissions.
|
||||
const scopes = Array.isArray(connectParams.scopes) ? connectParams.scopes : [];
|
||||
// Note: If the client does not present a device identity, we can't bind scopes to a paired
|
||||
// device/token, so we will clear scopes after auth to avoid self-declared permissions.
|
||||
let scopes = Array.isArray(connectParams.scopes) ? connectParams.scopes : [];
|
||||
connectParams.role = role;
|
||||
connectParams.scopes = scopes;
|
||||
|
||||
@@ -428,6 +430,10 @@ export function attachGatewayWsMessageHandler(params: {
|
||||
close(1008, truncateCloseReason(authMessage));
|
||||
};
|
||||
if (!device) {
|
||||
if (scopes.length > 0) {
|
||||
scopes = [];
|
||||
connectParams.scopes = scopes;
|
||||
}
|
||||
const canSkipDevice = sharedAuthOk;
|
||||
|
||||
if (isControlUi && !allowControlUiBypass) {
|
||||
|
||||
Reference in New Issue
Block a user