Summary
The /api/config API route returns the gateway authentication token in its JSON response, making it accessible to any user who can reach the dashboard.
Location
app/api/config/route.ts — near the end of the GET handler:
const data = {
agents: agentsWithStatus,
providers,
defaults: { model: defaultModel, fallbacks },
gateway: {
port: config.gateway?.port || 18789,
token: config.gateway?.auth?.token || "", // ⚠️ leaks token
host: config.gateway?.host || config.gateway?.hostname || "",
},
groupChats,
};
Impact
- Anyone with access to the dashboard (even read-only) can extract the gateway auth token
- The token grants full control over the OpenClaw gateway (config changes, restarts, session access)
- Especially dangerous if the dashboard is exposed via reverse proxy or tunnel without additional authentication
Proposed Fix
Option A (minimal): Redact the token, expose only a boolean for health check purposes:
gateway: {
port: config.gateway?.port || 18789,
hasToken: !!(config.gateway?.auth?.token),
host: config.gateway?.host || config.gateway?.hostname || "",
},
Then update gateway-health/route.ts to read the token directly from config on the server side (it already does this) rather than receiving it from the client.
Option B (if token is needed for client-side gateway probes): Pass a short-lived HMAC or session-scoped proxy token instead of the raw gateway credential.
Additional Recommendation
Consider adding authentication middleware to the dashboard itself (even a simple env-based password check) since it exposes sensitive operational data including:
- Agent configurations and models
- Session statistics and token usage
- Platform binding details
- Gateway connectivity status
A lightweight approach:
// middleware.ts
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
export function middleware(request: NextRequest) {
const token = request.headers.get("authorization")?.replace("Bearer ", "");
if (token !== process.env.DASHBOARD_TOKEN) {
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
}
}
export const config = { matcher: "/api/:path*" };
Great project overall — just needs this credential exposure patched before production/public use. Happy to submit a PR if preferred.
Summary
The
/api/configAPI route returns the gateway authentication token in its JSON response, making it accessible to any user who can reach the dashboard.Location
app/api/config/route.ts— near the end of theGEThandler:Impact
Proposed Fix
Option A (minimal): Redact the token, expose only a boolean for health check purposes:
Then update
gateway-health/route.tsto read the token directly from config on the server side (it already does this) rather than receiving it from the client.Option B (if token is needed for client-side gateway probes): Pass a short-lived HMAC or session-scoped proxy token instead of the raw gateway credential.
Additional Recommendation
Consider adding authentication middleware to the dashboard itself (even a simple env-based password check) since it exposes sensitive operational data including:
A lightweight approach:
Great project overall — just needs this credential exposure patched before production/public use. Happy to submit a PR if preferred.