thsmi / sieve

Sieve Script Editor
GNU Affero General Public License v3.0
729 stars 56 forks source link

The WebApp webserver requires a certificate in all cases #879

Open Smith4545 opened 1 year ago

Smith4545 commented 1 year ago

Prerequisites

What happened?

The builtin webserver always requires TLS-certificates, even if the admin explicitly doesn't want to use TLS, because e.g. a reverse proxy is used and the connection between proxy and webapp is purely local.

https://github.com/thsmi/sieve/blob/dfeeac10cb5cf65b08b31360229053bcdae50174/src/web/script/webserver.py#L32-L36

What did you expect to happen?

The common way of running such an application is by using a reverse proxy such as nginx. Normally nginx then terminates TLS and connects unencrypted to a local TCP- or UNIX-Socket. This is done to be able to serve multiple applications on one server using SNI and to prevent possibly insecure TLS implementations being abused by malicious actors (or not to let a buggy TLS implementation abuse the user).

If TLS is enforced the admin has only the choice to provide a snake-oil certificate and to explicitly not let nginx verify it.

Which Version

Include information about your system, server and most important if it is about the app or webextension.

thsmi commented 1 year ago

This is also an interesting one. There was a good reason why I implemented it ssl only. But I don't remember why.

It was some time ago but if I recall it correctly, it is because reverse proxies do not allow downgrading a secure websocket connection to insecure one. But this might be wrong. I have to check my note and read the documentation.

Do you know if nginx prohibits downgrading a secure websocket?

If not it should be a low hanging fruit to change the server to be a plain old http.

And I fully agree there is no point in using a secure connection on a trustworthy backend to backend connection. It just makes stuff unnecessarily complicated. And whoever gains control to the backend normally does not need to do eaves dropping to grab secrets he just reads it from the log files or accesses it directly on the backend.

Smith4545 commented 1 year ago

AFAIK the following applies:

  1. The connection from nginx to the upstream (the web app) can be unencrypted, including for the WebSocket connection. Grafana does this, for example.
  2. The web app must encode the paths that link to the WebSocket in the HTML with wss:, and must not use ws:. This is true even if the web app transmits and receives unencrypted traffic by itself. After nginx wraps TLS around the traffic it effectively is WebSocket Secure. Otherwise, the browser (not nginx) has trouble because of the mixed content.
  3. Whether HTTP or HTTPS is used between reverse proxy <--> browser is usually either set statically in an application's configuration (to ensure 2.) or can be dynamically derived from X-Forwarded-Proto.
  4. (Just for the record) It shouldn't matter that StartTLS is used over the WebSocket as nginx doesn't recognize that anyway.
stale[bot] commented 1 year ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.