@@ -622,6 +622,40 @@ def fake_sendall(data):
622
622
self .assertIn ('Error code: 400' , self .data )
623
623
self .assertIn ('Message: URI must not start with //' , self .data )
624
624
625
+ def test_reject_open_redirect_3_slashes (self ):
626
+ # This will test the behavior when an attempt is made to cause an open
627
+ # redirect. It should be rejected.
628
+ mock_req = mock .MagicMock ()
629
+ mock_req .makefile ().readline .side_effect = [
630
+ b'GET ///example.com/%2F.. HTTP/1.1\r \n ' ,
631
+ b''
632
+ ]
633
+
634
+ # Collect the response data to verify at the end. The
635
+ # SimpleHTTPRequestHandler writes the response data by calling the
636
+ # request socket sendall() method.
637
+ self .data = b''
638
+
639
+ def fake_sendall (data ):
640
+ self .data += data
641
+
642
+ mock_req .sendall .side_effect = fake_sendall
643
+
644
+ client_addr = ('8.8.8.8' , 54321 )
645
+ mock_server = mock .MagicMock ()
646
+ # This specifies that the server will be able to handle requests other
647
+ # than only websockets.
648
+ mock_server .only_upgrade = False
649
+
650
+ # Constructing a handler will process the mock_req request passed in.
651
+ websocketproxy .NovaProxyRequestHandler (
652
+ mock_req , client_addr , mock_server )
653
+
654
+ # Verify no redirect happens and instead a 400 Bad Request is returned.
655
+ self .data = self .data .decode ()
656
+ self .assertIn ('Error code: 400' , self .data )
657
+ self .assertIn ('Message: URI must not start with //' , self .data )
658
+
625
659
@mock .patch ('nova.objects.ConsoleAuthToken.validate' )
626
660
def test_no_compute_rpcapi_with_invalid_token (self , mock_validate ):
627
661
"""Tests that we don't create a ComputeAPI object until we actually
0 commit comments