detect recursive self-connects and stop them (attempt 2)

This commit is contained in:
Maximilian Hils 2021-03-30 09:02:12 +02:00
parent d0e54bc32c
commit 945e4e3ef5
3 changed files with 26 additions and 26 deletions

View File

@ -4,7 +4,7 @@ from typing import Dict, Optional, Tuple
from mitmproxy import command, controller, ctx, flow, http, log, master, options, platform, tcp, websocket
from mitmproxy.flow import Error, Flow
from mitmproxy.proxy import commands, events
from mitmproxy.proxy import commands, events, server_hooks
from mitmproxy.proxy import server
from mitmproxy.proxy.layers.tcp import TcpMessageInjected
from mitmproxy.proxy.layers.websocket import WebSocketMessageInjected
@ -180,3 +180,13 @@ class Proxyserver:
self.inject_event(event)
except ValueError as e:
ctx.log.warn(str(e))
def server_connect(self, ctx: server_hooks.ServerConnectionHookData):
assert ctx.server.address
self_connect = (
ctx.server.address[1] == self.options.listen_port
and
ctx.server.address[0] in ("localhost", "127.0.0.1", "::1", self.options.listen_host)
)
if self_connect:
ctx.server.error = "Stopped mitmproxy from recursively connecting to itself."

View File

@ -142,9 +142,9 @@ class ConnectionHandler(metaclass=abc.ABCMeta):
server=command.connection
)
await self.handle_hook(server_hooks.ServerConnectHook(hook_data))
if command.connection.error:
self.log(f"server connection to {human.format_address(command.connection.address)} killed before connect.")
self.server_event(events.OpenConnectionCompleted(command, "Connection killed."))
if err := command.connection.error:
self.log(f"server connection to {human.format_address(command.connection.address)} killed before connect: {err}")
self.server_event(events.OpenConnectionCompleted(command, f"Connection killed: {err}"))
return
async with self.max_conns[command.connection.address]:

View File

@ -5,9 +5,10 @@ import pytest
from mitmproxy.addons.proxyserver import Proxyserver
from mitmproxy.proxy.layers.http import HTTPMode
from mitmproxy.proxy import layers
from mitmproxy.proxy import layers, server_hooks
from mitmproxy.connection import Address
from mitmproxy.test import taddons, tflow
from mitmproxy.test.tflow import tclient_conn, tserver_conn
class HelperAddon:
@ -162,26 +163,15 @@ async def test_warn_no_nextlayer():
await ps.shutdown_server()
@pytest.mark.asyncio
async def test_self_connect():
def test_self_connect():
server = tserver_conn()
client = tclient_conn()
server.address = ("localhost", 8080)
ps = Proxyserver()
with taddons.context(ps) as tctx:
state = HelperAddon()
state.layers = [
lambda ctx: layers.modes.ReverseProxy(ctx),
lambda ctx: layers.HttpLayer(ctx, HTTPMode.transparent),
lambda ctx: layers.modes.ReverseProxy(ctx),
]
tctx.master.addons.add(state)
tctx.configure(ps, listen_host="127.0.0.1", listen_port=0)
ps.running()
await tctx.master.await_log("Proxy server listening", level="info")
assert ps.server
proxy_addr = ps.server.sockets[0].getsockname()[:2]
tctx.options.mode = f"reverse:{':'.join(str(x) for x in proxy_addr)}"
reader, writer = await asyncio.open_connection(*proxy_addr)
writer.write(b"GET / HTTP/1.1\r\n\r\n")
assert b"502 Bad Gateway" in await reader.readuntil(b"\r\n\r\n")
assert b"Stopped mitmproxy from recursively connecting" in await reader.readuntil(b"</html>")
# not calling .running() here to avoid unnecessary socket
ps.options = tctx.options
ps.server_connect(
server_hooks.ServerConnectionHookData(server, client)
)
assert server.error == "Stopped mitmproxy from recursively connecting to itself."