php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #74796 Requests through https:// with http proxy set altering default context
Submitted: 2017-06-22 11:06 UTC Modified: 2025-04-09 14:09 UTC
Votes:10
Avg. Score:3.9 ± 0.9
Reproduced:7 of 8 (87.5%)
Same Version:6 (85.7%)
Same OS:5 (71.4%)
From: anrdaemon at freemail dot ru Assigned: bukka (profile)
Status: Assigned Package: Streams related
PHP Version: 7.1.6 OS: Windows, Linux
Private report: No CVE-ID: None
View Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
If you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: anrdaemon at freemail dot ru
New email:
PHP Version: OS:

 

 [2017-06-22 11:06 UTC] anrdaemon at freemail dot ru
Description:
------------
Adding http proxy to default stream context making addressing different HTTPS domains in the same script impossible.
First request to HTTPS site after associating a http proxy sets ssl context to a single peer name and requests to any other domain will fail.

Tested with 7.1.6 and 5.6.30 on Windows and Ubuntu Linux.

Test script:
---------------
<?php

stream_context_set_default([
  "https" => [
    "proxy" => "tcp://proxy:3128"
    ],
]);
var_dump(stream_context_get_options(stream_context_get_default()));
file_get_contents("https://www.google.com/"); // fine
var_dump(stream_context_get_options(stream_context_get_default()));
file_get_contents("https://www.yahoo.com/"); // fine
var_dump(stream_context_get_options(stream_context_get_default()));
stream_context_set_default([
  "http" => [
    "proxy" => "tcp://proxy:3128"
    ],
]);
var_dump(stream_context_get_options(stream_context_get_default()));
file_get_contents("https://www.google.com/"); // fine
var_dump(stream_context_get_options(stream_context_get_default())); // ssl:peer_name is set
file_get_contents("https://www.yahoo.com/"); // Peer certificate CN=`*.www.yahoo.com' did not match expected CN=`www.google.com' in ...
var_dump(stream_context_get_options(stream_context_get_default()));


Expected result:
----------------
array(1) {
  ["https"]=>
  array(1) {
    ["proxy"]=>
    string(16) "tcp://proxy:3128"
  }
}
array(1) {
  ["https"]=>
  array(1) {
    ["proxy"]=>
    string(16) "tcp://proxy:3128"
  }
}
array(1) {
  ["https"]=>
  array(1) {
    ["proxy"]=>
    string(16) "tcp://proxy:3128"
  }
}
array(2) {
  ["https"]=>
  array(1) {
    ["proxy"]=>
    string(16) "tcp://proxy:3128"
  }
  ["http"]=>
  array(1) {
    ["proxy"]=>
    string(16) "tcp://proxy:3128"
  }
}
array(3) {
  ["https"]=>
  array(1) {
    ["proxy"]=>
    string(16) "tcp://proxy:3128"
  }
  ["http"]=>
  array(1) {
    ["proxy"]=>
    string(16) "tcp://proxy:3128"
  }
}
array(3) {
  ["https"]=>
  array(1) {
    ["proxy"]=>
    string(16) "tcp://proxy:3128"
  }
  ["http"]=>
  array(1) {
    ["proxy"]=>
    string(16) "tcp://proxy:3128"
  }
}


Actual result:
--------------
array(1) {
  ["https"]=>
  array(1) {
    ["proxy"]=>
    string(16) "tcp://proxy:3128"
  }
}
array(1) {
  ["https"]=>
  array(1) {
    ["proxy"]=>
    string(16) "tcp://proxy:3128"
  }
}
array(1) {
  ["https"]=>
  array(1) {
    ["proxy"]=>
    string(16) "tcp://proxy:3128"
  }
}
array(2) {
  ["https"]=>
  array(1) {
    ["proxy"]=>
    string(16) "tcp://proxy:3128"
  }
  ["http"]=>
  array(1) {
    ["proxy"]=>
    string(16) "tcp://proxy:3128"
  }
}
array(3) {
  ["https"]=>
  array(1) {
    ["proxy"]=>
    string(16) "tcp://proxy:3128"
  }
  ["http"]=>
  array(1) {
    ["proxy"]=>
    string(16) "tcp://proxy:3128"
  }
  ["ssl"]=>
  array(1) {
    ["peer_name"]=>
    string(14) "www.google.com"
  }
}
PHP Warning:  file_get_contents(): Peer certificate CN=`*.www.yahoo.com' did not match expected CN=`www.google.com' in test.php on line 21
PHP Warning:  file_get_contents(https://www.yahoo.com/): failed to open stream: Cannot connect to HTTPS server through proxy in test.php on line 21
array(3) {
  ["https"]=>
  array(1) {
    ["proxy"]=>
    string(16) "tcp://proxy:3128"
  }
  ["http"]=>
  array(1) {
    ["proxy"]=>
    string(16) "tcp://proxy:3128"
  }
  ["ssl"]=>
  array(1) {
    ["peer_name"]=>
    string(14) "www.google.com"
  }
}


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2017-06-22 11:42 UTC] anrdaemon at freemail dot ru
And I just found out that settings "https" context has no effect.
Both "https://" and "http://" URL's fall into "http" context.
WHY?…
 [2018-08-20 17:22 UTC] cmb@php.net
-Status: Open +Status: Verified
 [2018-08-20 17:22 UTC] cmb@php.net
This issue has been introduced by fixing bug #67609.
 [2025-04-09 14:09 UTC] bukka@php.net
-Status: Verified +Status: Assigned -Assigned To: +Assigned To: bukka
 [2025-04-09 14:09 UTC] bukka@php.net
So I finally managed to recreate this. It took me quite some time how to set it all up in envoy (it's a bit more complicated there but thought that I will try it with some a bit more modern forward proxy setup supporting connect which might have been overkill). Anyway working config for a proxy can be found in https://github.com/bukka/php-manual-tests/blob/48fef4ddd482ebb647b8c77c98cce235fa804cf1/openssl/http-proxy/dynamic-http1-connect.yaml .

With that and the following script:

<?php

stream_context_set_default([
  "http" => [
    "proxy" => "tcp://127.0.0.1:10001"
    ],
]);
var_dump(stream_context_get_options(stream_context_get_default()));
var_dump(file_get_contents("https://www.google.com/")); // fine
var_dump(stream_context_get_options(stream_context_get_default()));
var_dump(file_get_contents("https://www.yahoo.com/")); // Peer certificate issues
var_dump(stream_context_get_options(stream_context_get_default()));

This is exactly as mentioned and the problem is that the global config is being modified and not cleaned up - think we should do some temp copy as context should never get permanently modified.

This might be also causing some issues for extensions like soap that make use of proxy. There are bunch of open issues already for this so will check it out.

But first I will need to come with some light forward proxy testing implementation so I can actually verify this in test and can also then for soap tests and possibly closing all those proxy issues there.
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Tue Apr 29 02:01:27 2025 UTC