Browse Source

Fix side-effect in destructor

SmtpTransport had the potential to create a harmful side-effect
in its destructor should an untrusted value ever be deserialized. This
solves that by removing the socket on wakeup.
Mark Story 7 years ago
parent
commit
1a74e79830

+ 12 - 0
src/Mailer/Transport/SmtpTransport.php

@@ -79,6 +79,18 @@ class SmtpTransport extends AbstractTransport
     }
 
     /**
+     * Unserialize handler.
+     *
+     * Ensure that the socket property isn't reinitialized in a broken state.
+     *
+     * @return void
+     */
+    public function __wakeup()
+    {
+        $this->_socket = null;
+    }
+
+    /**
      * Connect to the SMTP server.
      *
      * This method tries to connect only in case there is no open

+ 21 - 0
tests/TestCase/Mailer/Transport/SmtpTransportTest.php

@@ -709,4 +709,25 @@ class SmtpTransportTest extends TestCase
 
         $this->SmtpTransport->send($email);
     }
+
+    /**
+     * Ensure that unserialized transports have no connection.
+     *
+     * @return void
+     */
+    public function testSerializeCleanupSocket()
+    {
+        $this->socket->expects($this->at(0))->method('connect')->will($this->returnValue(true));
+        $this->socket->expects($this->at(1))->method('read')->will($this->returnValue("220 Welcome message\r\n"));
+        $this->socket->expects($this->at(2))->method('write')->with("EHLO localhost\r\n");
+        $this->socket->expects($this->at(3))->method('read')->will($this->returnValue("250 OK\r\n"));
+
+        $smtpTransport = new SmtpTestTransport();
+        $smtpTransport->setSocket($this->socket);
+        $smtpTransport->connect();
+
+        $result = unserialize(serialize($smtpTransport));
+        $this->assertAttributeEquals(null, '_socket', $result);
+        $this->assertFalse($result->connected());
+    }
 }