Add basic domain validation for `DomainSpecificString.is_valid`. (#9071)

This checks that the domain given to `DomainSpecificString.is_valid` (e.g.
`UserID`, `RoomAlias`, etc.) is of a valid form. Previously some validation
was done on the localpart (e.g. the sigil), but not the domain portion.
This commit is contained in:
Patrick Cloke 2021-01-13 07:05:16 -05:00 committed by GitHub
parent aa4d8c1f9a
commit 98a64b7f7f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 12 additions and 1 deletions

1
changelog.d/9071.bugfix Normal file
View File

@ -0,0 +1 @@
Fix "Failed to send request" errors when a client provides an invalid room alias.

View File

@ -37,6 +37,7 @@ from signedjson.key import decode_verify_key_bytes
from unpaddedbase64 import decode_base64 from unpaddedbase64 import decode_base64
from synapse.api.errors import Codes, SynapseError from synapse.api.errors import Codes, SynapseError
from synapse.http.endpoint import parse_and_validate_server_name
if TYPE_CHECKING: if TYPE_CHECKING:
from synapse.appservice.api import ApplicationService from synapse.appservice.api import ApplicationService
@ -257,8 +258,13 @@ class DomainSpecificString(
@classmethod @classmethod
def is_valid(cls: Type[DS], s: str) -> bool: def is_valid(cls: Type[DS], s: str) -> bool:
"""Parses the input string and attempts to ensure it is valid."""
try: try:
cls.from_string(s) obj = cls.from_string(s)
# Apply additional validation to the domain. This is only done
# during is_valid (and not part of from_string) since it is
# possible for invalid data to exist in room-state, etc.
parse_and_validate_server_name(obj.domain)
return True return True
except Exception: except Exception:
return False return False

View File

@ -58,6 +58,10 @@ class RoomAliasTestCase(unittest.HomeserverTestCase):
self.assertEquals(room.to_string(), "#channel:my.domain") self.assertEquals(room.to_string(), "#channel:my.domain")
def test_validate(self):
id_string = "#test:domain,test"
self.assertFalse(RoomAlias.is_valid(id_string))
class GroupIDTestCase(unittest.TestCase): class GroupIDTestCase(unittest.TestCase):
def test_parse(self): def test_parse(self):