CVE-2019-3569 (published 2019-06-26T15:15Z)

HHVM, when used with FastCGI, would bind by default to all available interfaces. This behavior could allow a malicious individual unintended direct access to the application, which could result in information disclosure. This issue affects versions 4.3.0, 4.4.0, 4.5.0, 4.6.0, 4.7.0, 4.8.0, versions 3.30.5 and below, and all versions in the 4.0, 4.1, and 4.2 series.

Severity: MEDIUM
CVSS v2 base score: 5.0 (AV:N/AC:L/Au:N/C:P/I:N/A:N)
CVSS v3 base score: 7.5, HIGH (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N)

Weakness information:
cwe_id: CWE-668
cwe_name: Exposure of Resource to Wrong Sphere
description: The product exposes a resource to the wrong control sphere, providing unintended actors with inappropriate access to the resource.
extended_description: 
            Resources such as files and directories may be inadvertently exposed through mechanisms such as insecure permissions, or when a program accidentally operates on the wrong object. For example, a program may intend that private files can only be provided to a specific user. This effectively defines a control sphere that is intended to prevent attackers from accessing these private files. If the file permissions are insecure, then parties other than the user will be able to access those files.
            A separate control sphere might effectively require that the user can only access the private files, but not any other files on the system. If the program does not ensure that the user is only requesting private files, then the user might be able to access other files on the system.
            In either case, the end result is that a resource has been exposed to the wrong party.
         
         

Fix information:
repo_url: https://github.com/facebook/hhvm
commit_details: repo_url: https://github.com/facebook/hhvm
author: Fred Emmott
author_date: 2019-06-11 11:44:59-07:00
msg: Fix default FastCGI interface

Reviewed By: alexeyt

Differential Revision: D15567393

fbshipit-source-id: ffab228f689d4ddca9ea4835c70aecf16da2aa9f
repository: repo_url: https://github.com/facebook/hhvm
repo_name: facebook/hhvm
description: A virtual machine for executing programs written in Hack.
repo_language: Hack
owner: facebook
file_changes: filename: fastcgi-server.cpp
change_type: ModificationType.MODIFY
diff: @@ -80,7 +80,8 @@ FastCGIServer::FastCGIServer(const std::string &address,
   if (useFileSocket) {
     sock_addr.setFromPath(address);
   } else if (address.empty()) {
-    sock_addr.setFromLocalPort(port);
+    sock_addr.setFromHostPort("localhost", port);
+    assert(sock_addr.isLoopbackAddress());
   } else {
     sock_addr.setFromHostPort(address, port);
   }

programming_language: C++
filename: runTest1.php
change_type: ModificationType.MODIFY
diff: @@ -5,9 +5,8 @@ require_once('test_base.inc');
 function test1Controller($hphpdOutput, $hphpdProcessId, $serverPort) {
   // Request a page so that the client can debug it.
   waitForClientToOutput($hphpdOutput, "Waiting for server response");
-  $url = "http://".php_uname('n').':'.$serverPort.'/test1.php';
   echo "Requesting test1.php\n";
-  request(php_uname('n'), $serverPort, 'test1.php', 10); // ignore response
+  request('localhost', $serverPort, 'test1.php', 10); // ignore response
 
   // Let client run until script quits
   waitForClientToOutput($hphpdOutput, "quit");

programming_language: PHP
filename: authDigestTest.php
change_type: ModificationType.MODIFY
diff: @@ -8,7 +8,7 @@ function BadAuthDigestTestController($serverPort) {
     'uri="/test_auth_digest.php", cnonce="MjIyMTg2", nc=00000001, ' .
     'qop="auth", response="6dfbea52fbf13016476c1879e6436004", ' .
     'opaque="cdce8a5c95a1427d74df7acbf41c9ce0"');
-  var_dump(request(php_uname('n'), $serverPort, "test_auth_digest.php",
+  var_dump(request('localhost', $serverPort, "test_auth_digest.php",
                   [], [], $args));
 }
 
@@ -18,7 +18,7 @@ function GoodAuthDigestTestController($serverPort) {
     'uri="/test_auth_digest.php", cnonce="MjIyMTg1", nc=00000001, ' .
     'qop="auth", response="e544aaed06917adea3e5c74dd49f0e32", ' .
     'opaque="cdce8a5c95a1427d74df7acbf41c9ce0"');
-  var_dump(request(php_uname('n'), $serverPort, "test_auth_digest.php",
+  var_dump(request('localhost', $serverPort, "test_auth_digest.php",
                   [], [], $args));
 }
 

programming_language: PHP
filename: disable_ini_zend_compat.php
change_type: ModificationType.MODIFY
diff: @@ -6,7 +6,7 @@
 require_once('test_base.inc');
 
 function disableIniZendCompatController($port) {
-  echo request(php_uname('n'), $port, 'test_disable_ini_zend_compat.php');
+  echo request('localhost', $port, 'test_disable_ini_zend_compat.php');
 }
 
 echo "---Enable Ini Zend Compat ON---\n";

programming_language: Lua
filename: global_variables_server.php
change_type: ModificationType.MODIFY
diff: @@ -23,6 +23,6 @@ foreach($requests as $request) {
     $path = 'global_variables.php?var=GET&get=1';
     $post = array('var' => 'POST', 'post' => 2);
     $headers = array('Cookie' => 'var=COOKIE;cookie=3;');
-    echo request(php_uname('n'), $port, $path, $post, $headers, $extra) . "\n";
+    echo request('localhost', $port, $path, $post, $headers, $extra) . "\n";
   }, $request[0]);
 }

programming_language: PHP
filename: headerTest.php
change_type: ModificationType.MODIFY
diff: @@ -4,7 +4,7 @@ require_once('test_base.inc');
 
 function headerTestController($serverPort) {
   $args = array('Authorization' => 'foo');
-  var_dump(request(php_uname('n'), $serverPort, "test_headers.php",
+  var_dump(request('localhost', $serverPort, "test_headers.php",
                   [], ['PROXY' => 'foobar'], $args));
 }
 

programming_language: PHP
filename: httpsTest.php
change_type: ModificationType.MODIFY
diff: @@ -4,7 +4,7 @@ require_once('test_base.inc');
 
 function httpsTestController($serverPort) {
   $args = array('HTTPS' => '');
-  var_dump(request(php_uname('n'), $serverPort, "test_https.php",
+  var_dump(request('localhost', $serverPort, "test_https.php",
                   [], [], $args));
 }
 

programming_language: PHP
filename: invalid.php
change_type: ModificationType.MODIFY
diff: @@ -3,7 +3,7 @@
 require_once('test_base.inc');
 
 function invalidTestController($port) {
-  $host = php_uname('n');
+  $host = 'localhost';
 
   $filename = __DIR__.'/request-doesnotexist.dat';
   $file = fopen($filename, 'rb');

programming_language: PHP
filename: server_tests.inc
change_type: ModificationType.MODIFY
diff: @@ -179,7 +179,7 @@ function startServer(&$serverPort, &$adminPort, &$debugPort, $home, $root,
 
 // Check if the server id is in the expected list of ids.
 function checkServerId($serverPort, $expectedIds) {
-  $host = php_uname('n');
+  $host = 'localhost';
   $r = request($host, $serverPort, "hello.php");
   if (preg_match('/Hello, World!(.*+)/', $r ?? '', &$matches)) {
     foreach ((array)$expectedIds as $id) {
@@ -217,7 +217,7 @@ function stopServer($adminPort, $serverProc) {
 
   $r = "";
   for ($i = 1; $i <= 10; $i++) {
-    $r = request(php_uname('n'), $adminPort, 'stop?instance-id='.$test_run_id);
+    $r = request('localhost', $adminPort, 'stop?instance-id='.$test_run_id);
     if ($r === "OK") break;
     usleep(100000);
   }
@@ -286,7 +286,7 @@ function http_request($host, $port, $path, $timeout = 1200, $curl_opts = '') {
     $headers = implode(" ", $s);
   }
   $url = "http://$host:$port/$path";
-  $host_name = "hphpd.debugger.".php_uname('n');
+  $host_name = "hphpd.debugger.".\php_uname('n');
 
   $LOG_ROOT = ServerUtilServerTests::$LOG_ROOT;
   $test_run_id = ServerUtilServerTests::$test_run_id;
@@ -304,7 +304,7 @@ function requestAll(array $requests, $customArgs = '', $repoArgs = '') {
       foreach ($requests as $request) {
         $r = is_array($request) ? $request[0] : $request;
         echo "Requesting '$r'\n";
-        var_dump(request(php_uname('n'), $serverPort, $request));
+        var_dump(request('localhost', $serverPort, $request));
       }
     },
     $customArgs,

programming_language: PHP