I looked a little bit deeper into this and found that this looks
like a missing implementation in mod_proxy_wstunnel.
The proxy_wstunnel_handler() (in modules/proxy/mod_proxy_wstunnel.c)
does not set the "proxy-request-hostname" when it creates the
connection to the backend. When the TLS handshake is done then
(in ssl_io_filter_handshake() (in modules/ssl/ssl_engine_io.c))
this causes the check to be omitted.
Looking into the HTTP Proxy implementation proxy_http_handler()
(of module/proxy/mod_proxy_http.c) sets this.
So I filed a bug that describes the issue in detail and proposes
a fix (which I already tested sucessfully):
Defect summary:
Security: Apache 2.4 not verifying URL hostname against certificate
in SSL handshake for WebSockets
Reference:
https://bz.apache.org/bugzilla/show_bug.cgi?id=61857
2017-12-04 17:04 GMT+01:00 Markus Gausling <[email protected]>:
> Hello,
>
> I am using 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.
>
> I have defined 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>
>
> So a local request to Apache for ws://127.0.0.1:8888/websocket/would
> end up in a request to wss://mywebsocket.org/.
>
> I have also defined 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 means when I map the IP address of mywebsocket.org in /etc/hosts,
> 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").
>
> When I do the similar thing for HTTP (define Reverse Proxy which does
> http-to-https mapping) then Apache corectly refuses the connection as
>
> it realizes that name in certificate provided by server and hostname in
>
> request URL do not match.
>
> Is this a known issue/unimplemented feature or am I missing some
> specific configuration here?
>
> Regards
> Markus
>