Abstract the code to blacklist IP address resolutions.
parent
82c067d2e8
commit
f559354dd1
|
@ -125,7 +125,7 @@ def _make_scheduler(reactor):
|
||||||
return _scheduler
|
return _scheduler
|
||||||
|
|
||||||
|
|
||||||
class IPBlacklistingResolver:
|
class _IPBlacklistingResolver:
|
||||||
"""
|
"""
|
||||||
A proxy for reactor.nameResolver which only produces non-blacklisted IP
|
A proxy for reactor.nameResolver which only produces non-blacklisted IP
|
||||||
addresses, preventing DNS rebinding attacks on URL preview.
|
addresses, preventing DNS rebinding attacks on URL preview.
|
||||||
|
@ -199,6 +199,35 @@ class IPBlacklistingResolver:
|
||||||
return r
|
return r
|
||||||
|
|
||||||
|
|
||||||
|
@implementer(IReactorPluggableNameResolver)
|
||||||
|
class BlacklistingReactorWrapper:
|
||||||
|
"""
|
||||||
|
A Reactor wrapper which will prevent DNS resolution to blacklisted IP
|
||||||
|
addresses, to prevent DNS rebinding.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
reactor: IReactorPluggableNameResolver,
|
||||||
|
ip_whitelist: Optional[IPSet],
|
||||||
|
ip_blacklist: IPSet,
|
||||||
|
):
|
||||||
|
self._reactor = reactor
|
||||||
|
|
||||||
|
# We need to use a DNS resolver which filters out blacklisted IP
|
||||||
|
# addresses, to prevent DNS rebinding.
|
||||||
|
self._nameResolver = _IPBlacklistingResolver(
|
||||||
|
self._reactor, ip_whitelist, ip_blacklist
|
||||||
|
)
|
||||||
|
|
||||||
|
def __getattr__(self, attr: str) -> Any:
|
||||||
|
# Passthrough to the real reactor except for the DNS resolver.
|
||||||
|
if attr == "nameResolver":
|
||||||
|
return self._nameResolver
|
||||||
|
else:
|
||||||
|
return getattr(self._reactor, attr)
|
||||||
|
|
||||||
|
|
||||||
class BlacklistingAgentWrapper(Agent):
|
class BlacklistingAgentWrapper(Agent):
|
||||||
"""
|
"""
|
||||||
An Agent wrapper which will prevent access to IP addresses being accessed
|
An Agent wrapper which will prevent access to IP addresses being accessed
|
||||||
|
@ -292,22 +321,11 @@ class SimpleHttpClient:
|
||||||
self.user_agent = self.user_agent.encode("ascii")
|
self.user_agent = self.user_agent.encode("ascii")
|
||||||
|
|
||||||
if self._ip_blacklist:
|
if self._ip_blacklist:
|
||||||
real_reactor = hs.get_reactor()
|
|
||||||
# If we have an IP blacklist, we need to use a DNS resolver which
|
# If we have an IP blacklist, we need to use a DNS resolver which
|
||||||
# filters out blacklisted IP addresses, to prevent DNS rebinding.
|
# filters out blacklisted IP addresses, to prevent DNS rebinding.
|
||||||
nameResolver = IPBlacklistingResolver(
|
self.reactor = BlacklistingReactorWrapper(
|
||||||
real_reactor, self._ip_whitelist, self._ip_blacklist
|
hs.get_reactor(), self._ip_whitelist, self._ip_blacklist
|
||||||
)
|
)
|
||||||
|
|
||||||
@implementer(IReactorPluggableNameResolver)
|
|
||||||
class Reactor:
|
|
||||||
def __getattr__(_self, attr):
|
|
||||||
if attr == "nameResolver":
|
|
||||||
return nameResolver
|
|
||||||
else:
|
|
||||||
return getattr(real_reactor, attr)
|
|
||||||
|
|
||||||
self.reactor = Reactor()
|
|
||||||
else:
|
else:
|
||||||
self.reactor = hs.get_reactor()
|
self.reactor = hs.get_reactor()
|
||||||
|
|
||||||
|
|
|
@ -26,11 +26,10 @@ import treq
|
||||||
from canonicaljson import encode_canonical_json
|
from canonicaljson import encode_canonical_json
|
||||||
from prometheus_client import Counter
|
from prometheus_client import Counter
|
||||||
from signedjson.sign import sign_json
|
from signedjson.sign import sign_json
|
||||||
from zope.interface import implementer
|
|
||||||
|
|
||||||
from twisted.internet import defer
|
from twisted.internet import defer
|
||||||
from twisted.internet.error import DNSLookupError
|
from twisted.internet.error import DNSLookupError
|
||||||
from twisted.internet.interfaces import IReactorPluggableNameResolver, IReactorTime
|
from twisted.internet.interfaces import IReactorTime
|
||||||
from twisted.internet.task import _EPSILON, Cooperator
|
from twisted.internet.task import _EPSILON, Cooperator
|
||||||
from twisted.web.http_headers import Headers
|
from twisted.web.http_headers import Headers
|
||||||
from twisted.web.iweb import IBodyProducer, IResponse
|
from twisted.web.iweb import IBodyProducer, IResponse
|
||||||
|
@ -45,7 +44,7 @@ from synapse.api.errors import (
|
||||||
from synapse.http import QuieterFileBodyProducer
|
from synapse.http import QuieterFileBodyProducer
|
||||||
from synapse.http.client import (
|
from synapse.http.client import (
|
||||||
BlacklistingAgentWrapper,
|
BlacklistingAgentWrapper,
|
||||||
IPBlacklistingResolver,
|
BlacklistingReactorWrapper,
|
||||||
encode_query_args,
|
encode_query_args,
|
||||||
readBodyToFile,
|
readBodyToFile,
|
||||||
)
|
)
|
||||||
|
@ -221,24 +220,12 @@ class MatrixFederationHttpClient:
|
||||||
self.signing_key = hs.signing_key
|
self.signing_key = hs.signing_key
|
||||||
self.server_name = hs.hostname
|
self.server_name = hs.hostname
|
||||||
|
|
||||||
real_reactor = hs.get_reactor()
|
|
||||||
|
|
||||||
# We need to use a DNS resolver which filters out blacklisted IP
|
# We need to use a DNS resolver which filters out blacklisted IP
|
||||||
# addresses, to prevent DNS rebinding.
|
# addresses, to prevent DNS rebinding.
|
||||||
nameResolver = IPBlacklistingResolver(
|
self.reactor = BlacklistingReactorWrapper(
|
||||||
real_reactor, None, hs.config.federation_ip_range_blacklist
|
hs.get_reactor(), None, hs.config.federation_ip_range_blacklist
|
||||||
)
|
)
|
||||||
|
|
||||||
@implementer(IReactorPluggableNameResolver)
|
|
||||||
class Reactor:
|
|
||||||
def __getattr__(_self, attr):
|
|
||||||
if attr == "nameResolver":
|
|
||||||
return nameResolver
|
|
||||||
else:
|
|
||||||
return getattr(real_reactor, attr)
|
|
||||||
|
|
||||||
self.reactor = Reactor()
|
|
||||||
|
|
||||||
user_agent = hs.version_string
|
user_agent = hs.version_string
|
||||||
if hs.config.user_agent_suffix:
|
if hs.config.user_agent_suffix:
|
||||||
user_agent = "%s %s" % (user_agent, hs.config.user_agent_suffix)
|
user_agent = "%s %s" % (user_agent, hs.config.user_agent_suffix)
|
||||||
|
|
Loading…
Reference in New Issue