webSocketOriginAllowed function

bool webSocketOriginAllowed(
  1. String? origin,
  2. String? host,
  3. List<String> allowedOrigins
)

true when a WebSocket upgrade with this origin may open.

A browser always sends Origin on a WebSocket upgrade, and it sends the cookies of the app too. So without this check any site could open a socket as the logged in user (cross-site WebSocket hijacking).

  • no Origin header: allowed. This is not a browser.
  • the origin host and port are the same as the Host header: allowed.
  • the origin is in allowedOrigins (like https://app.example.com), or the list has *: allowed.
  • anything else: not allowed.

Implementation

bool webSocketOriginAllowed(
  String? origin,
  String? host,
  List<String> allowedOrigins,
) {
  if (origin == null) return true;
  if (allowedOrigins.contains('*')) return true;
  String clean = _cleanOrigin(origin);
  for (String allowed in allowedOrigins) {
    if (_cleanOrigin(allowed) == clean) return true;
  }
  if (host == null || host.isEmpty) return false;
  Uri? originUri = Uri.tryParse(origin.trim());
  if (originUri == null || originUri.host.isEmpty) return false;
  Uri? hostUri = Uri.tryParse('${originUri.scheme}://${host.trim()}');
  if (hostUri == null) return false;
  return originUri.host.toLowerCase() == hostUri.host.toLowerCase() &&
      originUri.port == hostUri.port;
}