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

Commit

Permalink
Remove support for the X-Original-Url and X-Rewrite-Url headers
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
weierophinney committed Aug 1, 2018
1 parent ed59d8a commit 3a4f44f
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 48 deletions.
45 changes: 43 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,56 @@

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

## 1.8.4 - TBD
## 1.8.4 - 2018-08-01

### Added

- Nothing.

### Changed

- Nothing.
- This release modifies how `ServerRequestFactory` marshals the request URI. In
prior releases, we would attempt to inspect the `X-Rewrite-Url` and
`X-Original-Url` headers, using their values, if present. These headers are
issued by the ISAPI_Rewrite module for IIS (developed by HeliconTech).
However, we have no way of guaranteeing that the module is what issued the
headers, making it an unreliable source for discovering the URI. As such, we
have removed this feature in this release of Diactoros.

If you are developing a middleware application, you can mimic the
functionality via middleware as follows:

```php
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Zend\Diactoros\Uri;

public function process(ServerRequestInterface $request, RequestHandlerInterface $handler) : ResponseInterface
{
$requestUri = null;

$httpXRewriteUrl = $request->getHeaderLine('X-Rewrite-Url');
if ($httpXRewriteUrl !== null) {
$requestUri = $httpXRewriteUrl;
}

$httpXOriginalUrl = $request->getHeaderLine('X-Original-Url');
if ($httpXOriginalUrl !== null) {
$requestUri = $httpXOriginalUrl;
}

if ($requestUri !== null) {
$request = $request->withUri(new Uri($requestUri));
}

return $handler->handle($request);
}
```

If you use middleware such as the above, make sure you also instruct your web
server to strip any incoming headers of the same name so that you can
guarantee they are issued by the ISAPI_Rewrite module.

### Deprecated

Expand Down
18 changes: 5 additions & 13 deletions src/functions/marshal_uri_from_sapi.php
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,11 @@ function marshalUriFromSapi(array $server, array $headers)
* Detect the path for the request
*
* Looks at a variety of criteria in order to attempt to autodetect the base
* request path, including rewrite URIs, proxy URIs, etc.
* request path, including:
*
* - IIS7 UrlRewrite environment
* - REQUEST_URI
* - ORIG_PATH_INFO
*
* From ZF2's Zend\Http\PhpEnvironment\Request class
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
Expand All @@ -144,18 +148,6 @@ function marshalUriFromSapi(array $server, array $headers)

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

// Check this first so IIS will catch.
$httpXRewriteUrl = array_key_exists('HTTP_X_REWRITE_URL', $server) ? $server['HTTP_X_REWRITE_URL'] : null;
if ($httpXRewriteUrl !== null) {
$requestUri = $httpXRewriteUrl;
}

// Check for IIS 7.0 or later with ISAPI_Rewrite
$httpXOriginalUrl = array_key_exists('HTTP_X_ORIGINAL_URL', $server) ? $server['HTTP_X_ORIGINAL_URL'] : null;
if ($httpXOriginalUrl !== null) {
$requestUri = $httpXOriginalUrl;
}

if ($requestUri !== null) {
return preg_replace('#^[^/:]+://[^/]+#', '', $requestUri);
}
Expand Down
46 changes: 13 additions & 33 deletions test/ServerRequestFactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -126,39 +126,6 @@ public function testMarshalRequestUriUsesIISUnencodedUrlValueIfPresentAndUrlWasR
$this->assertSame($server['UNENCODED_URL'], $uri->getPath());
}

public function testMarshalRequestUriUsesHTTPXRewriteUrlIfPresent()
{
$server = [
'IIS_WasUrlRewritten' => null,
'UNENCODED_URL' => '/foo/bar',
'REQUEST_URI' => '/overridden',
'HTTP_X_REWRITE_URL' => '/bar/baz',
];

$headers = marshalHeadersFromSapi($server);

$uri = marshalUriFromSapi($server, $headers);

$this->assertSame($server['HTTP_X_REWRITE_URL'], $uri->getPath());
}

public function testMarshalRequestUriUsesHTTPXOriginalUrlIfPresent()
{
$server = [
'IIS_WasUrlRewritten' => null,
'UNENCODED_URL' => '/foo/bar',
'REQUEST_URI' => '/overridden',
'HTTP_X_REWRITE_URL' => '/bar/baz',
'HTTP_X_ORIGINAL_URL' => '/baz/bat',
];

$headers = marshalHeadersFromSapi($server);

$uri = marshalUriFromSapi($server, $headers);

$this->assertSame($server['HTTP_X_ORIGINAL_URL'], $uri->getPath());
}

public function testMarshalRequestUriStripsSchemeHostAndPortInformationWhenPresent()
{
$server = [
Expand Down Expand Up @@ -627,4 +594,17 @@ public function marshalProtocolVersionProvider()
'HTTP/2' => ['HTTP/2', '2'],
];
}

public function testMarshalRequestUriPrefersRequestUriServerParamWhenXOriginalUrlButNoXRewriteUrlPresent()
{
$headers = [
'X-Original-URL' => '/hijack-attempt',
];
$server = [
'REQUEST_URI' => 'https://example.com/requested/path',
];

$uri = marshalUriFromSapi($server, $headers);
$this->assertSame('/requested/path', $uri->getPath());
}
}

0 comments on commit 3a4f44f

Please sign in to comment.