[Bug 61857] New: Security: Apache 2.4 not verifying URL hostname against certificate in SSL handshake for WebSockets

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

[Bug 61857] New: Security: Apache 2.4 not verifying URL hostname against certificate in SSL handshake for WebSockets

Bugzilla from bugzilla@apache.org
https://bz.apache.org/bugzilla/show_bug.cgi?id=61857

            Bug ID: 61857
           Summary: Security: Apache 2.4 not verifying URL hostname
                    against certificate in SSL handshake for WebSockets
           Product: Apache httpd-2
           Version: 2.4.10
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: major
          Priority: P2
         Component: mod_proxy_wstunnel
          Assignee: [hidden email]
          Reporter: [hidden email]
  Target Milestone: ---

Issue was found in Apache 2.4.10 and is still available in trunk. The Apache
2.4.10 is not verifying URL hostname against certificate in SSL handshake for
WebSockets even when SSLProxyCheckPeerCN and/or SSLProxyCheckPeerName are
enabled.

Configure Apache as a "WebSocket Relay" that allows local clients to connect to
(local) ​Apache using "ws://" and Apache then maps this to "wss://" and passes
the request on to the actual serving backend.

Define a Virtual Host for this:
    <VirtualHost 127.0.0.1:8888>
        SSLProxyEngine On
        ProxyRequests Off

        <Proxy "*">
            Order deny,allow
            Deny from all
            Allow from 127.0.0.1
        </Proxy>

        ProxyPass /websocket/ wss://mywebsocket.org/
    </VirtualHost>

A local request to Apache for ws://​127.0.0.1:8888/​websocket/would end up in a
request to wss://mywebsocket.org/.

Define the following security option (amongst others):
    SSLProxyCheckPeerCN on
    SSLProxyCheckPeerName on
    SSLProxyCheckPeerExpire on
    SSLProxyCACertificateFile "/opt/apache2/mycert.pem"
    SSLProxyVerify require
    SSLProxyVerifyDepth 1

While Apache properly checks if the server provided certificate is not expired
and also matches mycert.pem it does not validate the subject name or the
subject alternative names.

This is a security hole and means e.g. when mapping the IP address of
mywebsocket.org in /etc/hosts on Linux to e.g. to myotherwebsocket.org, then
Apache establishes a secure connection to mywebsocket.org however it does not
complain about the mismatch of the hostname in the request
("myotherwebsocket.org") vs. the one in the certificate provided during TLS
session establishment ("mywebsocket.org").

Doing a similar thing for HTTP (define Reverse Proxy which does http-to-https
mapping) works, i.e. Apache corectly refuses the connection as it realizes that
name in certificate provided by server and hostname in request URL do not
match.

========================================
Source of Apache 2.4.10
-----------------------
The function ssl_io_filter_handshake() (in modules/ssl/ssl_engine_io.c) checks
the peer hostname or the URL (depending on the Apache configuration) against
the CN, agsinst the name or the subjectAltNames in the peer provided
certificate.
It does this only if hostname_note is not empty:
  const char *hostname_note = apr_table_get(c->notes,
                                            "proxy-request-hostname");


In proxy_http_handler() of module/proxy/mod_proxy_http.c the connection
establishment with the backend stores "proxy-request-hostname":

    /* Step Three: Create conn_rec */
    backconn = backend->connection;
    if (!backconn) {
        if ((status = ap_proxy_connection_create_ex(proxy_function,
                                                    backend, r)) != OK)
            break;
        backconn = backend->connection;

        /*
         * On SSL connections set a note on the connection what CN is
         * requested, such that mod_ssl can check if it is requested to do
         * so.
         */
        if (backend->ssl_hostname) {
            apr_table_setn(backend->connection->notes,
                           "proxy-request-hostname",
                           backend->ssl_hostname);
        }
    }

For the WebSocket tunneling in function proxy_wstunnel_handler() (in file:
modules/proxy/mod_proxy_wstunnel.c) adding "proxy-request-hostname" is missing
and as a result later in the TLS/SSL handshake the check is not done.

========================================

My proposed fix is to add the same code used in the HTTP case for the
WebSockets  in function proxy_wstunnel_handler() (file:
modules/proxy/mod_proxy_wstunnel.c) as well:

  /* Step Three: Create conn_rec */
  if (!backend->connection) {
      if ((status = ap_proxy_connection_create(scheme, backend,
                                               c, r->server)) != OK)
          break;

+      /*
+       * On SSL connections set a note on the connection what CN is
+       * requested, such that mod_ssl can check if it is requested to do
+       * so.
+       */
+       if (backend->ssl_hostname) {
+           apr_table_setn(backend->connection->notes,
+                          "proxy-request-hostname",
+                          backend->ssl_hostname);
      }
  }

This is 2.4.10 code but the code in trunk looks slightly different but the fix
should be similar.

--
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

[Bug 61857] Security: Apache 2.4 not verifying URL hostname against certificate in SSL handshake for WebSockets

Bugzilla from bugzilla@apache.org
https://bz.apache.org/bugzilla/show_bug.cgi?id=61857

--- Comment #1 from Yann Ylavic <[hidden email]> ---
Thanks for the report and patch.

Committed in r1818726, such that SSLProxyCheckPeer* directives can be used for
any proxy module (with SSL backend connections).

Does that work for you?

--
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

[Bug 61857] Security: Apache 2.4 not verifying URL hostname against certificate in SSL handshake for WebSockets

Bugzilla from bugzilla@apache.org
In reply to this post by Bugzilla from bugzilla@apache.org
https://bz.apache.org/bugzilla/show_bug.cgi?id=61857

Markus Gausling <[hidden email]> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|---                         |FIXED

--- Comment #2 from Markus Gausling <[hidden email]> ---
Yes looks good.

Thanks
Markus

--
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

[Bug 61857] Security: Apache 2.4 not verifying URL hostname against certificate in SSL handshake for WebSockets

Bugzilla from bugzilla@apache.org
In reply to this post by Bugzilla from bugzilla@apache.org
https://bz.apache.org/bugzilla/show_bug.cgi?id=61857

--- Comment #3 from Yann Ylavic <[hidden email]> ---
Backported to 2.4.x (>= 2.4.40) in r1859844.

--
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]