Skip to content

Commit

Permalink
disable h2c prior knowledge connections
Browse files Browse the repository at this point in the history
  • Loading branch information
Kriechi committed Mar 10, 2017
1 parent 98b5893 commit 45bf1ff
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 40 deletions.
4 changes: 2 additions & 2 deletions mitmproxy/addons/__init__.py
Expand Up @@ -4,7 +4,7 @@
from mitmproxy.addons import check_ca
from mitmproxy.addons import clientplayback
from mitmproxy.addons import core_option_validation
from mitmproxy.addons import disable_h2c_upgrade
from mitmproxy.addons import disable_h2c
from mitmproxy.addons import onboarding
from mitmproxy.addons import proxyauth
from mitmproxy.addons import replace
Expand All @@ -26,7 +26,7 @@ def default_addons():
check_alpn.CheckALPN(),
check_ca.CheckCA(),
clientplayback.ClientPlayback(),
disable_h2c_upgrade.DisableH2CleartextUpgrade(),
disable_h2c.DisableH2C(),
onboarding.Onboarding(),
proxyauth.ProxyAuth(),
replace.Replace(),
Expand Down
41 changes: 41 additions & 0 deletions mitmproxy/addons/disable_h2c.py
@@ -0,0 +1,41 @@
import mitmproxy


class DisableH2C:

"""
We currently only support HTTP/2 over a TLS connection.
Some clients try to upgrade a connection from HTTP/1.1 to h2c. We need to
remove those headers to avoid protocol errors if one endpoints suddenly
starts sending HTTP/2 frames.
Some clients might use HTTP/2 Prior Knowledge to directly initiate a session
by sending the connection preface. We just kill those flows.
"""

def configure(self, options, updated):
pass

def process_flow(self, f):
if f.request.headers.get('upgrade', '') == 'h2c':
mitmproxy.ctx.log.warn("HTTP/2 cleartext connections (h2c upgrade requests) are currently not supported.")
del f.request.headers['upgrade']
if 'connection' in f.request.headers:
del f.request.headers['connection']
if 'http2-settings' in f.request.headers:
del f.request.headers['http2-settings']

is_connection_preface = (
f.request.method == 'PRI' and
f.request.path == '*' and
f.request.http_version == 'HTTP/2.0'
)
if is_connection_preface:
f.kill()
mitmproxy.ctx.log.warn("Initiating HTTP/2 connections with prior knowledge are currently not supported.")

# Handlers

def request(self, f):
self.process_flow(f)
21 changes: 0 additions & 21 deletions mitmproxy/addons/disable_h2c_upgrade.py

This file was deleted.

39 changes: 39 additions & 0 deletions test/mitmproxy/addons/test_disable_h2c.py
@@ -0,0 +1,39 @@
import io
from mitmproxy import http
from mitmproxy.addons import disable_h2c
from mitmproxy.net.http import http1
from mitmproxy.exceptions import Kill
from mitmproxy.test import tflow
from mitmproxy.test import taddons


class TestDisableH2CleartextUpgrade:
def test_upgrade(self):
with taddons.context() as tctx:
a = disable_h2c.DisableH2C()
tctx.configure(a)

f = tflow.tflow()
f.request.headers['upgrade'] = 'h2c'
f.request.headers['connection'] = 'foo'
f.request.headers['http2-settings'] = 'bar'

a.request(f)
assert 'upgrade' not in f.request.headers
assert 'connection' not in f.request.headers
assert 'http2-settings' not in f.request.headers

def test_prior_knowledge(self):
with taddons.context() as tctx:
a = disable_h2c.DisableH2C()
tctx.configure(a)

b = io.BytesIO(b"PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n")
f = tflow.tflow()
f.request = http.HTTPRequest.wrap(http1.read_request(b))
f.reply.handle()
f.intercept()

a.request(f)
assert not f.killable
assert f.reply.value == Kill
17 changes: 0 additions & 17 deletions test/mitmproxy/addons/test_disable_h2c_upgrade.py

This file was deleted.

0 comments on commit 45bf1ff

Please sign in to comment.