Skip to content
Snippets Groups Projects
Commit 163f3efd authored by Tulir Asokan's avatar Tulir Asokan :cat2:
Browse files

Start switching webhook secrets to not contain room ID

parent b17a052d
No related branches found
No related tags found
No related merge requests found
Pipeline #10643 passed
......@@ -33,6 +33,7 @@ if TYPE_CHECKING:
class WebhookInfo(Protocol):
secret: str
old_secret: str
class HandlerFunc(Protocol):
......@@ -109,7 +110,10 @@ class GitHubWebhookReceiver:
secret = webhook_info.secret.encode("utf-8")
digest = f"sha1={hmac.new(secret, text_binary, hashlib.sha1).hexdigest()}"
if not hmac.compare_digest(signature, digest):
return web.Response(status=401, text="Invalid signature")
old_secret = webhook_info.old_secret.encode("utf-8")
old_digest = f"sha1={hmac.new(old_secret, text_binary, hashlib.sha1).hexdigest()}"
if not hmac.compare_digest(signature, old_digest):
return web.Response(status=401, text="Invalid signature")
try:
data = json.loads(text)
except json.JSONDecodeError:
......
......@@ -57,6 +57,7 @@ class GitHubBot(Plugin):
self.clients.load_db()
self.register_handler_class(self.webhook_receiver)
self.register_handler_class(self.webhook_manager)
self.register_handler_class(self.clients)
self.register_handler_class(self.commands)
......
......@@ -21,7 +21,8 @@ import hmac
from sqlalchemy import MetaData, Table, Column, String, Integer, UniqueConstraint, and_
from sqlalchemy.engine.base import Engine
from mautrix.types import UserID, RoomID
from mautrix.types import UserID, RoomID, EventType, StateEvent, RoomTombstoneStateEventContent
from maubot.handlers import event
from ..util import UUIDType
......@@ -61,13 +62,20 @@ class WebhookInfo:
super().__setattr__(key, value)
@property
def secret(self) -> str:
def old_secret(self) -> str:
secret = hmac.new(key=self._secret_key, digestmod=hashlib.sha256)
secret.update(self.id.bytes)
secret.update(self.user_id.encode("utf-8"))
secret.update(self.room_id.encode("utf-8"))
return secret.hexdigest()
@property
def secret(self) -> str:
secret = hmac.new(key=self._secret_key, digestmod=hashlib.sha256)
secret.update(self.id.bytes)
secret.update(self.user_id.encode("utf-8"))
return secret.hexdigest()
class WebhookManager:
_table: Table
......@@ -99,6 +107,18 @@ class WebhookManager:
self._webhooks[info.id] = info
return info
@event.on(EventType.ROOM_TOMBSTONE)
async def handle_room_upgrade(self, evt: StateEvent) -> None:
assert isinstance(evt.content, RoomTombstoneStateEventContent)
self._db.execute(
self._table.update()
.where(self._table.c.room_id == evt.room_id)
.values(room_id=evt.content.replacement_room)
)
for webhook in self._webhooks.values():
if webhook.room_id == evt.room_id:
webhook.room_id = evt.content.replacement_room
def set_github_id(self, info: WebhookInfo, github_id: int) -> WebhookInfo:
self._db.execute(self._table.update()
.where(self._table.c.id == info.id)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment