diff --git a/src/components/layout/layout-traffic.tsx b/src/components/layout/layout-traffic.tsx
index 97caa82bf061a400804438eee02556d8f1cc24e4..f97c6cfd7260d012ef34171176f5df5e5616737d 100644
--- a/src/components/layout/layout-traffic.tsx
+++ b/src/components/layout/layout-traffic.tsx
@@ -46,7 +46,7 @@ const LayoutTraffic = () => {
       if (document.visibilityState === "visible") {
         // reconnect websocket
         const { server = "", secret = "" } = clashInfo;
-        connect(`ws://${server}/traffic?token=${secret}`);
+        connect(`ws://${server}/traffic?token=${encodeURIComponent(secret)}`);
       } else {
         disconnect();
       }
diff --git a/src/components/setting/mods/web-ui-viewer.tsx b/src/components/setting/mods/web-ui-viewer.tsx
index ae1bf3194f4b193c0981d1d0c61f5b9c137a377f..8588d3d107925647b25fefe60b80d902328ea4a0 100644
--- a/src/components/setting/mods/web-ui-viewer.tsx
+++ b/src/components/setting/mods/web-ui-viewer.tsx
@@ -60,7 +60,10 @@ export const WebUIViewer = forwardRef<DialogRef>((props, ref) => {
           .trim();
 
         url = url.replaceAll("%port", port || "9090");
-        url = url.replaceAll("%secret", clashInfo.secret || "");
+        url = url.replaceAll(
+          "%secret",
+          encodeURIComponent(clashInfo.secret || "")
+        );
       }
 
       await openWebUrl(url);
diff --git a/src/pages/connections.tsx b/src/pages/connections.tsx
index 3654a6127b39789055b46623d5b11b03f38feb05..535d3c01d7ba00d0c8a965af0a1e915930a5e9cf 100644
--- a/src/pages/connections.tsx
+++ b/src/pages/connections.tsx
@@ -96,7 +96,7 @@ const ConnectionsPage = () => {
     if (!clashInfo) return;
 
     const { server = "", secret = "" } = clashInfo;
-    connect(`ws://${server}/connections?token=${secret}`);
+    connect(`ws://${server}/connections?token=${encodeURIComponent(secret)}`);
 
     return () => {
       disconnect();