Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Sanity check identity server passed to bind/unbind. #9802

Merged
merged 5 commits into from
Apr 19, 2021
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/9802.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add some sanity checks to identity server passed to 3PID bind/unbind endpoints.
29 changes: 26 additions & 3 deletions synapse/handlers/identity.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
# limitations under the License.

"""Utilities for interacting with Identity Servers"""

import logging
import urllib.parse
from typing import Awaitable, Callable, Dict, List, Optional, Tuple
Expand All @@ -35,7 +34,11 @@
from synapse.types import JsonDict, Requester
from synapse.util import json_decoder
from synapse.util.hash import sha256_and_url_safe_base64
from synapse.util.stringutils import assert_valid_client_secret, random_string
from synapse.util.stringutils import (
assert_valid_client_secret,
random_string,
valid_id_server_location,
)

from ._base import BaseHandler

Expand Down Expand Up @@ -173,6 +176,11 @@ async def bind_threepid(
server with, if necessary. Required if use_v2 is true
use_v2: Whether to use v2 Identity Service API endpoints. Defaults to True

Raises:
SynapseError: On any of the following conditions
- the supplied id_server is not a valid identity server name
- we failed to contact the supplied identity server

Returns:
The response from the identity server
"""
Expand All @@ -182,6 +190,12 @@ async def bind_threepid(
if id_access_token is None:
use_v2 = False

if not valid_id_server_location(id_server):
raise SynapseError(
400,
"id_server must be a valid hostname with optional port and path components",
)

# Decide which API endpoint URLs to use
headers = {}
bind_data = {"sid": sid, "client_secret": client_secret, "mxid": mxid}
Expand Down Expand Up @@ -270,12 +284,21 @@ async def try_unbind_threepid_with_id_server(
id_server: Identity server to unbind from

Raises:
SynapseError: If we failed to contact the identity server
SynapseError: On any of the following conditions
- the supplied id_server is not a valid identity server name
- we failed to contact the supplied identity server

Returns:
True on success, otherwise False if the identity
server doesn't support unbinding
"""

if not valid_id_server_location(id_server):
raise SynapseError(
400,
"id_server must be a valid hostname with optional port and path components",
)

url = "https://%s/_matrix/identity/api/v1/3pid/unbind" % (id_server,)
url_bytes = "/_matrix/identity/api/v1/3pid/unbind".encode("ascii")

Expand Down
29 changes: 29 additions & 0 deletions synapse/util/stringutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,35 @@ def parse_and_validate_server_name(server_name: str) -> Tuple[str, Optional[int]
return host, port


def valid_id_server_location(id_server: str) -> bool:
"""Check whether an identity server location, such as the one passed as the
`id_server` parameter to `/_matrix/client/r0/account/3pid/bind`, is valid.

A valid identity server location consists of a valid hostname and optional
port number, optionally followed by any number of `/` delimited path
components, without any fragment or query string parts.

Args:
id_server: identity server location string to validate

Returns:
True if valid, False otherwise.
"""

components = id_server.split("/")

host = components[0]

try:
parse_and_validate_server_name(host)
except ValueError:
return False

path = components[1:]

return not path or all("#" not in p and "?" not in p for p in path)
dkasak marked this conversation as resolved.
Show resolved Hide resolved


def parse_and_validate_mxc_uri(mxc: str) -> Tuple[str, Optional[int], str]:
"""Parse the given string as an MXC URI

Expand Down