Skip to content
Snippets Groups Projects
Unverified Commit 8afb7b55 authored by Hubert Chathi's avatar Hubert Chathi Committed by GitHub
Browse files

Make handling of federation Authorization header (more) compliant with RFC7230 (#12774)

The main differences are:
- values with delimiters (such as colons) should be quoted, so always
  quote the origin, since it could contain a colon followed by a port
  number
- should allow more than one space after "X-Matrix"
- quoted values with backslash-escaped characters should be unescaped
- names should be case insensitive
parent 37935b51
No related branches found
No related tags found
No related merge requests found
Make handling of federation Authorization header (more) compliant with RFC7230.
......@@ -169,14 +169,16 @@ def _parse_auth_header(header_bytes: bytes) -> Tuple[str, str, str, Optional[str
"""
try:
header_str = header_bytes.decode("utf-8")
params = header_str.split(" ")[1].split(",")
params = re.split(" +", header_str)[1].split(",")
param_dict: Dict[str, str] = {
k: v for k, v in [param.split("=", maxsplit=1) for param in params]
k.lower(): v for k, v in [param.split("=", maxsplit=1) for param in params]
}
def strip_quotes(value: str) -> str:
if value.startswith('"'):
return value[1:-1]
return re.sub(
"\\\\(.)", lambda matchobj: matchobj.group(1), value[1:-1]
)
else:
return value
......
......@@ -747,7 +747,7 @@ class MatrixFederationHttpClient:
for key, sig in request["signatures"][self.server_name].items():
auth_headers.append(
(
'X-Matrix origin=%s,key="%s",sig="%s",destination="%s"'
'X-Matrix origin="%s",key="%s",sig="%s",destination="%s"'
% (
self.server_name,
key,
......
......@@ -17,7 +17,7 @@ from typing import Dict, List, Tuple
from synapse.api.errors import Codes
from synapse.federation.transport.server import BaseFederationServlet
from synapse.federation.transport.server._base import Authenticator
from synapse.federation.transport.server._base import Authenticator, _parse_auth_header
from synapse.http.server import JsonResource, cancellable
from synapse.server import HomeServer
from synapse.types import JsonDict
......@@ -112,3 +112,30 @@ class BaseFederationServletCancellationTests(
expect_cancellation=False,
expected_body={"result": True},
)
class BaseFederationAuthorizationTests(unittest.TestCase):
def test_authorization_header(self) -> None:
"""Tests that the Authorization header is parsed correctly."""
# test a "normal" Authorization header
self.assertEqual(
_parse_auth_header(
b'X-Matrix origin=foo,key="ed25519:1",sig="sig",destination="bar"'
),
("foo", "ed25519:1", "sig", "bar"),
)
# test an Authorization with extra spaces, upper-case names, and escaped
# characters
self.assertEqual(
_parse_auth_header(
b'X-Matrix ORIGIN=foo,KEY="ed25\\519:1",SIG="sig",destination="bar"'
),
("foo", "ed25519:1", "sig", "bar"),
)
self.assertEqual(
_parse_auth_header(
b'X-Matrix origin=foo,key="ed25519:1",sig="sig",destination="bar",extra_field=ignored'
),
("foo", "ed25519:1", "sig", "bar"),
)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment