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

Commit 3a4f44f

Browse files
committed
Remove support for the X-Original-Url and X-Rewrite-Url headers
This patch modifies the logic of `ServerRequestFactory::marshalRequestUri()` such that it will ignore the X-Original-Url and X-Rewrite-Url headers when marshaling the request URI.
1 parent ed59d8a commit 3a4f44f

File tree

3 files changed

+61
-48
lines changed

3 files changed

+61
-48
lines changed

CHANGELOG.md

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,56 @@
22

33
All notable changes to this project will be documented in this file, in reverse chronological order by release.
44

5-
## 1.8.4 - TBD
5+
## 1.8.4 - 2018-08-01
66

77
### Added
88

99
- Nothing.
1010

1111
### Changed
1212

13-
- Nothing.
13+
- This release modifies how `ServerRequestFactory` marshals the request URI. In
14+
prior releases, we would attempt to inspect the `X-Rewrite-Url` and
15+
`X-Original-Url` headers, using their values, if present. These headers are
16+
issued by the ISAPI_Rewrite module for IIS (developed by HeliconTech).
17+
However, we have no way of guaranteeing that the module is what issued the
18+
headers, making it an unreliable source for discovering the URI. As such, we
19+
have removed this feature in this release of Diactoros.
20+
21+
If you are developing a middleware application, you can mimic the
22+
functionality via middleware as follows:
23+
24+
```php
25+
use Psr\Http\Message\ResponseInterface;
26+
use Psr\Http\Message\ServerRequestInterface;
27+
use Psr\Http\Server\RequestHandlerInterface;
28+
use Zend\Diactoros\Uri;
29+
30+
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler) : ResponseInterface
31+
{
32+
$requestUri = null;
33+
34+
$httpXRewriteUrl = $request->getHeaderLine('X-Rewrite-Url');
35+
if ($httpXRewriteUrl !== null) {
36+
$requestUri = $httpXRewriteUrl;
37+
}
38+
39+
$httpXOriginalUrl = $request->getHeaderLine('X-Original-Url');
40+
if ($httpXOriginalUrl !== null) {
41+
$requestUri = $httpXOriginalUrl;
42+
}
43+
44+
if ($requestUri !== null) {
45+
$request = $request->withUri(new Uri($requestUri));
46+
}
47+
48+
return $handler->handle($request);
49+
}
50+
```
51+
52+
If you use middleware such as the above, make sure you also instruct your web
53+
server to strip any incoming headers of the same name so that you can
54+
guarantee they are issued by the ISAPI_Rewrite module.
1455

1556
### Deprecated
1657

src/functions/marshal_uri_from_sapi.php

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,11 @@ function marshalUriFromSapi(array $server, array $headers)
124124
* Detect the path for the request
125125
*
126126
* Looks at a variety of criteria in order to attempt to autodetect the base
127-
* request path, including rewrite URIs, proxy URIs, etc.
127+
* request path, including:
128+
*
129+
* - IIS7 UrlRewrite environment
130+
* - REQUEST_URI
131+
* - ORIG_PATH_INFO
128132
*
129133
* From ZF2's Zend\Http\PhpEnvironment\Request class
130134
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
@@ -144,18 +148,6 @@ function marshalUriFromSapi(array $server, array $headers)
144148

145149
$requestUri = array_key_exists('REQUEST_URI', $server) ? $server['REQUEST_URI'] : null;
146150

147-
// Check this first so IIS will catch.
148-
$httpXRewriteUrl = array_key_exists('HTTP_X_REWRITE_URL', $server) ? $server['HTTP_X_REWRITE_URL'] : null;
149-
if ($httpXRewriteUrl !== null) {
150-
$requestUri = $httpXRewriteUrl;
151-
}
152-
153-
// Check for IIS 7.0 or later with ISAPI_Rewrite
154-
$httpXOriginalUrl = array_key_exists('HTTP_X_ORIGINAL_URL', $server) ? $server['HTTP_X_ORIGINAL_URL'] : null;
155-
if ($httpXOriginalUrl !== null) {
156-
$requestUri = $httpXOriginalUrl;
157-
}
158-
159151
if ($requestUri !== null) {
160152
return preg_replace('#^[^/:]+://[^/]+#', '', $requestUri);
161153
}

test/ServerRequestFactoryTest.php

Lines changed: 13 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -126,39 +126,6 @@ public function testMarshalRequestUriUsesIISUnencodedUrlValueIfPresentAndUrlWasR
126126
$this->assertSame($server['UNENCODED_URL'], $uri->getPath());
127127
}
128128

129-
public function testMarshalRequestUriUsesHTTPXRewriteUrlIfPresent()
130-
{
131-
$server = [
132-
'IIS_WasUrlRewritten' => null,
133-
'UNENCODED_URL' => '/foo/bar',
134-
'REQUEST_URI' => '/overridden',
135-
'HTTP_X_REWRITE_URL' => '/bar/baz',
136-
];
137-
138-
$headers = marshalHeadersFromSapi($server);
139-
140-
$uri = marshalUriFromSapi($server, $headers);
141-
142-
$this->assertSame($server['HTTP_X_REWRITE_URL'], $uri->getPath());
143-
}
144-
145-
public function testMarshalRequestUriUsesHTTPXOriginalUrlIfPresent()
146-
{
147-
$server = [
148-
'IIS_WasUrlRewritten' => null,
149-
'UNENCODED_URL' => '/foo/bar',
150-
'REQUEST_URI' => '/overridden',
151-
'HTTP_X_REWRITE_URL' => '/bar/baz',
152-
'HTTP_X_ORIGINAL_URL' => '/baz/bat',
153-
];
154-
155-
$headers = marshalHeadersFromSapi($server);
156-
157-
$uri = marshalUriFromSapi($server, $headers);
158-
159-
$this->assertSame($server['HTTP_X_ORIGINAL_URL'], $uri->getPath());
160-
}
161-
162129
public function testMarshalRequestUriStripsSchemeHostAndPortInformationWhenPresent()
163130
{
164131
$server = [
@@ -627,4 +594,17 @@ public function marshalProtocolVersionProvider()
627594
'HTTP/2' => ['HTTP/2', '2'],
628595
];
629596
}
597+
598+
public function testMarshalRequestUriPrefersRequestUriServerParamWhenXOriginalUrlButNoXRewriteUrlPresent()
599+
{
600+
$headers = [
601+
'X-Original-URL' => '/hijack-attempt',
602+
];
603+
$server = [
604+
'REQUEST_URI' => 'https://example.com/requested/path',
605+
];
606+
607+
$uri = marshalUriFromSapi($server, $headers);
608+
$this->assertSame('/requested/path', $uri->getPath());
609+
}
630610
}

0 commit comments

Comments
 (0)