Skip to content

Instantly share code, notes, and snippets.

@funilrys
Last active August 1, 2022 15:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save funilrys/7ce7bcc8d6957d7b2bb633b3ceaa4b94 to your computer and use it in GitHub Desktop.
Save funilrys/7ce7bcc8d6957d7b2bb633b3ceaa4b94 to your computer and use it in GitHub Desktop.
A quick and dirty way to protect a matrix room against phishing by adding all possible variants of the room name as the room aliases.
"""
protect_matrix_room - A quick and dirty way to protect a matrix room against phishing.
What does it do?
Protects a matrix room against phishing by adding an alias to the room.
The alias is the room name, but in all possible variants.
NOTE: We Only change the between the last point (`.`) and
the first double point `:`.
Example:
If the room name is `#room:matrix.org`, then the alias will be:
#ROOM:matrix.org
#ROOm:matrix.org
#ROoM:matrix.org
#ROom:matrix.org
#RoOM:matrix.org
#RoOm:matrix.org
#RooM:matrix.org
#Room:matrix.org
#rOOM:matrix.org
#rOOm:matrix.org
#rOoM:matrix.org
#rOom:matrix.org
#roOM:matrix.org
#roOm:matrix.org
#rooM:matrix.org
If the room name is `awesome.room:matrix.org`, then the alias will be:
#awesome.ROOM:matrix.org
#awesome.ROOm:matrix.org
#awesome.ROoM:matrix.org
#awesome.ROom:matrix.org
#awesome.RoOM:matrix.org
#awesome.RoOm:matrix.org
#awesome.RooM:matrix.org
#awesome.Room:matrix.org
#awesome.rOOM:matrix.org
#awesome.rOOm:matrix.org
#awesome.rOoM:matrix.org
#awesome.rOom:matrix.org
#awesome.roOM:matrix.org
#awesome.roOm:matrix.org
#awesome.rooM:matrix.org
Author:
Nissar Chababy, @funilrys, contactTATAfunilrysTODTODcom
"""
import itertools
import urllib.parse
from typing import Generator
import requests
def get_next_variant(name: str) -> Generator[str, None, None]:
"""
Returns the next variant of the given name.
:param name: The name to get the next variant of.
:return: The next variant of the given name.
"""
for result in list(
map("".join, itertools.product(*zip(name.upper(), name.lower())))
):
yield result
def add_alias(*, room_name, server, alias: str, raise_error: bool = False) -> bool:
"""
Adds an alias to the given room.
Whqat does it do?
1. Fetch room ID.
2. Assign room ID to alias.
3. Return True if the alias was successfully added. False otherwise.
:param room_name: The name of the room to add the alias to.
:param server: The server to reach out.
:param alias: The alias to add to the room.
:param raise_error:
Whether to raise an error if there is any.
:return: Whether the alias was added to the room.
"""
encoded_room_name = urllib.parse.quote(room_name)
encoded_alias = urllib.parse.quote(alias)
room_url = f"https://{server}/_matrix/client/r0/directory/room/{encoded_room_name}"
room_new_alias_url = (
f"https://{server}/_matrix/client/r0/directory/room/{encoded_alias}"
)
try:
room_req = requests.get(
room_url, headers={"Authorization": f"Bearer {access_token}"}
)
room_req.raise_for_status()
room_data = room_req.json()
new_alias_req = requests.put(
room_new_alias_url,
json={"room_id": room_data["room_id"]},
headers={"Authorization": f"Bearer {access_token}"},
)
new_alias_req.raise_for_status()
return True
except requests.exceptions.HTTPError as exception:
if raise_error and exception.response.status_code not in [409]:
raise exception
return False
if __name__ == "__main__":
# Switch to False if you just want to go through the list of aliases.
raise_on_error = True
# The Fully Qualified Room Name to work with. It must starts with `#`.
# Example: #hello:matrix.org
room_name = ""
# The access token to use to communicate with the server.
#
# To obtain your API Key do as followed:
# Click your account avatar and choose 'All Setting' and go to the sub
# menu 'Help & About' and then scroll to the bottum where to find
# 'Access Token'
#
# Example: xuy_Onwqx_xuy_Onwqx
access_token = ""
if not room_name:
raise ValueError("Room name is required.")
if not access_token:
raise ValueError("Access token is required.")
room_std_name, server = room_name.split(":", 1)
room_std_name = room_std_name[1:]
if "." in room_std_name:
room_prefix, room_std_name = room_std_name.rsplit(".", 1)
else:
room_prefix = ""
for index, new_alias in enumerate(get_next_variant(room_std_name)):
if room_prefix:
fqa = f"#{room_prefix}.{new_alias}:{server}"
else:
fqa = f"#{new_alias}:{server}"
if fqa == room_name:
continue
print(index, "Adding alias:", fqa)
if add_alias(
room_name=room_name, alias=fqa, server=server, raise_error=raise_on_error
):
print("Successfully added alias:", fqa)
else:
print("Couldn't add alias:", fqa)
@spirillen
Copy link

You have a typo:

https://gist.github.com/funilrys/7ce7bcc8d6957d7b2bb633b3ceaa4b94#file-protect_matrix_room-py-L78

Quick userguide:

Set the room name in line 130

room_name = ""

Set your access code from "Help & About" => #Advacned => Access Token in Line 139

access_token = ""

@spirillen
Copy link

spirillen commented Jul 22, 2022

PS: The script fails when it trying to add the already existing name rather than just skip to next

raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 409 Client Error: Conflict for url: https://matrix.org/_matrix/client/r0/directory/room/%23$room_name%3Amatrix.org

@funilrys
Copy link
Author

Hey @spirillen,

the update should fix it 😄

Cheers!

@spirillen
Copy link

spirillen commented Aug 1, 2022

Super I give it a spin later

UPDATE: bin spinning for some time now, and everything seems pine this far :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment