forked from MirrorHub/synapse
Fix handling of User-Agent headers with bad utf-8. (#8632)
This commit is contained in:
parent
db9ef792f0
commit
c850dd9a8e
8 changed files with 33 additions and 28 deletions
1
changelog.d/8632.bugfix
Normal file
1
changelog.d/8632.bugfix
Normal file
|
@ -0,0 +1 @@
|
|||
Fix handling of User-Agent headers that are invalid UTF-8, which caused user agents of users to not get correctly recorded.
|
|
@ -184,9 +184,7 @@ class Auth:
|
|||
"""
|
||||
try:
|
||||
ip_addr = self.hs.get_ip_from_request(request)
|
||||
user_agent = request.requestHeaders.getRawHeaders(
|
||||
b"User-Agent", default=[b""]
|
||||
)[0].decode("ascii", "surrogateescape")
|
||||
user_agent = request.get_user_agent("")
|
||||
|
||||
access_token = self.get_access_token_from_request(request)
|
||||
|
||||
|
|
|
@ -470,9 +470,7 @@ class AuthHandler(BaseHandler):
|
|||
# authentication flow.
|
||||
await self.store.set_ui_auth_clientdict(sid, clientdict)
|
||||
|
||||
user_agent = request.requestHeaders.getRawHeaders(b"User-Agent", default=[b""])[
|
||||
0
|
||||
].decode("ascii", "surrogateescape")
|
||||
user_agent = request.get_user_agent("")
|
||||
|
||||
await self.store.add_user_agent_ip_to_ui_auth_session(
|
||||
session.session_id, user_agent, clientip
|
||||
|
|
|
@ -212,9 +212,7 @@ class CasHandler:
|
|||
else:
|
||||
if not registered_user_id:
|
||||
# Pull out the user-agent and IP from the request.
|
||||
user_agent = request.requestHeaders.getRawHeaders(
|
||||
b"User-Agent", default=[b""]
|
||||
)[0].decode("ascii", "surrogateescape")
|
||||
user_agent = request.get_user_agent("")
|
||||
ip_address = self.hs.get_ip_from_request(request)
|
||||
|
||||
registered_user_id = await self._registration_handler.register_user(
|
||||
|
|
|
@ -695,9 +695,7 @@ class OidcHandler:
|
|||
return
|
||||
|
||||
# Pull out the user-agent and IP from the request.
|
||||
user_agent = request.requestHeaders.getRawHeaders(b"User-Agent", default=[b""])[
|
||||
0
|
||||
].decode("ascii", "surrogateescape")
|
||||
user_agent = request.get_user_agent("")
|
||||
ip_address = self.hs.get_ip_from_request(request)
|
||||
|
||||
# Call the mapper to register/login the user
|
||||
|
|
|
@ -216,9 +216,7 @@ class SamlHandler:
|
|||
return
|
||||
|
||||
# Pull out the user-agent and IP from the request.
|
||||
user_agent = request.requestHeaders.getRawHeaders(b"User-Agent", default=[b""])[
|
||||
0
|
||||
].decode("ascii", "surrogateescape")
|
||||
user_agent = request.get_user_agent("")
|
||||
ip_address = self.hs.get_ip_from_request(request)
|
||||
|
||||
# Call the mapper to register/login the user
|
||||
|
|
|
@ -109,8 +109,14 @@ class SynapseRequest(Request):
|
|||
method = self.method.decode("ascii")
|
||||
return method
|
||||
|
||||
def get_user_agent(self):
|
||||
return self.requestHeaders.getRawHeaders(b"User-Agent", [None])[-1]
|
||||
def get_user_agent(self, default: str) -> str:
|
||||
"""Return the last User-Agent header, or the given default.
|
||||
"""
|
||||
user_agent = self.requestHeaders.getRawHeaders(b"User-Agent", [None])[-1]
|
||||
if user_agent is None:
|
||||
return default
|
||||
|
||||
return user_agent.decode("ascii", "replace")
|
||||
|
||||
def render(self, resrc):
|
||||
# this is called once a Resource has been found to serve the request; in our
|
||||
|
@ -274,11 +280,7 @@ class SynapseRequest(Request):
|
|||
# with maximum recursion trying to log errors about
|
||||
# the charset problem.
|
||||
# c.f. https://github.com/matrix-org/synapse/issues/3471
|
||||
user_agent = self.get_user_agent()
|
||||
if user_agent is not None:
|
||||
user_agent = user_agent.decode("utf-8", "replace")
|
||||
else:
|
||||
user_agent = "-"
|
||||
user_agent = self.get_user_agent("-")
|
||||
|
||||
code = str(self.code)
|
||||
if not self.finished:
|
||||
|
|
|
@ -394,7 +394,14 @@ class OidcHandlerTestCase(HomeserverTestCase):
|
|||
self.handler._map_userinfo_to_user = simple_async_mock(return_value=user_id)
|
||||
self.handler._auth_handler.complete_sso_login = simple_async_mock()
|
||||
request = Mock(
|
||||
spec=["args", "getCookie", "addCookie", "requestHeaders", "getClientIP"]
|
||||
spec=[
|
||||
"args",
|
||||
"getCookie",
|
||||
"addCookie",
|
||||
"requestHeaders",
|
||||
"getClientIP",
|
||||
"get_user_agent",
|
||||
]
|
||||
)
|
||||
|
||||
code = "code"
|
||||
|
@ -414,9 +421,8 @@ class OidcHandlerTestCase(HomeserverTestCase):
|
|||
request.args[b"code"] = [code.encode("utf-8")]
|
||||
request.args[b"state"] = [state.encode("utf-8")]
|
||||
|
||||
request.requestHeaders = Mock(spec=["getRawHeaders"])
|
||||
request.requestHeaders.getRawHeaders.return_value = [user_agent.encode("ascii")]
|
||||
request.getClientIP.return_value = ip_address
|
||||
request.get_user_agent.return_value = user_agent
|
||||
|
||||
self.get_success(self.handler.handle_oidc_callback(request))
|
||||
|
||||
|
@ -621,7 +627,14 @@ class OidcHandlerTestCase(HomeserverTestCase):
|
|||
self.handler._map_userinfo_to_user = simple_async_mock(return_value=user_id)
|
||||
self.handler._auth_handler.complete_sso_login = simple_async_mock()
|
||||
request = Mock(
|
||||
spec=["args", "getCookie", "addCookie", "requestHeaders", "getClientIP"]
|
||||
spec=[
|
||||
"args",
|
||||
"getCookie",
|
||||
"addCookie",
|
||||
"requestHeaders",
|
||||
"getClientIP",
|
||||
"get_user_agent",
|
||||
]
|
||||
)
|
||||
|
||||
state = "state"
|
||||
|
@ -637,9 +650,8 @@ class OidcHandlerTestCase(HomeserverTestCase):
|
|||
request.args[b"code"] = [b"code"]
|
||||
request.args[b"state"] = [state.encode("utf-8")]
|
||||
|
||||
request.requestHeaders = Mock(spec=["getRawHeaders"])
|
||||
request.requestHeaders.getRawHeaders.return_value = [b"Browser"]
|
||||
request.getClientIP.return_value = "10.0.0.1"
|
||||
request.get_user_agent.return_value = "Browser"
|
||||
|
||||
self.get_success(self.handler.handle_oidc_callback(request))
|
||||
|
||||
|
|
Loading…
Reference in a new issue