From fd406987c1cc56612cf27056aa901c37efd30e8c Mon Sep 17 00:00:00 2001 From: Sorunome Date: Mon, 29 Jun 2020 12:02:18 +0000 Subject: [PATCH] Better validate event contents --- lib/encryption/key_manager.dart | 2 +- lib/matrix_api/matrix_api.dart | 2 +- lib/matrix_api/model/login_response.dart | 2 +- lib/src/database/database.dart | 2 +- lib/src/event.dart | 16 ++++++++-------- lib/src/room.dart | 4 ++-- lib/src/timeline.dart | 4 ++-- 7 files changed, 16 insertions(+), 16 deletions(-) diff --git a/lib/encryption/key_manager.dart b/lib/encryption/key_manager.dart index d9b2a88..e60cacb 100644 --- a/lib/encryption/key_manager.dart +++ b/lib/encryption/key_manager.dart @@ -448,7 +448,7 @@ class KeyManager { /// Handle an incoming to_device event that is related to key sharing Future handleToDeviceEvent(ToDeviceEvent event) async { if (event.type == 'm.room_key_request') { - if (!event.content.containsKey('request_id')) { + if (!(event.content['request_id'] is String)) { return; // invalid event } if (event.content['action'] == 'request') { diff --git a/lib/matrix_api/matrix_api.dart b/lib/matrix_api/matrix_api.dart index d0d716d..8239657 100644 --- a/lib/matrix_api/matrix_api.dart +++ b/lib/matrix_api/matrix_api.dart @@ -1345,7 +1345,7 @@ class MatrixApi { .codeUnits : await streamedResponse.stream.first), ); - if (!jsonResponse.containsKey('content_uri')) { + if (!(jsonResponse['content_uri'] is String)) { throw MatrixException.fromJson(jsonResponse); } return jsonResponse['content_uri']; diff --git a/lib/matrix_api/model/login_response.dart b/lib/matrix_api/model/login_response.dart index 727f6d8..a29627a 100644 --- a/lib/matrix_api/model/login_response.dart +++ b/lib/matrix_api/model/login_response.dart @@ -28,7 +28,7 @@ class LoginResponse { userId = json['user_id']; accessToken = json['access_token']; deviceId = json['device_id']; - if (json.containsKey('well_known')) { + if (json['well_known'] is Map) { wellKnownInformations = WellKnownInformations.fromJson(json['well_known']); } diff --git a/lib/src/database/database.dart b/lib/src/database/database.dart index b033a27..082c585 100644 --- a/lib/src/database/database.dart +++ b/lib/src/database/database.dart @@ -324,7 +324,7 @@ class Database extends _$Database { // is there a transaction id? Then delete the event with this id. if (status != -1 && - eventUpdate.content.containsKey('unsigned') && + eventUpdate.content['unsigned'] is Map && eventUpdate.content['unsigned']['transaction_id'] is String) { await removeEvent(clientId, eventUpdate.content['unsigned']['transaction_id'], chatId); diff --git a/lib/src/event.dart b/lib/src/event.dart index 4beeede..2014ce4 100644 --- a/lib/src/event.dart +++ b/lib/src/event.dart @@ -60,7 +60,7 @@ class Event extends MatrixEvent { /// Optional. The event that redacted this event, if any. Otherwise null. Event get redactedBecause => - unsigned != null && unsigned.containsKey('redacted_because') + unsigned != null && unsigned['redacted_because'] is Map ? Event.fromJson(unsigned['redacted_because'], room) : null; @@ -206,7 +206,7 @@ class Event extends MatrixEvent { unsigned: unsigned, room: room); - String get messageType => (content.containsKey('m.relates_to') && + String get messageType => (content['m.relates_to'] is Map && content['m.relates_to']['m.in_reply_to'] != null) ? MessageTypes.Reply : content['msgtype'] ?? MessageTypes.Text; @@ -353,8 +353,8 @@ class Event extends MatrixEvent { bool get hasThumbnail => content['info'] is Map && - (content['info'].containsKey('thumbnail_url') || - content['info'].containsKey('thumbnail_file')); + (content['info']['thumbnail_url'] is String || + content['info']['thumbnail_file'] is Map); /// Downloads (and decryptes if necessary) the attachment of this /// event and returns it as a [MatrixFile]. If this event doesn't @@ -366,16 +366,16 @@ class Event extends MatrixEvent { throw ("This event has the type '$type' and so it can't contain an attachment."); } if (!getThumbnail && - !content.containsKey('url') && - !content.containsKey('file')) { + !(content['url'] is String) && + !(content['file'] is Map)) { throw ("This event hasn't any attachment."); } if (getThumbnail && !hasThumbnail) { throw ("This event hasn't any thumbnail."); } final isEncrypted = getThumbnail - ? !content['info'].containsKey('thumbnail_url') - : !content.containsKey('url'); + ? !(content['info']['thumbnail_url'] is String) + : !(content['url'] is String); if (isEncrypted && !room.client.encryptionEnabled) { throw ('Encryption is not enabled in your Client.'); diff --git a/lib/src/room.dart b/lib/src/room.dart index a6fa024..045bef5 100644 --- a/lib/src/room.dart +++ b/lib/src/room.dart @@ -931,7 +931,7 @@ class Room { /// Sets this room as a direct chat for this user if not already. Future addToDirectChat(String userID) async { var directChats = client.directChats; - if (directChats.containsKey(userID)) { + if (directChats[userID] is List) { if (!directChats[userID].contains(id)) { directChats[userID].add(id); } else { @@ -952,7 +952,7 @@ class Room { /// Removes this room from all direct chat tags. Future removeFromDirectChat() async { var directChats = client.directChats; - if (directChats.containsKey(directChatMatrixID) && + if (directChats[directChatMatrixID] is List && directChats[directChatMatrixID].contains(id)) { directChats[directChatMatrixID].remove(id); } else { diff --git a/lib/src/timeline.dart b/lib/src/timeline.dart index 42ddb0f..e219733 100644 --- a/lib/src/timeline.dart +++ b/lib/src/timeline.dart @@ -147,11 +147,11 @@ class Timeline { if (i < events.length) events.removeAt(i); } // Is this event already in the timeline? - else if (eventUpdate.content.containsKey('unsigned') && + else if (eventUpdate.content['unsigned'] is Map && eventUpdate.content['unsigned']['transaction_id'] is String) { var i = _findEvent( event_id: eventUpdate.content['event_id'], - unsigned_txid: eventUpdate.content.containsKey('unsigned') + unsigned_txid: eventUpdate.content['unsigned'] is Map ? eventUpdate.content['unsigned']['transaction_id'] : null);