aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Kriechbaumer <thomas@kriechbaumer.name>2017-03-09 19:40:42 +0100
committerThomas Kriechbaumer <thomas@kriechbaumer.name>2017-03-10 11:37:25 +0100
commit45bf1ff64d0609a8550d901f731fc21502ad39e9 (patch)
treef7945dfe2edb152152efad1e51aada7a06eeadea
parent98b589385519eb6b27f8be89bb1ba45940d45245 (diff)
downloadmitmproxy-45bf1ff64d0609a8550d901f731fc21502ad39e9.tar.gz
mitmproxy-45bf1ff64d0609a8550d901f731fc21502ad39e9.tar.bz2
mitmproxy-45bf1ff64d0609a8550d901f731fc21502ad39e9.zip
disable h2c prior knowledge connections
-rw-r--r--mitmproxy/addons/__init__.py4
-rw-r--r--mitmproxy/addons/disable_h2c.py41
-rw-r--r--mitmproxy/addons/disable_h2c_upgrade.py21
-rw-r--r--test/mitmproxy/addons/test_disable_h2c.py39
-rw-r--r--test/mitmproxy/addons/test_disable_h2c_upgrade.py17
5 files changed, 82 insertions, 40 deletions
diff --git a/mitmproxy/addons/__init__.py b/mitmproxy/addons/__init__.py
index 16510640..80e3b2cb 100644
--- a/mitmproxy/addons/__init__.py
+++ b/mitmproxy/addons/__init__.py
@@ -4,7 +4,7 @@ from mitmproxy.addons import check_alpn
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
@@ -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(),
diff --git a/mitmproxy/addons/disable_h2c.py b/mitmproxy/addons/disable_h2c.py
new file mode 100644
index 00000000..b43d5207
--- /dev/null
+++ b/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)
diff --git a/mitmproxy/addons/disable_h2c_upgrade.py b/mitmproxy/addons/disable_h2c_upgrade.py
deleted file mode 100644
index f4a36d5f..00000000
--- a/mitmproxy/addons/disable_h2c_upgrade.py
+++ /dev/null
@@ -1,21 +0,0 @@
-class DisableH2CleartextUpgrade:
-
- """
- We currently only support HTTP/2 over a TLS connection. Some clients try
- to upgrade a connection from HTTP/1.1 to h2c, so we need to remove those
- headers to avoid protocol errors if one endpoints suddenly starts sending
- HTTP/2 frames.
- """
-
- def process_flow(self, f):
- if f.request.headers.get('upgrade', '') == 'h2c':
- 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']
-
- # Handlers
-
- def request(self, f):
- self.process_flow(f)
diff --git a/test/mitmproxy/addons/test_disable_h2c.py b/test/mitmproxy/addons/test_disable_h2c.py
new file mode 100644
index 00000000..d4df8390
--- /dev/null
+++ b/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
diff --git a/test/mitmproxy/addons/test_disable_h2c_upgrade.py b/test/mitmproxy/addons/test_disable_h2c_upgrade.py
deleted file mode 100644
index 6cab713d..00000000
--- a/test/mitmproxy/addons/test_disable_h2c_upgrade.py
+++ /dev/null
@@ -1,17 +0,0 @@
-from mitmproxy.addons import disable_h2c_upgrade
-from mitmproxy.test import tflow
-
-
-class TestTermLog:
- def test_simple(self):
- a = disable_h2c_upgrade.DisableH2CleartextUpgrade()
-
- 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