Skip to content

Commit 9b0bffc

Browse files
committed
Merge branch 'SvenRtbg-fix-issue-15'
Closes #16
2 parents 62a3895 + 86c8a20 commit 9b0bffc

File tree

3 files changed

+34
-14
lines changed

3 files changed

+34
-14
lines changed

README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ Note that the proxy headers are only checked if the first parameter to the const
1515

1616
**Trusted Proxies**
1717

18-
You can set a list of proxies that are trusted as the second constructor parameter. If this list is set, then the proxy headers will only be checked if the `REMOTE_ADDR` is in the trusted list.
18+
If you configure to check the proxy headers (first parameter is `true`), you have to provide an array of trusted proxies as the second parameter. If the array is empty, the proxy headers will always be evaluated. If the array is not empty, it must contain strings with IP addresses, one of them must be the `$_SERVER['REMOTE_ADDR']` variable in order to allow evaluating the proxy headers - otherwise the `REMOTE_ADDR` itself is returned.
1919

2020
**Attribute name**
2121

@@ -25,6 +25,12 @@ By default, the name of the attribute is '`ip_address`'. This can be changed by
2525

2626
By default, this middleware checks the 'Forwarded', 'X-Forwarded-For', 'X-Forwarded', 'X-Cluster-Client-Ip' and 'Client-Ip' headers. You can replace this list with your own using the fourth constructor parameter.
2727

28+
## Security considerations
29+
30+
A malicious client may send any header to your proxy, including any proxy headers, containing any IP address. If your proxy simply adds another IP address to the header, an attacker can send a fake IP. Make sure to setup your proxy in a way that removes any sent (and possibly faked) headers from the original request and replaces them with correct values (i.e. the currently used `REMOTE_ADDR` on the proxy server).
31+
32+
This library cannot by design ensure you get correct and trustworthy results if your network environment isn't setup properly.
33+
2834
## Installation
2935

3036
`composer require akrabat/ip-address-middleware`

src/IpAddress.php

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,14 @@ class IpAddress implements MiddlewareInterface
5858
*/
5959
public function __construct(
6060
$checkProxyHeaders = false,
61-
array $trustedProxies = [],
61+
array $trustedProxies = null,
6262
$attributeName = null,
6363
array $headersToInspect = []
6464
) {
65+
if ($checkProxyHeaders && $trustedProxies === null) {
66+
throw new \InvalidArgumentException('Use of the forward headers requires an array for trusted proxies.');
67+
}
68+
6569
$this->checkProxyHeaders = $checkProxyHeaders;
6670
$this->trustedProxies = $trustedProxies;
6771

@@ -127,10 +131,14 @@ protected function determineClientIpAddress($request)
127131
}
128132
}
129133

130-
if ($this->checkProxyHeaders
131-
&& !empty($this->trustedProxies)
132-
&& in_array($ipAddress, $this->trustedProxies)
133-
) {
134+
$checkProxyHeaders = $this->checkProxyHeaders;
135+
if ($checkProxyHeaders && !empty($this->trustedProxies)) {
136+
if (!in_array($ipAddress, $this->trustedProxies)) {
137+
$checkProxyHeaders = false;
138+
}
139+
}
140+
141+
if ($checkProxyHeaders) {
134142
foreach ($this->headersToInspect as $header) {
135143
if ($request->hasHeader($header)) {
136144
$ip = $this->getFirstIpAddressFromHeader($request, $header);

tests/IpAddressTest.php

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ public function testIpIsNullIfMissing()
7171

7272
public function testXForwardedForIp()
7373
{
74-
$middleware = new IPAddress(true, ['192.168.1.1']);
74+
$middleware = new IPAddress(true, []);
7575

7676
$request = ServerRequestFactory::fromGlobals([
7777
'REMOTE_ADDR' => '192.168.1.1',
@@ -131,7 +131,7 @@ public function testProxyIpIsIgnored()
131131

132132
public function testHttpClientIp()
133133
{
134-
$middleware = new IPAddress(true, ['192.168.1.1']);
134+
$middleware = new IPAddress(true, []);
135135

136136
$request = ServerRequestFactory::fromGlobals([
137137
'REMOTE_ADDR' => '192.168.1.1',
@@ -151,7 +151,7 @@ public function testHttpClientIp()
151151

152152
public function testXForwardedForIpV6()
153153
{
154-
$middleware = new IPAddress(true, ['192.168.1.1']);
154+
$middleware = new IPAddress(true, []);
155155

156156
$request = ServerRequestFactory::fromGlobals([
157157
'REMOTE_ADDR' => '192.168.1.1',
@@ -171,7 +171,7 @@ public function testXForwardedForIpV6()
171171

172172
public function testXForwardedForWithInvalidIp()
173173
{
174-
$middleware = new IPAddress(true, ['192.168.1.1']);
174+
$middleware = new IPAddress(true, []);
175175

176176
$request = ServerRequestFactory::fromGlobals([
177177
'REMOTE_ADDR' => '192.168.1.1',
@@ -231,7 +231,7 @@ public function testXForwardedForIpWithUntrustedProxy()
231231

232232
public function testForwardedWithMultipleFor()
233233
{
234-
$middleware = new IPAddress(true, ['192.168.1.1']);
234+
$middleware = new IPAddress(true, []);
235235

236236
$request = ServerRequestFactory::fromGlobals([
237237
'REMOTE_ADDR' => '192.168.1.1',
@@ -251,7 +251,7 @@ public function testForwardedWithMultipleFor()
251251

252252
public function testForwardedWithAllOptions()
253253
{
254-
$middleware = new IPAddress(true, ['192.168.1.1']);
254+
$middleware = new IPAddress(true, []);
255255

256256
$request = ServerRequestFactory::fromGlobals([
257257
'REMOTE_ADDR' => '192.168.1.1',
@@ -271,7 +271,7 @@ public function testForwardedWithAllOptions()
271271

272272
public function testForwardedWithWithIpV6()
273273
{
274-
$middleware = new IPAddress(true, ['192.168.1.1']);
274+
$middleware = new IPAddress(true, []);
275275

276276
$request = ServerRequestFactory::fromGlobals([
277277
'REMOTE_ADDR' => '192.168.1.1',
@@ -294,7 +294,7 @@ public function testCustomHeader()
294294
$headersToInspect = [
295295
'Foo-Bar'
296296
];
297-
$middleware = new IPAddress(true, ['192.168.0.1'], null, $headersToInspect);
297+
$middleware = new IPAddress(true, [], null, $headersToInspect);
298298

299299
$request = ServerRequestFactory::fromGlobals([
300300
'REMOTE_ADDR' => '192.168.0.1',
@@ -333,4 +333,10 @@ public function handle(ServerRequestInterface $request): ResponseInterface
333333

334334
$this->assertSame("Hello World", (string) $response->getBody());
335335
}
336+
337+
public function testNotGivingAProxyListShouldThrowException()
338+
{
339+
$this->expectException(\InvalidArgumentException::class);
340+
new IpAddress(true);
341+
}
336342
}

0 commit comments

Comments
 (0)