@@ -659,6 +659,40 @@ def test_reject_open_redirect(self):
659659 # Verify no redirect happens and instead a 400 Bad Request is returned.
660660 self .assertIn ('400 URI must not start with //' , result [0 ].decode ())
661661
662+ def test_reject_open_redirect_3_slashes (self ):
663+ # This will test the behavior when an attempt is made to cause an open
664+ # redirect. It should be rejected.
665+ mock_req = mock .MagicMock ()
666+ mock_req .makefile ().readline .side_effect = [
667+ b'GET ///example.com/%2F.. HTTP/1.1\r \n ' ,
668+ b''
669+ ]
670+
671+ # Collect the response data to verify at the end. The
672+ # SimpleHTTPRequestHandler writes the response data by calling the
673+ # request socket sendall() method.
674+ self .data = b''
675+
676+ def fake_sendall (data ):
677+ self .data += data
678+
679+ mock_req .sendall .side_effect = fake_sendall
680+
681+ client_addr = ('8.8.8.8' , 54321 )
682+ mock_server = mock .MagicMock ()
683+ # This specifies that the server will be able to handle requests other
684+ # than only websockets.
685+ mock_server .only_upgrade = False
686+
687+ # Constructing a handler will process the mock_req request passed in.
688+ websocketproxy .NovaProxyRequestHandler (
689+ mock_req , client_addr , mock_server )
690+
691+ # Verify no redirect happens and instead a 400 Bad Request is returned.
692+ self .data = self .data .decode ()
693+ self .assertIn ('Error code: 400' , self .data )
694+ self .assertIn ('Message: URI must not start with //' , self .data )
695+
662696 @mock .patch ('websockify.websocketproxy.select_ssl_version' )
663697 def test_ssl_min_version_is_not_set (self , mock_select_ssl ):
664698 websocketproxy .NovaWebSocketProxy ()
0 commit comments