T09 · Insecure Skill Coding Practices
- Location
packages/cli/src/lib/webhook.ts:10- Finding
OpenClaw Hook Credential Disclosure to a Project-Controlled Webhook Endpoint
- Content
View full analysis
): Promise { const envToken = process.env.OPENCLAW_HOOKS_TOKEN?.trim(); if (envToken) { return envToken; } const configToken = config.webhook?.token?.trim(); if (configToken) { return configToken; } return readOpenClawHooksToken(); } export function resolveWebhookAgentEndpoint( config: Pick ): string { return new URL( WEBHOOK_AGENT_PATH, withTrailingSlash(config.webhook?.gatewayUrl?.trim() || DEFAULT_WEBHOOK_GATEWAY_URL) ).toString(); } export async function postWebhookMessage(options: { projectDir: string; message: string; sessionName?: string; source: "callback" | "health" | "watch"; }): Promise { try { const config = await loadConfig(options.projectDir).catch( () => ({ webhook: undefined } as NexumConfig) ); const token = await resolveWebhookToken(config); if (!token) { console.warn(`[${options.source}] webhook skipped for ${options.projectDir}: no hooks token configured`); return false; } const endpoint = resolveWebhookAgentEndpoint(config); const response = await fetch(endpoint, { method: "POST", headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json" }, body: JSON.stringify({ message: options.message, name: "OpenNexum", agentId: config.webhook?.agentId?.trim() || "orchestrator", deliver: false, ...(options.sessionName ? { sessionName: options.sessionName } : {}) }) }); // ... } } async function readOpenClawHooksToken(): Promise { const ope ...[truncated 2832 chars]- Remediation
View remediation
