From c7572fb49c029ab9458898e08939b2845687b609 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me=20Benoit?= Date: Wed, 22 Apr 2026 20:54:58 +0200 Subject: [PATCH] fix(ui-server): harden CSMS credential handling in supervision URL flow - Add autocomplete="off" on supervision password inputs - Reject colon in supervisionUser via Zod regex (RFC 7617) - Strip credentials from broadcast channel error response payloads --- src/charging-station/ChargingStation.ts | 6 +++--- .../ChargingStationWorkerBroadcastChannel.ts | 2 ++ src/charging-station/ui-server/mcp/MCPToolSchemas.ts | 2 ++ ui/web/src/components/actions/AddChargingStations.vue | 1 + ui/web/src/components/actions/SetSupervisionUrl.vue | 1 + 5 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/charging-station/ChargingStation.ts b/src/charging-station/ChargingStation.ts index 674825e1..2cb492c3 100644 --- a/src/charging-station/ChargingStation.ts +++ b/src/charging-station/ChargingStation.ts @@ -994,9 +994,9 @@ export class ChargingStation extends EventEmitter { /** * Updates the supervision server URL and optionally the CSMS basic auth credentials. - * @param url - * @param supervisionUser - * @param supervisionPassword + * @param url - The new supervision server URL + * @param supervisionUser - CSMS basic auth user (undefined preserves existing) + * @param supervisionPassword - CSMS basic auth password (undefined preserves existing) */ public setSupervisionUrl ( url: string, diff --git a/src/charging-station/broadcast-channel/ChargingStationWorkerBroadcastChannel.ts b/src/charging-station/broadcast-channel/ChargingStationWorkerBroadcastChannel.ts index 95b14718..297ed559 100644 --- a/src/charging-station/broadcast-channel/ChargingStationWorkerBroadcastChannel.ts +++ b/src/charging-station/broadcast-channel/ChargingStationWorkerBroadcastChannel.ts @@ -527,6 +527,8 @@ export class ChargingStationWorkerBroadcastChannel extends WorkerBroadcastChanne `${this.chargingStation.logPrefix()} ${moduleName}.requestHandler: Handle request error:`, error ) + delete requestPayload.supervisionPassword + delete requestPayload.supervisionUser responsePayload = { command, errorDetails: error instanceof OCPPError ? error.details : undefined, diff --git a/src/charging-station/ui-server/mcp/MCPToolSchemas.ts b/src/charging-station/ui-server/mcp/MCPToolSchemas.ts index 30c91098..660320d0 100644 --- a/src/charging-station/ui-server/mcp/MCPToolSchemas.ts +++ b/src/charging-station/ui-server/mcp/MCPToolSchemas.ts @@ -69,6 +69,7 @@ const chargingStationOptionsSchema = z.object({ .describe('OCPP server supervision URL(s)'), supervisionUser: z .string() + .regex(/^[^:]*$/, 'must not contain ":"') .optional() .describe('CSMS basic auth user used on the supervision WebSocket'), }) @@ -349,6 +350,7 @@ export const mcpToolSchemas = new Map([ .describe('CSMS basic auth password used on the supervision WebSocket'), supervisionUser: z .string() + .regex(/^[^:]*$/, 'must not contain ":"') .optional() .describe('CSMS basic auth user used on the supervision WebSocket'), url: z.url().describe('The OCPP server supervision URL to set'), diff --git a/ui/web/src/components/actions/AddChargingStations.vue b/ui/web/src/components/actions/AddChargingStations.vue index 8a7f3264..1d7c4a76 100644 --- a/ui/web/src/components/actions/AddChargingStations.vue +++ b/ui/web/src/components/actions/AddChargingStations.vue @@ -76,6 +76,7 @@