Skip to content

Web Client Requires HTTPS

Marc Pope edited this page Jul 25, 2026 · 3 revisions

Web client: why it requires HTTPS

The in-browser client does not work over plain http://. This is a browser restriction, not a CortenDesk setting, and it cannot be worked around in JavaScript. The console itself is fine over HTTP — only the web client is affected.

What you see

Over plain HTTP the browser console shows something like:

Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'digest')

or a WebSocket error before the session opens. Since 0.9.3 the client says so directly instead, on the connect screen.

Why

Browsers restrict certain APIs to a secure context — HTTPS, or localhost. The web client is built on two of them:

  • crypto.subtle (Web Crypto) — the login handshake hashes with SHA-256.
  • VideoDecoder (WebCodecs) — the entire video pipeline.

Outside a secure context both are simply absent. window.isSecureContext is false, and the handshake fails first because it runs first.

A JavaScript crypto fallback would not help. It is a reasonable idea — and CortenDesk already bundles libsodium and TweetNaCl, so the hash could be swapped in an afternoon — but the decoder cannot be polyfilled. Doing it would move the failure from the login to the video and change nothing for the operator.

Clipboard sync and file transfer are also secure-context APIs, so they degrade over HTTP too.

Getting HTTPS on an internal network

A self-signed certificate is not enough on its own: browsers only grant a secure context to a certificate they trust, so a self-signed cert has to be installed into the trust store of every machine that connects.

Options, roughly easiest first:

A real certificate for a name that resolves to a private address. This is usually the least work and is widely misunderstood as impossible. Point a public DNS name you own — console.example.com — at the LAN address (10.0.0.50), and issue a certificate with a DNS-01 challenge, which never requires the host to be reachable from the internet. You get a browser-trusted certificate for a service that is only reachable internally, and nothing has to be deployed to client machines.

A reverse proxy that handles certificates for you. Caddy does this in one line, and Traefik or nginx-proxy-manager are equivalent:

console.example.com {
    reverse_proxy localhost:8080
}

Remember the web client also needs /ws/id and /ws/relay proxied with WebSocket upgrade headers — see Install with Docker or Install on a VM.

An internal CA. If you already run one — AD Certificate Services, step-ca, Smallstep — issue from it. The CA root is usually already trusted on managed machines, which is what makes this painless where it applies and painful where it does not.

Chrome enterprise policy, for a managed fleet. If deploying certificates is genuinely not an option, Chrome and Edge can be told to treat a specific origin as trustworthy via the OverrideSecurityRestrictionsOnInsecureOrigin policy, pushed by GPO or MDM. Set it to your console's origin and the browser grants a secure context over HTTP.

This is a real option for a locked-down internal fleet, and it is the only one that requires no certificate at all. It is also a deliberate weakening of a browser security boundary for that origin, so it is worth understanding rather than pasting.

Tailscale, or a similar overlay. Tailscale issues trusted certificates for its own hostnames and needs no public DNS or open ports, which suits a clinic or office network well.

What does not work

  • A self-signed certificate that has not been installed on each client.
  • Clicking through the browser's certificate warning — it loads the page but does not grant a secure context.
  • --unsafely-treat-insecure-origin-as-secure as a permanent answer. It works for one machine for testing; it is a command-line flag, not deployment.

If you cannot use HTTPS at all

The desktop RustDesk client has none of these restrictions. The console's per-device Connect links open it with rustdesk://, so an HTTP-only console is still fully usable for managing devices — you just launch sessions in the desktop app instead of the browser.

Clone this wiki locally