Skip to content
This repository has been archived by the owner on Jan 30, 2020. It is now read-only.

Commit

Permalink
Merge branch 'master' of https://github.com/zendframework/zf2 into zf…
Browse files Browse the repository at this point in the history
…5256
  • Loading branch information
imel96 committed Nov 18, 2013
Show file tree
Hide file tree
Showing 4 changed files with 162 additions and 8 deletions.
4 changes: 1 addition & 3 deletions src/Header/SetCookie.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@

namespace Zend\Http\Header;

use Closure;
use Zend\Uri\UriFactory;

/**
Expand Down Expand Up @@ -97,7 +96,6 @@ class SetCookie implements MultipleHeaderInterface
*/
public static function fromString($headerLine, $bypassHeaderFieldName = false)
{
/* @var $setCookieProcessor Closure */
static $setCookieProcessor = null;

if ($setCookieProcessor === null) {
Expand All @@ -107,7 +105,7 @@ public static function fromString($headerLine, $bypassHeaderFieldName = false)
$keyValuePairs = preg_split('#;\s*#', $headerLine);

foreach ($keyValuePairs as $keyValue) {
if (preg_match('#^(?<headerKey>[^=]+)=\s*("?)(?<headerValue>[^"]+)\2#',$keyValue,$matches)) {
if (preg_match('#^(?P<headerKey>[^=]+)=\s*("?)(?P<headerValue>[^"]+)\2#', $keyValue, $matches)) {
$headerKey = $matches['headerKey'];
$headerValue= $matches['headerValue'];
} else {
Expand Down
14 changes: 10 additions & 4 deletions src/PhpEnvironment/RemoteAddress.php
Original file line number Diff line number Diff line change
Expand Up @@ -113,16 +113,18 @@ public function getIpAddress()
/**
* Attempt to get the IP address for a proxied client
*
* @see http://tools.ietf.org/html/draft-ietf-appsawg-http-forwarded-10#section-5.2
* @return false|string
*/
protected function getIpAddressFromProxy()
{
if (!$this->useProxy) {
if (!$this->useProxy
|| (isset($_SERVER['REMOTE_ADDR']) && !in_array($_SERVER['REMOTE_ADDR'], $this->trustedProxies))
) {
return false;
}

$header = $this->proxyHeader;

if (!isset($_SERVER[$header]) || empty($_SERVER[$header])) {
return false;
}
Expand All @@ -139,8 +141,12 @@ protected function getIpAddressFromProxy()
return false;
}

// Return right-most
$ip = array_pop($ips);
// Since we've removed any known, trusted proxy servers, the right-most
// address represents the first IP we do not know about -- i.e., we do
// not know if it is a proxy server, or a client. As such, we treat it
// as the originating IP.
// @see http://en.wikipedia.org/wiki/X-Forwarded-For
$ip = array_pop($ips);
return $ip;
}

Expand Down
1 change: 0 additions & 1 deletion test/ClientTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@

namespace ZendTest\Http;

use ReflectionClass;
use Zend\Uri\Http;
use Zend\Http\Client;
use Zend\Http\Cookies;
Expand Down
151 changes: 151 additions & 0 deletions test/PhpEnvironment/RemoteAddressTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/

namespace ZendTest\Http\PhpEnvironment;

use PHPUnit_Framework_TestCase as TestCase;
use Zend\Http\PhpEnvironment\RemoteAddress as RemoteAddr;

class RemoteAddressTest extends TestCase
{
/**
* Original environemnt
*
* @var array
*/
protected $originalEnvironment;

/**
* Save the original environment and set up a clean one.
*/
public function setUp()
{
$this->originalEnvironment = array(
'post' => $_POST,
'get' => $_GET,
'cookie' => $_COOKIE,
'server' => $_SERVER,
'env' => $_ENV,
'files' => $_FILES,
);

$_POST = array();
$_GET = array();
$_COOKIE = array();
$_SERVER = array();
$_ENV = array();
$_FILES = array();

$this->remoteAddress = new RemoteAddr();
}

/**
* Restore the original environment
*/
public function tearDown()
{
$_POST = $this->originalEnvironment['post'];
$_GET = $this->originalEnvironment['get'];
$_COOKIE = $this->originalEnvironment['cookie'];
$_SERVER = $this->originalEnvironment['server'];
$_ENV = $this->originalEnvironment['env'];
$_FILES = $this->originalEnvironment['files'];
}

public function testSetGetUseProxy()
{
$this->remoteAddress->setUseProxy(false);
$this->assertFalse($this->remoteAddress->getUseProxy());
}

public function testSetGetDefaultUseProxy()
{
$this->remoteAddress->setUseProxy();
$this->assertTrue($this->remoteAddress->getUseProxy());
}

public function testSetTrustedProxies()
{
$result = $this->remoteAddress->setTrustedProxies(array(
'192.168.0.10', '192.168.0.1'
));
$this->assertTrue($result instanceOf RemoteAddr);
}

public function testGetIpAddress()
{
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
$this->assertEquals('127.0.0.1', $this->remoteAddress->getIpAddress());
}

public function testGetIpAddressFromProxy()
{
$this->remoteAddress->setUseProxy(true);
$this->remoteAddress->setTrustedProxies(array(
'192.168.0.10', '10.0.0.1'
));
$_SERVER['REMOTE_ADDR'] = '192.168.0.10';
$_SERVER['HTTP_X_FORWARDED_FOR'] = '8.8.8.8, 10.0.0.1';
$this->assertEquals('8.8.8.8', $this->remoteAddress->getIpAddress());
}

public function testGetIpAddressFromProxyRemoteAddressNotTrusted()
{
$this->remoteAddress->setUseProxy(true);
$this->remoteAddress->setTrustedProxies(array(
'10.0.0.1'
));
// the REMOTE_ADDR is not in the trusted IPs, possible attack here
$_SERVER['REMOTE_ADDR'] = '1.1.1.1';
$_SERVER['HTTP_X_FORWARDED_FOR'] = '8.8.8.8, 10.0.0.1';
$this->assertEquals('1.1.1.1', $this->remoteAddress->getIpAddress());
}

/**
* Test to prevent attack on the HTTP_X_FORWARDED_FOR header
* The client IP is always the first on the left
*
* @see http://tools.ietf.org/html/draft-ietf-appsawg-http-forwarded-10#section-5.2
*/
public function testGetIpAddressFromProxyFakeData()
{
$this->remoteAddress->setUseProxy(true);
$this->remoteAddress->setTrustedProxies(array(
'192.168.0.10', '10.0.0.1', '10.0.0.2'
));
$_SERVER['REMOTE_ADDR'] = '192.168.0.10';
// 1.1.1.1 is the first IP address from the right not representing a known proxy server; as such, we
// must treat it as a client IP.
$_SERVER['HTTP_X_FORWARDED_FOR'] = '8.8.8.8, 10.0.0.2, 1.1.1.1, 10.0.0.1';
$this->assertEquals('1.1.1.1', $this->remoteAddress->getIpAddress());
}

/**
* Tests if an empty string is returned if the server variable
* REMOTE_ADDR is not set.
*
* This happens when you run a local unit test, or a PHP script with
* PHP from the command line.
*/
public function testGetIpAddressReturnsEmptyStringOnNoRemoteAddr()
{
// Store the set IP address for later use
if (isset($_SERVER['REMOTE_ADDR'])) {
$ipAddress = $_SERVER['REMOTE_ADDR'];
unset($_SERVER['REMOTE_ADDR']);
}

$this->remoteAddress->setUseProxy(true);
$this->assertEquals('', $this->remoteAddress->getIpAddress());

if (isset($ipAddress)) {
$_SERVER['REMOTE_ADDR'] = $ipAddress;
}
}
}

0 comments on commit 6d17b76

Please sign in to comment.