{"id":"GHSA-xv8g-fj9h-6gmv","aliases":["GO-2026-4661"],"url":"https://o3.security/vulnerability/GHSA-xv8g-fj9h-6gmv","summary":"Linkdave Missing Authentication on REST and WebSocket endpoints","details":"The `linkdave` server does not enforce authentication on its REST and WebSocket routes in versions prior to `0.1.5`.\n\n### Impact\n\nAn attacker with network access to the server port can:\n- Connect to the WebSocket endpoint (`/ws`) and receive a valid `session_id` in the `OpReady` response.\n- Use that session to invoke all REST player controls on any guild corresponding to their session id[1].\n- Enumerate server statistics and runtime information via the unauthenticated `/stats` endpoint (still public after the fix).\n\n[1] If on [`>=0.1.0`](https://github.com/shi-gg/linkdave/releases/tag/v0.1.0), attackers are restricted to creating, controlling and deleting players created within their own session ID.\n\n### Vulnerable Routes\n\nThe following routes were entirely unauthenticated in `>= 0.0.1, < 0.1.5`:\n\n| Method | Path | Description |\n|--------|------|-------------|\n| `POST` | `/sessions/{session_id}/players/{guild_id}/play` | Start audio playback |\n| `POST` | `/sessions/{session_id}/players/{guild_id}/pause` | Pause playback |\n| `POST` | `/sessions/{session_id}/players/{guild_id}/resume` | Resume playback |\n| `POST` | `/sessions/{session_id}/players/{guild_id}/stop` | Stop playback |\n| `POST` | `/sessions/{session_id}/players/{guild_id}/seek` | Seek to position |\n| `PATCH` | `/sessions/{session_id}/players/{guild_id}/volume` | Set volume |\n| `DELETE` | `/sessions/{session_id}/players/{guild_id}` | Disconnect from voice channel |\n| `GET` | `/ws` | WebSocket event stream |\n\n### Patches\n\nUpdate to [`0.1.5`](https://github.com/shi-gg/linkdave/commit/0f9a00d9d549b16278db81fce6dfec350c2abc01).\n\n```diff\n- image: ghcr.io/shi-gg/linkdave:0.1.4\n+ image: ghcr.io/shi-gg/linkdave:latest\n```\nor\n```sh\ndocker pull ghcr.io/shi-gg/linkdave:latest\n```\n\nAfter upgrading, set the `LINKDAVE_PASSWORD` environment variable to a strong secret value. If this variable is left unset, the server will still accept all connections without authentication even on `>= 0.1.5`.\n\n**Server configuration (e.g. `compose.yml`):**\n```sh\nenvironment:\n    LINKDAVE_PASSWORD: ${LINKDAVE_PASSWORD}\n```\n```sh\necho \"LINKDAVE_PASSWORD=$(openssl rand -hex 16)\" >> .env\n```\n\nTo restart the stack, run\n```sh\ndocker compose up -d\n```\n\n**TypeScript client (`0.1.5+`):**\n\nThe client automatically handles authentication. Pass the password when constructing the client:\n```ts\nconst linkdave = new LinkDaveClient({\n    nodes: [\n        {\n            name: \"main\",\n            url: process.env.LINKDAVE_URI,\n            password: process.env.LINKDAVE_PASSWORD\n        }\n    ]\n});\n```\n\n### Workarounds\n\nIf upgrading is not immediately possible, restrict network access to the server's port using a firewall so it is only accessible from trusted internal IP addresses.","published":"2026-03-10T01:18:20Z","modified":"2026-03-23T04:56:29.322172632Z","cvss":null,"epss":null,"cisaKev":null,"exploitsKnown":0,"affectedPackages":[{"ecosystem":"Go","name":"github.com/shi-gg/linkdave","fixedVersion":"0.1.5"}],"fix":{"url":"https://github.com/shi-gg/linkdave/commit/0f9a00d9d549b16278db81fce6dfec350c2abc01","label":"shi-gg/linkdave@0f9a00d"},"references":[{"type":"WEB","url":"https://github.com/shi-gg/linkdave/security/advisories/GHSA-xv8g-fj9h-6gmv"},{"type":"WEB","url":"https://github.com/shi-gg/linkdave/commit/0f9a00d9d549b16278db81fce6dfec350c2abc01"},{"type":"PACKAGE","url":"https://github.com/shi-gg/linkdave"}],"provenance":{"sources":["OSV.dev","FIRST.org (EPSS)"],"lastVerified":"2026-03-23T04:56:29.322172632Z"}}