Add a new get_ip_address_from_request method

This method raises a `SynapseException` if Synapse is unable to extract the IP address of a client from an incoming request. This
typically indicates that there is an invalid configuration in one's reverse proxy.

Raise an exception rather than returning a dummy IP address, as it's typically better to fail loudly in this case.
This commit is contained in:
Andrew Morgan
2025-10-01 16:28:34 +01:00
parent 0615b64bb4
commit 4e333c310a
2 changed files with 49 additions and 0 deletions
+16
View File
@@ -188,6 +188,22 @@ class Auth(Protocol):
request
"""
@staticmethod
def get_ip_address_from_request(request: Request) -> str:
"""
Extract the IPv4 or IPv6 address from a client request.
Args:
request: The request to process.
Returns:
The IPv4 or IPv6 address of the client.
Raises:
SynapseError: If an IP address could not be extracted from the
request.
"""
async def check_user_in_room_or_world_readable(
self, room_id: str, requester: Requester, allow_departed_users: bool = False
) -> Tuple[str, Optional[str]]:
+33
View File
@@ -19,10 +19,12 @@
#
#
import logging
from http import HTTPStatus
from typing import TYPE_CHECKING, Optional, Tuple
from netaddr import IPAddress
from twisted.internet.address import IPv4Address, IPv6Address
from twisted.web.server import Request
from synapse import event_auth
@@ -31,6 +33,7 @@ from synapse.api.errors import (
AuthError,
Codes,
MissingClientTokenError,
SynapseError,
UnstableSpecAuthError,
)
from synapse.appservice import ApplicationService
@@ -291,6 +294,36 @@ class BaseAuth:
return query_params[0].decode("ascii")
@staticmethod
def get_ip_address_from_request(request: Request) -> str:
"""
Extract the IPv4 or IPv6 address from a client request.
Args:
request: The request to process.
Returns:
The IPv4 or IPv6 address of the client.
Raises:
SynapseError: If an IP address could not be extracted from the
request.
"""
client_address = request.getClientAddress()
if not isinstance(client_address, IPv4Address) and not isinstance(
client_address, IPv6Address
):
logger.error(
"Unable to view IP address of the requester. Check that you are setting the X-Forwarded-For header correctly in your reverse proxy. Assuming '127.0.0.1'"
)
raise SynapseError(
HTTPStatus.INTERNAL_SERVER_ERROR,
"Unable to read client IP address",
Codes.UNKNOWN,
)
return client_address.host
@cancellable
async def get_appservice_user(
self, request: Request, access_token: str