diff --git a/src/client_server/typing.rs b/src/client_server/typing.rs
index 60fc1cc44b50c6fb31945d95aa2dd393d6d0a844..413c5400b7889540a932eddf3e02e9c9583842a5 100644
--- a/src/client_server/typing.rs
+++ b/src/client_server/typing.rs
@@ -1,5 +1,5 @@
-use crate::{database::DatabaseGuard, utils, Result, Ruma};
-use ruma::api::client::typing::create_typing_event;
+use crate::{database::DatabaseGuard, Error, utils, Result, Ruma};
+use ruma::api::client::{typing::create_typing_event, error::ErrorKind};
 
 /// # `PUT /_matrix/client/r0/rooms/{roomId}/typing/{userId}`
 ///
@@ -12,6 +12,13 @@ pub async fn create_typing_event_route(
 
     let sender_user = body.sender_user.as_ref().expect("user is authenticated");
 
+    if !db.rooms.is_joined(sender_user, &body.room_id)? {
+        return Err(Error::BadRequest(
+            ErrorKind::Forbidden,
+            "You are not in this room.",
+        ));
+    }
+
     if let Typing::Yes(duration) = body.state {
         db.rooms.edus.typing_add(
             sender_user,
diff --git a/src/server_server.rs b/src/server_server.rs
index e95c4c0f9b21f543c096072dadb2ed5d9e667144..67ad3691c1459d98d5fffc89e99bd326731682ec 100644
--- a/src/server_server.rs
+++ b/src/server_server.rs
@@ -770,17 +770,21 @@ pub async fn send_transaction_message_route(
                 }
             }
             Edu::Typing(typing) => {
-                if typing.typing {
-                    db.rooms.edus.typing_add(
-                        &typing.user_id,
-                        &typing.room_id,
-                        3000 + utils::millis_since_unix_epoch(),
-                        &db.globals,
-                    )?;
-                } else {
-                    db.rooms
-                        .edus
-                        .typing_remove(&typing.user_id, &typing.room_id, &db.globals)?;
+                if db.rooms.is_joined(&typing.user_id, &typing.room_id)? {
+                    if typing.typing {
+                        db.rooms.edus.typing_add(
+                            &typing.user_id,
+                            &typing.room_id,
+                            3000 + utils::millis_since_unix_epoch(),
+                            &db.globals,
+                        )?;
+                    } else {
+                        db.rooms.edus.typing_remove(
+                            &typing.user_id,
+                            &typing.room_id,
+                            &db.globals,
+                        )?;
+                    }
                 }
             }
             Edu::DeviceListUpdate(DeviceListUpdateContent { user_id, .. }) => {