mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-19 22:10:51 +00:00
test(security): add trusted-proxy audit tests
- Test trusted-proxy mode flagged as critical - Test missing trustedProxies finding - Test missing userHeader finding - Test empty allowUsers warning - Fix env isolation for bind_no_auth test Part of #1560 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
committed by
Peter Steinberger
parent
b4f6e26ae9
commit
097a2f5bd1
@@ -95,23 +95,36 @@ describe("security audit", () => {
|
||||
});
|
||||
|
||||
it("flags non-loopback bind without auth as critical", async () => {
|
||||
const cfg: OpenClawConfig = {
|
||||
gateway: {
|
||||
bind: "lan",
|
||||
auth: {},
|
||||
},
|
||||
};
|
||||
// Clear env tokens so resolveGatewayAuth defaults to mode=none
|
||||
const prevToken = process.env.CLAWDBOT_GATEWAY_TOKEN;
|
||||
const prevPassword = process.env.CLAWDBOT_GATEWAY_PASSWORD;
|
||||
delete process.env.CLAWDBOT_GATEWAY_TOKEN;
|
||||
delete process.env.CLAWDBOT_GATEWAY_PASSWORD;
|
||||
|
||||
const res = await runSecurityAudit({
|
||||
config: cfg,
|
||||
env: {},
|
||||
includeFilesystem: false,
|
||||
includeChannelSecurity: false,
|
||||
});
|
||||
try {
|
||||
const cfg: ClawdbotConfig = {
|
||||
gateway: {
|
||||
bind: "lan",
|
||||
auth: {},
|
||||
},
|
||||
};
|
||||
|
||||
expect(
|
||||
res.findings.some((f) => f.checkId === "gateway.bind_no_auth" && f.severity === "critical"),
|
||||
).toBe(true);
|
||||
const res = await runSecurityAudit({
|
||||
config: cfg,
|
||||
includeFilesystem: false,
|
||||
includeChannelSecurity: false,
|
||||
});
|
||||
|
||||
expect(
|
||||
res.findings.some((f) => f.checkId === "gateway.bind_no_auth" && f.severity === "critical"),
|
||||
).toBe(true);
|
||||
} finally {
|
||||
// Restore env
|
||||
if (prevToken === undefined) delete process.env.CLAWDBOT_GATEWAY_TOKEN;
|
||||
else process.env.CLAWDBOT_GATEWAY_TOKEN = prevToken;
|
||||
if (prevPassword === undefined) delete process.env.CLAWDBOT_GATEWAY_PASSWORD;
|
||||
else process.env.CLAWDBOT_GATEWAY_PASSWORD = prevPassword;
|
||||
}
|
||||
});
|
||||
|
||||
it("warns when non-loopback bind has auth but no auth rate limit", async () => {
|
||||
@@ -593,6 +606,125 @@ describe("security audit", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("flags trusted-proxy auth mode as critical warning", async () => {
|
||||
const cfg: ClawdbotConfig = {
|
||||
gateway: {
|
||||
bind: "lan",
|
||||
trustedProxies: ["10.0.0.1"],
|
||||
auth: {
|
||||
mode: "trusted-proxy",
|
||||
trustedProxy: {
|
||||
userHeader: "x-forwarded-user",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const res = await runSecurityAudit({
|
||||
config: cfg,
|
||||
includeFilesystem: false,
|
||||
includeChannelSecurity: false,
|
||||
});
|
||||
|
||||
expect(res.findings).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
checkId: "gateway.trusted_proxy_auth",
|
||||
severity: "critical",
|
||||
}),
|
||||
]),
|
||||
);
|
||||
});
|
||||
|
||||
it("flags trusted-proxy auth without trustedProxies configured", async () => {
|
||||
const cfg: ClawdbotConfig = {
|
||||
gateway: {
|
||||
bind: "lan",
|
||||
trustedProxies: [],
|
||||
auth: {
|
||||
mode: "trusted-proxy",
|
||||
trustedProxy: {
|
||||
userHeader: "x-forwarded-user",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const res = await runSecurityAudit({
|
||||
config: cfg,
|
||||
includeFilesystem: false,
|
||||
includeChannelSecurity: false,
|
||||
});
|
||||
|
||||
expect(res.findings).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
checkId: "gateway.trusted_proxy_no_proxies",
|
||||
severity: "critical",
|
||||
}),
|
||||
]),
|
||||
);
|
||||
});
|
||||
|
||||
it("flags trusted-proxy auth without userHeader configured", async () => {
|
||||
const cfg: ClawdbotConfig = {
|
||||
gateway: {
|
||||
bind: "lan",
|
||||
trustedProxies: ["10.0.0.1"],
|
||||
auth: {
|
||||
mode: "trusted-proxy",
|
||||
trustedProxy: {} as never,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const res = await runSecurityAudit({
|
||||
config: cfg,
|
||||
includeFilesystem: false,
|
||||
includeChannelSecurity: false,
|
||||
});
|
||||
|
||||
expect(res.findings).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
checkId: "gateway.trusted_proxy_no_user_header",
|
||||
severity: "critical",
|
||||
}),
|
||||
]),
|
||||
);
|
||||
});
|
||||
|
||||
it("warns when trusted-proxy auth allows all users", async () => {
|
||||
const cfg: ClawdbotConfig = {
|
||||
gateway: {
|
||||
bind: "lan",
|
||||
trustedProxies: ["10.0.0.1"],
|
||||
auth: {
|
||||
mode: "trusted-proxy",
|
||||
trustedProxy: {
|
||||
userHeader: "x-forwarded-user",
|
||||
allowUsers: [],
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const res = await runSecurityAudit({
|
||||
config: cfg,
|
||||
includeFilesystem: false,
|
||||
includeChannelSecurity: false,
|
||||
});
|
||||
|
||||
expect(res.findings).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
checkId: "gateway.trusted_proxy_no_allowlist",
|
||||
severity: "warn",
|
||||
}),
|
||||
]),
|
||||
);
|
||||
});
|
||||
|
||||
it("warns when multiple DM senders share the main session", async () => {
|
||||
const cfg: OpenClawConfig = { session: { dmScope: "main" } };
|
||||
const plugins: ChannelPlugin[] = [
|
||||
|
||||
Reference in New Issue
Block a user