disable HTTP/2 CONNECT for secure web proxies

This commit is contained in:
Maximilian Hils 2021-07-20 15:23:25 +02:00
parent d4899574eb
commit ef2795673b
3 changed files with 35 additions and 2 deletions

View File

@ -1,5 +1,11 @@
# Release History
## Unreleased: mitmproxy next
* Don't negotiate HTTP/2 on the outer TLS connection in Secure Web Proxy Mode.
This fixes compatibility with Firefox.
## 16 July 2021: mitmproxy 7.0
### New Proxy Core (@mhils, [blog post](https://www.mitmproxy.org/posts/releases/mitmproxy7/))

View File

@ -8,10 +8,11 @@ from mitmproxy import certs, ctx, exceptions, connection
from mitmproxy.net import tls as net_tls
from mitmproxy.options import CONF_BASENAME
from mitmproxy.proxy import context
from mitmproxy.proxy.layers import tls
from mitmproxy.proxy.layers import tls, modes
# We manually need to specify this, otherwise OpenSSL may select a non-HTTP2 cipher by default.
# https://ssl-config.mozilla.org/#config=old
DEFAULT_CIPHERS = (
'ECDHE-ECDSA-AES128-GCM-SHA256', 'ECDHE-RSA-AES128-GCM-SHA256', 'ECDHE-ECDSA-AES256-GCM-SHA384',
'ECDHE-RSA-AES256-GCM-SHA384', 'ECDHE-ECDSA-CHACHA20-POLY1305', 'ECDHE-RSA-CHACHA20-POLY1305',
@ -149,8 +150,17 @@ class TlsConfig:
dhparams=self.certstore.dhparams,
)
tls_start.ssl_conn = SSL.Connection(ssl_ctx)
# Force HTTP/1 for secure web proxies, we currently don't support CONNECT over HTTP/2.
# There is a proof-of-concept branch at https://github.com/mhils/mitmproxy/tree/http2-proxy,
# but the complexity outweighs the benefits for now.
if len(tls_start.context.layers) == 2 and isinstance(tls_start.context.layers[0], modes.HttpProxy):
client_alpn: Optional[bytes] = b"http/1.1"
else:
client_alpn = client.alpn
tls_start.ssl_conn.set_app_data(AppData(
client_alpn=client.alpn,
client_alpn=client_alpn,
server_alpn=server.alpn,
http2=ctx.options.http2,
))

View File

@ -346,6 +346,23 @@ class ClientTLSLayer(_TLSLayer):
client_hello_parsed: bool = False
def __init__(self, context: context.Context):
if context.client.tls:
# In the case of TLS-over-TLS, we already have client TLS. As the outer TLS connection between client
# and proxy isn't that interesting to us, we just unset the attributes here and keep the inner TLS
# session's attributes.
# Alternatively we could create a new Client instance,
# but for now we keep it simple. There is a proof-of-concept at
# https://github.com/mitmproxy/mitmproxy/commit/9b6e2a716888b7787514733b76a5936afa485352.
context.client.alpn = None
context.client.cipher = None
context.client.sni = None
context.client.timestamp_tls_setup = None
context.client.tls_version = None
context.client.certificate_list = []
context.client.mitmcert = None
context.client.alpn_offers = []
context.client.cipher_list = []
super().__init__(context, context.client)
self.server_tls_available = isinstance(self.context.layers[-2], ServerTLSLayer)
self.recv_buffer = bytearray()