GitHub CopilotWrite better code with AI | MCP RegistryIntegrate external tools | ActionsAutomate any workflow | CodespacesInstant dev environments | IssuesPlan and track work | Code ReviewManage code changes | Code QualityEnforce quality at merge | Why GitHub | Marketplace | View all features | Enterprises | Small and medium teams | Startups | View all use cases | View all industries | View all solutions | AI | Software Development | DevOps | Security | View all topics | Customer stories | Events & webinars | Ebooks & reports | Business insights | Trust center | Partners | View all resources
@@ -103,6 +103,10 @@ def __init__(self, conn, encoding=DEFAULT_ENCODING):
103103self.next_retr_data=RETR_DATA
104104self.push('220 welcome')
105105self.encoding=encoding
106+# We use this as the string IPv4 address to direct the client
107+# to in response to a PASV command. To test security behavior.
108+# https://bugs.python.org/issue43285/.
109+self.fake_pasv_server_ip='252.253.254.255'
106110107111defcollect_incoming_data(self, data):
108112self.in_buffer.append(data)
@@ -143,7 +147,8 @@ def cmd_port(self, arg):
143147defcmd_pasv(self, arg):
144148withsocket.create_server((self.socket.getsockname()[0], 0)) assock:
145149sock.settimeout(TIMEOUT)
146-ip, port=sock.getsockname()[:2]
150+port=sock.getsockname()[1]
151+ip=self.fake_pasv_server_ip
147152ip=ip.replace('.', ','); p1=port/256; p2=port%256
148153self.push('227 entering passive mode (%s,%d,%d)'%(ip, p1, p2))
149154conn, addr=sock.accept()
@@ -707,6 +712,26 @@ def test_makepasv(self):
707712# IPv4 is in use, just make sure send_epsv has not been used
708713self.assertEqual(self.server.handler_instance.last_received_cmd, 'pasv')
709714715+deftest_makepasv_issue43285_security_disabled(self):
716+"""Test the opt-in to the old vulnerable behavior."""
717+self.client.trust_server_pasv_ipv4_address=True
718+bad_host, port=self.client.makepasv()
719+self.assertEqual(
720+bad_host, self.server.handler_instance.fake_pasv_server_ip)
721+# Opening and closing a connection keeps the dummy server happy
722+# instead of timing out on accept.
723+socket.create_connection((self.client.sock.getpeername()[0], port),
724+timeout=TIMEOUT).close()
725+726+deftest_makepasv_issue43285_security_enabled_default(self):
727+self.assertFalse(self.client.trust_server_pasv_ipv4_address)
728+trusted_host, port=self.client.makepasv()
729+self.assertNotEqual(
730+trusted_host, self.server.handler_instance.fake_pasv_server_ip)
731+# Opening and closing a connection keeps the dummy server happy
732+# instead of timing out on accept.
733+socket.create_connection((trusted_host, port), timeout=TIMEOUT).close()
734+710735deftest_with_statement(self):
711736self.client.quit()
712737