28be644
diff --git a/src/twisted/conch/ssh/transport.py b/src/twisted/conch/ssh/transport.py
28be644
index bd76b0a..a477d27 100644
28be644
--- a/src/twisted/conch/ssh/transport.py
28be644
+++ b/src/twisted/conch/ssh/transport.py
28be644
@@ -677,6 +677,14 @@ class SSHTransportBase(protocol.Protocol):
28be644
         """
28be644
         self.buf = self.buf + data
28be644
         if not self.gotVersion:
28be644
+            if len(self.buf) > 4096:
28be644
+                self.sendDisconnect(
28be644
+                    DISCONNECT_CONNECTION_LOST,
28be644
+                    b"Peer version string longer than 4KB. "
28be644
+                    b"Preventing a denial of service attack.",
28be644
+                )
28be644
+                return
28be644
+
28be644
             if self.buf.find(b'\n', self.buf.find(b'SSH-')) == -1:
28be644
                 return
28be644
 
28be644
diff --git a/src/twisted/conch/test/test_transport.py b/src/twisted/conch/test/test_transport.py
28be644
index 98a3515..449dd3f 100644
28be644
--- a/src/twisted/conch/test/test_transport.py
28be644
+++ b/src/twisted/conch/test/test_transport.py
28be644
@@ -522,6 +522,27 @@ class BaseSSHTransportTests(BaseSSHTransportBaseCase, TransportTestCase):
28be644
             r')*$')
28be644
         self.assertRegex(softwareVersion, softwareVersionRegex)
28be644
 
28be644
+    def test_dataReceiveVersionNotSentMemoryDOS(self):
28be644
+        """
28be644
+        When the peer is not sending its SSH version but keeps sending data,
28be644
+        the connection is disconnected after 4KB to prevent buffering too
28be644
+        much and running our of memory.
28be644
+        """
28be644
+        sut = MockTransportBase()
28be644
+        sut.makeConnection(self.transport)
28be644
+
28be644
+        # Data can be received over multiple chunks.
28be644
+        sut.dataReceived(b"SSH-2-Server-Identifier")
28be644
+        sut.dataReceived(b"1234567890" * 406)
28be644
+        sut.dataReceived(b"1235678")
28be644
+        self.assertFalse(self.transport.disconnecting)
28be644
+
28be644
+        # Here we are going over the limit.
28be644
+        sut.dataReceived(b"1234567")
28be644
+        # Once a lot of data is received without an SSH version string,
28be644
+        # the transport is disconnected.
28be644
+        self.assertTrue(self.transport.disconnecting)
28be644
+        self.assertIn(b"Preventing a denial of service attack", self.transport.value())
28be644
 
28be644
     def test_sendPacketPlain(self):
28be644
         """